From 64cd4c10443b2f8d9bf85506c7f1986699767f3a Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:39:12 +0200 Subject: [PATCH] Upstream changes from 20250521 --- AUTHORS | 10 + CONTRIBUTING.md | 59 + MANIFEST.in | 4 +- api_client/python/setup.py | 5 +- .../timesketch_api_client/aggregation.py | 27 +- .../timesketch_api_client/aggregation_test.py | 7 +- .../python/timesketch_api_client/client.py | 452 +- .../timesketch_api_client/client_test.py | 8 +- .../python/timesketch_api_client/config.py | 13 +- .../timesketch_api_client/config_test.py | 2 +- .../python/timesketch_api_client/crypto.py | 1 + .../python/timesketch_api_client/graph.py | 16 +- .../python/timesketch_api_client/resource.py | 23 +- .../python/timesketch_api_client/scenario.py | 4 +- .../python/timesketch_api_client/search.py | 52 +- .../timesketch_api_client/searchtemplate.py | 4 +- .../python/timesketch_api_client/sketch.py | 536 +- .../python/timesketch_api_client/story.py | 8 +- .../python/timesketch_api_client/test_lib.py | 37 +- .../python/timesketch_api_client/timeline.py | 8 +- .../python/timesketch_api_client/version.py | 2 +- .../python/timesketch_cli_client/cli.py | 24 +- .../timesketch_cli_client/commands/analyze.py | 29 +- .../commands/attribute.py | 70 +- .../timesketch_cli_client/commands/events.py | 36 +- .../commands/events_test.py | 86 - .../commands/importer.py | 11 +- .../commands/intelligence.py | 23 +- .../commands/intelligence_test.py | 16 +- .../timesketch_cli_client/commands/search.py | 163 +- .../commands/search_test.py | 74 +- .../timesketch_cli_client/commands/sigma.py | 2 +- .../commands/sigma_test.py | 6 +- .../timesketch_cli_client/commands/sketch.py | 332 +- .../commands/sketch_test.py | 301 +- .../commands/timelines.py | 78 +- .../commands/timelines_test.py | 7 +- .../python/timesketch_cli_client/version.py | 2 +- config/dpkg/changelog | 5 + config/dpkg/clean | 4 + config/dpkg/compat | 1 + config/dpkg/control | 36 + config/dpkg/copyright | 27 + config/dpkg/python3-timesketch.install | 7 + config/dpkg/rules | 24 + config/dpkg/source/format | 1 + config/dpkg/timesketch-data.dirs | 1 + config/dpkg/timesketch-data.install | 1 + config/dpkg/timesketch-server.dirs | 1 + config/dpkg/timesketch-server.install | 1 + config/dpkg/timesketch-server.postinst | 47 + .../dpkg/timesketch-server.timesketch.default | 201 + .../dpkg/timesketch-server.timesketch.service | 17 + .../dpkg/timesketch-server.timesketch.socket | 8 + contrib/deploy_timesketch.ps1 | 6 +- contrib/deploy_timesketch.sh | 6 +- contrib/gcs_importer.py | 15 +- contrib/nginx.conf | 28 + data/gunicorn_config.py | 5 +- data/timesketch.conf | 17 +- dependencies.ini | 349 ++ docker/dev/README.md | 80 +- docker/dev/build/10-widgets.py | 108 +- docker/dev/build/Dockerfile-notebook | 71 +- docker/dev/build/custom.css | 11 + docker/dev/build/sigma_rules.txt | 17 +- docker/dev/build/snippets.json | 81 + docker/dev/build/timesketch/README.md | 7 + docker/dev/build/timesketch/main.js | 46 + docker/dev/build/timesketch/timesketch.yaml | 6 + docker/dev/docker-compose.yml | 34 +- docker/dev/restart.sh | 2 +- docker/dev/start_frontend.sh | 2 +- docker/e2e/Dockerfile | 3 +- docker/e2e/docker-compose.yml | 2 +- docker/e2e/docker-entrypoint.sh | 126 +- docker/release/build/Dockerfile-latest | 37 + docker/release/build/cloudbuild.yaml | 18 + docker/release/config.env | 4 +- docker/release/docker-compose.yml | 86 + docs/changelog/index.md | 6 +- docs/developers/api-client.md | 2 +- docs/developers/api-upload-data.md | 14 +- docs/developers/frontend-development.md | 97 +- docs/developers/testing.md | 36 +- docs/guides/admin/admin-cli.md | 317 +- docs/guides/admin/load-dfiq.md | 36 + docs/guides/admin/scaling-and-limits.md | 6 +- docs/guides/admin/troubleshooting.md | 92 +- docs/guides/admin/upgrade.md | 36 +- docs/guides/user/cli-client.md | 8 +- docs/guides/user/notebook.md | 131 + docs/guides/user/search-query-guide.md | 1 + end_to_end_tests/__init__.py | 2 + end_to_end_tests/cli_client_e2e_test.py | 102 + end_to_end_tests/client_test.py | 344 +- end_to_end_tests/interface.py | 5 +- end_to_end_tests/manager.py | 2 +- end_to_end_tests/tsctl_test.py | 108 + end_to_end_tests/upload_test.py | 68 +- .../python/timesketch_import_client/helper.py | 2 +- .../timesketch_import_client/importer.py | 72 +- .../timesketch_import_client/importer_test.py | 4 +- .../python/timesketch_import_client/utils.py | 1 + .../python/tools/timesketch_importer.py | 4 +- mkdocs.yml | 1 + notebooks/MUS2019_CTF.ipynb | 1182 ++++ notebooks/OSDFCon Demo.ipynb | 1113 ++++ notebooks/SigmaPortFileToDatabase.ipynb | 1419 +++++ notebooks/Sigma_test_Notebook.ipynb | 423 ++ .../Stolen_Szechuan_Sauce_Analysis.ipynb | 3243 +++++++++++ .../Stolen_Szechuan_Sauce_Data_Upload.ipynb | 1025 ++++ .../add_a_single_event_to_a_sketch.ipynb | 176 + notebooks/colab-timesketch-demo.ipynb | 1589 ++++++ notebooks/debugging_timesketch.ipynb | 512 ++ requirements.txt | 20 +- run_tests.py | 15 +- setup.cfg | 72 + setup.py | 13 +- test_dependencies.ini | 26 + test_requirements.txt | 4 +- timesketch.ini | 10 + timesketch/__init__.py | 2 +- timesketch/api/v1/export.py | 27 +- timesketch/api/v1/resources/__init__.py | 12 +- timesketch/api/v1/resources/aggregation.py | 112 +- timesketch/api/v1/resources/analysis.py | 32 +- timesketch/api/v1/resources/archive.py | 67 +- timesketch/api/v1/resources/attribute.py | 6 +- timesketch/api/v1/resources/datafinder.py | 17 +- timesketch/api/v1/resources/datasource.py | 6 +- timesketch/api/v1/resources/event.py | 330 +- timesketch/api/v1/resources/explore.py | 105 +- timesketch/api/v1/resources/graph.py | 8 +- timesketch/api/v1/resources/llm.py | 357 ++ timesketch/api/v1/resources/scenarios.py | 11 +- timesketch/api/v1/resources/searchindex.py | 51 +- timesketch/api/v1/resources/searchtemplate.py | 6 +- timesketch/api/v1/resources/session.py | 13 +- timesketch/api/v1/resources/settings.py | 116 +- timesketch/api/v1/resources/sigma.py | 81 +- timesketch/api/v1/resources/sketch.py | 131 +- timesketch/api/v1/resources/story.py | 26 +- timesketch/api/v1/resources/task.py | 24 +- timesketch/api/v1/resources/timeline.py | 345 +- timesketch/api/v1/resources/unfurl.py | 18 +- timesketch/api/v1/resources/upload.py | 171 +- timesketch/api/v1/resources/user.py | 22 +- timesketch/api/v1/resources/view.py | 35 +- timesketch/api/v1/resources_test.py | 818 +-- timesketch/api/v1/routes.py | 166 +- timesketch/api/v1/utils.py | 20 +- timesketch/app.py | 39 +- .../frontend-ng/dist/css/index.c0639a89.css | 1 + timesketch/frontend-ng/dist/index.html | 2 +- .../dist/js/chunk-vendors.87bc6782.js | 1987 +++++++ .../dist/js/chunk-vendors.87bc6782.js.map | 1 + .../frontend-ng/dist/js/index.25b58337.js | 2 + .../frontend-ng/dist/js/index.25b58337.js.map | 1 + .../frontend-ng/dist/js/login.009201af.js | 2 + .../frontend-ng/dist/js/login.009201af.js.map | 1 + timesketch/frontend-ng/dist/login.html | 2 +- timesketch/frontend-ng/package.json | 9 +- timesketch/frontend-ng/public/empty-state.png | Bin 0 -> 8329 bytes .../src/components/Analyzer/TimelineChip.vue | 3 + .../components/Analyzer/TimelineSearch.vue | 7 +- .../components/Explore/AggregateDialog.vue | 18 +- .../components/Explore/EventActionMenu.vue | 5 +- .../src/components/Explore/EventDetail.vue | 8 +- .../src/components/Explore/EventList.vue | 1042 ++-- .../src/components/Explore/TimelineChip.vue | 4 +- .../components/Explore/TimelineComponent.vue | 27 +- .../components/LeftPanel/AnalyzerResults.vue | 3 +- .../src/components/LeftPanel/Graphs.vue | 2 - .../src/components/LeftPanel/SigmaRules.vue | 3 - .../src/components/LeftPanel/Stories.vue | 4 +- .../components/LeftPanel/TimelinesTable.vue | 70 +- .../src/components/Scenarios/QuestionCard.vue | 143 +- .../src/components/SettingsDialog.vue | 130 +- .../Visualization/AggregationEventSelect.vue | 4 + .../Visualization/VisualizationEditor.vue | 6 +- .../src/filters/FormatTimestamp.js | 29 + .../frontend-ng/src/filters/ToISO8601.js | 26 + timesketch/frontend-ng/src/mixins/snackBar.js | 59 +- timesketch/frontend-ng/src/store.js | 54 +- .../frontend-ng/src/utils/RestApiClient.js | 16 +- timesketch/frontend-ng/src/views/Analyze.vue | 2 +- timesketch/frontend-ng/src/views/Explore.vue | 30 +- timesketch/frontend-ng/src/views/Sketch.vue | 41 +- timesketch/frontend-ng/src/views/Story.vue | 83 +- timesketch/frontend-ng/vue.config.js | 6 +- timesketch/frontend-ng/yarn.lock | 3806 +++++++------ .../frontend-v3/.eslintrc-auto-import.json | 5 +- .../frontend-v3/dist/assets/index-B0IAEnPZ.js | 37 + .../dist/assets/index-DfjbSsV6.css | 5 + .../materialdesignicons-webfont-B7mPwVP_.ttf | Bin 0 -> 1307660 bytes .../materialdesignicons-webfont-CSr8KVlo.eot | Bin 0 -> 1307880 bytes ...materialdesignicons-webfont-Dp5v-WZN.woff2 | Bin 0 -> 403216 bytes .../materialdesignicons-webfont-PXm3-2wK.woff | Bin 0 -> 587984 bytes timesketch/frontend-v3/dist/empty-state.png | Bin 0 -> 8329 bytes timesketch/frontend-v3/dist/favicon.ico | Bin 0 -> 2238 bytes timesketch/frontend-v3/dist/index.html | 24 + .../frontend-v3/dist/timesketch-color.png | Bin 0 -> 6167 bytes timesketch/frontend-v3/package.json | 4 +- timesketch/frontend-v3/public/empty-state.png | Bin 0 -> 8329 bytes .../frontend-v3/src/components/Canvas.vue | 49 + .../components/LeftPanel/ExampleLeftBar.vue | 83 + .../src/components/LeftPanel/Search.vue | 79 + .../src/components/RenameSketch.vue | 85 + .../src/components/SettingsDialog.vue | 100 + .../frontend-v3/src/components/ShareCard.vue | 230 + .../frontend-v3/src/components/UploadForm.vue | 578 ++ .../src/components/UploadFormButton.vue | 40 + timesketch/frontend-v3/src/layouts/AppBar.vue | 14 +- timesketch/frontend-v3/src/main.js | 2 + timesketch/frontend-v3/src/mixins.js | 40 + timesketch/frontend-v3/src/router/index.js | 20 +- timesketch/frontend-v3/src/stores/app.js | 20 + .../frontend-v3/src/utils/RestApiClient.js | 10 +- timesketch/frontend-v3/src/views/Sketch.vue | 255 +- timesketch/frontend-v3/yarn.lock | 16 +- timesketch/frontend/.browserslistrc | 3 + timesketch/frontend/.editorconfig | 5 + timesketch/frontend/.eslintrc.js | 29 + timesketch/frontend/.prettierrc | 7 + .../Horizontal/ts-logo-horizontal-color.eps | Bin 0 -> 694690 bytes .../Horizontal/ts-logo-horizontal-color.png | Bin 0 -> 15084 bytes .../Horizontal/ts-logo-horizontal-color.svg | 70 + .../ts-logo-horizontal-reversed.eps | Bin 0 -> 687130 bytes .../ts-logo-horizontal-reversed.png | Bin 0 -> 13758 bytes .../ts-logo-horizontal-reversed.svg | 69 + .../Logo Files/Mark Only/timesketch-color.eps | Bin 0 -> 628286 bytes .../Logo Files/Mark Only/timesketch-color.png | Bin 0 -> 6167 bytes .../Logo Files/Mark Only/timesketch-color.svg | 14 + .../Logo Files/Mark Only/timesketch-white.eps | Bin 0 -> 621766 bytes .../Logo Files/Mark Only/timesketch-white.png | Bin 0 -> 5707 bytes .../Logo Files/Mark Only/timesketch-white.svg | 13 + .../Logo Files/Text Only/ts-text-color.eps | Bin 0 -> 640750 bytes .../Logo Files/Text Only/ts-text-color.png | Bin 0 -> 6770 bytes .../Logo Files/Text Only/ts-text-color.svg | 63 + .../Logo Files/Text Only/ts-text-white.eps | Bin 0 -> 633046 bytes .../Logo Files/Text Only/ts-text-white.png | Bin 0 -> 6191 bytes .../Logo Files/Text Only/ts-text-white.svg | 63 + .../Vertical/ts-logo-vertical-color.eps | Bin 0 -> 691926 bytes .../Vertical/ts-logo-vertical-color.png | Bin 0 -> 14369 bytes .../Vertical/ts-logo-vertical-color.svg | 71 + .../Vertical/ts-logo-vertical-reversed.eps | Bin 0 -> 679146 bytes .../Vertical/ts-logo-vertical-reversed.png | Bin 0 -> 13210 bytes .../Vertical/ts-logo-vertical-reversed.svg | 70 + timesketch/frontend/README.md | 34 + timesketch/frontend/babel.config.js | 18 + .../dist/css/chunk-common.673b3577.css | 7 + .../dist/css/chunk-vendors.96a655cf.css | 1 + timesketch/frontend/dist/favicon.ico | Bin 0 -> 2238 bytes .../dist/fonts/fa-solid-900.0c6bfc66.eot | Bin 0 -> 203030 bytes .../dist/fonts/fa-solid-900.b9625119.ttf | Bin 0 -> 202744 bytes .../dist/fonts/fa-solid-900.d745348d.woff | Bin 0 -> 101648 bytes .../dist/fonts/fa-solid-900.d824df7e.woff2 | Bin 0 -> 78268 bytes .../dist/img/fa-solid-900.37bc7099.svg | 5034 +++++++++++++++++ timesketch/frontend/dist/index.html | 1 + .../frontend/dist/js/chunk-common.d12c964e.js | 2 + .../dist/js/chunk-common.d12c964e.js.map | 1 + .../dist/js/chunk-vendors.91a8ae5d.js | 123 + .../dist/js/chunk-vendors.91a8ae5d.js.map | 1 + timesketch/frontend/dist/js/index.55262dae.js | 2 + .../frontend/dist/js/index.55262dae.js.map | 1 + timesketch/frontend/dist/js/login.10bd00b4.js | 2 + .../frontend/dist/js/login.10bd00b4.js.map | 1 + timesketch/frontend/dist/login.html | 18 + timesketch/frontend/dist/timesketch-color.png | Bin 0 -> 6167 bytes .../frontend/dist/timesketch-logo-black.svg | 76 + .../frontend/dist/timesketch-logo-white.svg | 76 + timesketch/frontend/dist/timesketch-white.png | Bin 0 -> 5707 bytes timesketch/frontend/jsconfig.json | 1 + timesketch/frontend/package.json | 57 + timesketch/frontend/postcss.config.js | 20 + timesketch/frontend/public/favicon.ico | Bin 0 -> 2238 bytes timesketch/frontend/public/index.html | 29 + timesketch/frontend/public/login.html | 88 + .../frontend/public/timesketch-color.png | Bin 0 -> 6167 bytes .../frontend/public/timesketch-logo-black.svg | 76 + .../frontend/public/timesketch-logo-white.svg | 76 + .../frontend/public/timesketch-white.png | Bin 0 -> 5707 bytes timesketch/frontend/src/App.vue | 36 + timesketch/frontend/src/assets/main.scss | 577 ++ .../components/Aggregation/Aggregation.vue | 182 + .../Aggregation/AggregationCompact.vue | 98 + .../Aggregation/AggregationGroupCompact.vue | 59 + .../Aggregation/AggregationListDropdown.vue | 55 + .../Aggregation/AggregatorListDropdown.vue | 54 + .../src/components/Aggregation/BarChart.vue | 187 + .../src/components/Aggregation/TableChart.vue | 50 + .../components/Aggregation/VegaLiteChart.vue | 37 + .../Analyze/ActiveAnalysisSessions.vue | 114 + .../components/Analyze/AnalyzerHistory.vue | 105 + .../Analyze/AnalyzerSessionDetail.vue | 174 + .../frontend/src/components/AppNavbarMain.vue | 139 + .../src/components/AppNavbarSecondary.vue | 154 + .../components/Common/CreateSketchForm.vue | 70 + .../src/components/Common/CreateViewForm.vue | 58 + .../src/components/Common/Dropdown.vue | 53 + .../src/components/Common/DynamicForm.vue | 61 + .../Common/DynamicFormDatetimeInput.vue | 39 + .../Common/DynamicFormSelectInput.vue | 34 + .../Common/DynamicFormTextInput.vue | 34 + .../src/components/Common/ExplorePreview.vue | 131 + .../src/components/Common/TsContextMenu.vue | 85 + .../src/components/Common/TsDynamicTable.vue | 128 + .../src/components/Common/TsIOCMenu.vue | 194 + .../src/components/Common/TsIocCompose.vue | 118 + .../src/components/Common/UploadForm.vue | 757 +++ .../src/components/Common/ViewList.vue | 67 + .../src/components/Common/ViewListCompact.vue | 46 + .../components/Common/ViewListDropdown.vue | 186 + .../src/components/Explore/EventList.vue | 86 + .../components/Explore/EventListCompact.vue | 119 + .../src/components/Explore/EventListRow.vue | 649 +++ .../components/Explore/EventListRowDetail.vue | 165 + .../src/components/Explore/SearchDropdown.vue | 251 + .../Explore/SearchHistoryButtons.vue | 84 + .../components/Explore/SearchHistoryTree.vue | 130 + .../Explore/SearchHistoryTreeNode.vue | 87 + .../src/components/Explore/TimeFilter.vue | 357 ++ .../src/components/Explore/TimelineChip.vue | 342 ++ .../src/components/Explore/TimelinePicker.vue | 193 + .../frontend/src/components/Graph/Graph.vue | 758 +++ .../src/components/Graph/GraphList.vue | 63 + .../src/components/Graph/GraphPluginList.vue | 64 + .../src/components/Home/Graph/Graph.vue | 758 +++ .../src/components/Home/Graph/GraphList.vue | 63 + .../components/Home/Graph/GraphPluginList.vue | 64 + .../src/components/Home/SketchList.vue | 123 + .../src/components/Overview/ShareForm.vue | 232 + .../src/components/Overview/SketchMetrics.vue | 49 + .../src/components/Overview/SketchSummary.vue | 65 + .../src/components/Sigma/SigmaList.vue | 353 ++ .../components/Stories/CreateStoryForm.vue | 66 + .../src/components/Stories/StoryList.vue | 75 + .../src/components/Timelines/TimelineList.vue | 94 + .../Timelines/TimelineListDropdown.vue | 83 + .../components/Timelines/TimelineListItem.vue | 500 ++ timesketch/frontend/src/definitions.js | 54 + timesketch/frontend/src/filters/Capitalize.js | 23 + .../frontend/src/filters/CompactBytes.js | 28 + .../frontend/src/filters/CompactNumber.js | 37 + timesketch/frontend/src/filters/FilterChip.js | 29 + .../frontend/src/filters/FormatTimestamp.js | 31 + timesketch/frontend/src/main.js | 74 + timesketch/frontend/src/router.js | 150 + timesketch/frontend/src/store.js | 149 + .../src/utils/RegisterAppComponents.js | 40 + .../frontend/src/utils/RegisterAppFilters.js | 33 + .../frontend/src/utils/RestApiClient.js | 381 ++ .../frontend/src/utils/SigmaRuleTemplates.js | 634 +++ timesketch/frontend/src/utils/tagMetadata.js | 15 + timesketch/frontend/src/views/Aggregate.vue | 93 + timesketch/frontend/src/views/Analyze.vue | 174 + timesketch/frontend/src/views/Attributes.vue | 81 + timesketch/frontend/src/views/Explore.vue | 1209 ++++ timesketch/frontend/src/views/Graph.vue | 18 + .../frontend/src/views/GraphExplore.vue | 42 + .../frontend/src/views/GraphOverview.vue | 57 + timesketch/frontend/src/views/Home.vue | 182 + .../frontend/src/views/Intelligence.vue | 437 ++ timesketch/frontend/src/views/Overview.vue | 526 ++ .../frontend/src/views/SavedSearches.vue | 55 + timesketch/frontend/src/views/Sigma.vue | 18 + .../frontend/src/views/SigmaOverview.vue | 50 + timesketch/frontend/src/views/Sketch.vue | 42 + timesketch/frontend/src/views/Story.vue | 18 + .../frontend/src/views/StoryContent.vue | 787 +++ .../frontend/src/views/StoryOverview.vue | 90 + timesketch/frontend/src/views/Timelines.vue | 103 + timesketch/frontend/tests/unit/.eslintrc.js | 5 + .../frontend/tests/unit/iocmenu.spec.js | 51 + timesketch/frontend/vue.config.js | 63 + timesketch/lib/aggregators/apex.py | 7 +- timesketch/lib/aggregators/bucket.py | 16 +- timesketch/lib/aggregators/date_histogram.py | 35 +- timesketch/lib/aggregators/feed.py | 12 +- timesketch/lib/aggregators/interface.py | 35 +- timesketch/lib/aggregators/manager.py | 12 +- timesketch/lib/aggregators/manager_test.py | 5 +- timesketch/lib/aggregators/summary.py | 42 +- timesketch/lib/aggregators/term.py | 23 +- timesketch/lib/aggregators/vega.py | 19 +- timesketch/lib/analyzers/account_finder.py | 6 +- .../lib/analyzers/authentication/ssh.py | 4 +- .../lib/analyzers/authentication/ssh_test.py | 5 +- .../lib/analyzers/authentication/utils.py | 5 +- .../analyzers/authentication/windows_test.py | 2 +- .../lib/analyzers/base_sessionizer_test.py | 11 +- timesketch/lib/analyzers/browser_search.py | 34 +- .../lib/analyzers/browser_search_test.py | 9 +- timesketch/lib/analyzers/browser_timeframe.py | 32 +- .../lib/analyzers/browser_timeframe_test.py | 2 - timesketch/lib/analyzers/chain.py | 15 +- .../lib/analyzers/chain_plugins/__init__.py | 1 - .../chain_plugins/chrome_download_file.py | 16 +- .../lib/analyzers/chain_plugins/interface.py | 4 +- .../lib/analyzers/chain_plugins/manager.py | 9 +- .../analyzers/chain_plugins/win_prefetch.py | 10 +- timesketch/lib/analyzers/chain_test.py | 9 +- .../lib/analyzers/contrib/bigquery_matcher.py | 4 +- .../contrib/bigquery_matcher_test.py | 13 +- .../analyzers/contrib/hashlookup_analyzer.py | 10 +- .../contrib/hashlookup_analyzer_test.py | 6 +- .../lib/analyzers/contrib/misp_analyzer.py | 15 +- .../analyzers/contrib/misp_analyzer_test.py | 4 +- .../lib/analyzers/dfiq_plugins/manager.py | 23 +- timesketch/lib/analyzers/domain.py | 5 +- timesketch/lib/analyzers/domain_test.py | 4 +- timesketch/lib/analyzers/evtx_sessionizers.py | 8 +- .../lib/analyzers/evtx_sessionizers_test.py | 34 +- .../lib/analyzers/expert_sessionizers.py | 2 - .../lib/analyzers/expert_sessionizers_test.py | 18 +- .../feature_extraction_plugins/interface.py | 2 +- .../feature_extraction_plugins/manager.py | 2 +- .../regex_features.py | 19 +- .../lib/analyzers/feature_extraction_test.py | 35 +- timesketch/lib/analyzers/gcp_logging.py | 10 +- timesketch/lib/analyzers/gcp_servicekey.py | 4 +- timesketch/lib/analyzers/geoip.py | 28 +- timesketch/lib/analyzers/geoip_test.py | 37 +- timesketch/lib/analyzers/hashr_lookup.py | 36 +- timesketch/lib/analyzers/hashr_lookup_test.py | 80 +- timesketch/lib/analyzers/interface.py | 131 +- timesketch/lib/analyzers/interface_test.py | 15 +- timesketch/lib/analyzers/login.py | 11 +- timesketch/lib/analyzers/login_test.py | 2 - timesketch/lib/analyzers/manager.py | 16 +- timesketch/lib/analyzers/manager_test.py | 16 +- timesketch/lib/analyzers/ntfs_timestomp.py | 12 +- .../lib/analyzers/ntfs_timestomp_test.py | 8 +- timesketch/lib/analyzers/phishy_domains.py | 12 +- .../lib/analyzers/phishy_domains_test.py | 16 +- .../lib/analyzers/psexec_sessionizers.py | 4 +- timesketch/lib/analyzers/safebrowsing.py | 27 +- timesketch/lib/analyzers/safebrowsing_test.py | 13 +- .../lib/analyzers/sequence_sessionizer.py | 12 +- .../analyzers/sequence_sessionizer_test.py | 39 +- timesketch/lib/analyzers/sessionizer.py | 6 +- timesketch/lib/analyzers/sessionizer_test.py | 4 +- timesketch/lib/analyzers/sigma_tagger.py | 20 +- timesketch/lib/analyzers/sigma_tagger_test.py | 4 +- timesketch/lib/analyzers/similarity_scorer.py | 7 +- .../lib/analyzers/similarity_scorer_test.py | 9 +- timesketch/lib/analyzers/ssh_sessionizer.py | 17 +- .../lib/analyzers/ssh_sessionizer_test.py | 6 +- timesketch/lib/analyzers/tagger.py | 11 +- timesketch/lib/analyzers/tagger_test.py | 2 +- timesketch/lib/analyzers/utils.py | 13 +- timesketch/lib/analyzers/utils_test.py | 9 +- timesketch/lib/analyzers/win_crash.py | 10 +- timesketch/lib/analyzers/win_crash_test.py | 4 +- timesketch/lib/analyzers/win_evtxgap.py | 40 +- timesketch/lib/analyzers/win_evtxgap_test.py | 8 +- timesketch/lib/analyzers/yetiindicators.py | 356 +- .../lib/analyzers/yetiindicators_test.py | 94 +- timesketch/lib/charts/barchart.py | 3 +- timesketch/lib/charts/circle.py | 1 - timesketch/lib/charts/interface.py | 7 +- timesketch/lib/charts/line.py | 1 - timesketch/lib/charts/manager.py | 15 +- timesketch/lib/charts/manager_test.py | 3 +- timesketch/lib/datafinder.py | 16 +- timesketch/lib/datastores/opensearch.py | 1166 +++- timesketch/lib/definitions.py | 3 +- timesketch/lib/dfiq.py | 11 +- timesketch/lib/emojis.py | 1 - timesketch/lib/emojis_test.py | 4 - timesketch/lib/errors.py | 13 +- timesketch/lib/forms.py | 32 +- timesketch/lib/google_auth.py | 117 +- timesketch/lib/google_auth_test.py | 26 +- timesketch/lib/graphs/interface.py | 23 +- timesketch/lib/graphs/manager.py | 7 +- timesketch/lib/llms/__init__.py | 8 +- timesketch/lib/llms/features/__init__.py | 18 + timesketch/lib/llms/features/interface.py | 87 + timesketch/lib/llms/features/llm_summarize.py | 225 + .../lib/llms/features/llm_summarize_test.py | 197 + timesketch/lib/llms/features/manager.py | 98 + timesketch/lib/llms/features/manager_test.py | 200 + timesketch/lib/llms/features/nl2q.py | 190 + timesketch/lib/llms/features/nl2q_test.py | 150 + timesketch/lib/llms/providers/__init__.py | 18 + timesketch/lib/llms/providers/aistudio.py | 94 + timesketch/lib/llms/providers/interface.py | 93 + timesketch/lib/llms/providers/manager.py | 111 + timesketch/lib/llms/providers/manager_test.py | 221 + timesketch/lib/llms/providers/ollama.py | 125 + timesketch/lib/llms/providers/vertexai.py | 113 + timesketch/lib/sigma_util.py | 23 +- timesketch/lib/sigma_util_test.py | 26 +- timesketch/lib/similarity.py | 14 +- timesketch/lib/similarity_test.py | 8 +- timesketch/lib/stories/api_fetcher.py | 1 - timesketch/lib/stories/html.py | 23 +- timesketch/lib/stories/interface.py | 8 +- timesketch/lib/stories/manager.py | 8 +- timesketch/lib/stories/manager_test.py | 7 +- timesketch/lib/stories/markdown.py | 1 - timesketch/lib/tasks.py | 304 +- timesketch/lib/testlib.py | 87 +- timesketch/lib/utils.py | 80 +- timesketch/lib/utils_test.py | 1 - timesketch/migrations/env.py | 9 +- .../011cabf3aef0_refactor_scenario_models.py | 4 +- ...xtend_datasource_model_with_total_file_.py | 3 +- .../migrations/versions/36e85b266dba_.py | 4 +- .../migrations/versions/41cae2c10cd7_.py | 4 +- ...question_refactor_add_approach_and_add_.py | 3 +- .../migrations/versions/64c00337b9d1_.py | 4 +- .../migrations/versions/6e69f2cfcac1_.py | 4 +- ...732e1_add_dfiq_context_to_searchhistory.py | 4 +- ...d75b1e_extending_the_data_source_schema.py | 3 +- .../migrations/versions/7d48bf36b244_.py | 4 +- .../a3b082c9e6e9_extend_searchtemplate.py | 4 +- .../migrations/versions/be32626451fb_.py | 4 +- .../migrations/versions/c380f6dff0bd_.py | 4 +- ...60d97a2c8_add_uuid_field_to_dfiq_models.py | 4 +- .../migrations/versions/ecf00882f546_.py | 4 +- timesketch/models/__init__.py | 19 +- timesketch/models/acl.py | 60 +- timesketch/models/acl_test.py | 1 - timesketch/models/annotations.py | 158 +- timesketch/models/annotations_test.py | 7 +- timesketch/models/sketch.py | 12 +- timesketch/models/sketch_test.py | 3 +- timesketch/models/user.py | 3 +- timesketch/models/user_test.py | 1 - timesketch/tsctl.py | 1255 +++- timesketch/version.py | 2 +- timesketch/views/auth.py | 102 +- timesketch/views/auth_test.py | 1 - timesketch/views/spa.py | 9 +- timesketch/wsgi.py | 15 +- utils/generate_sample_data.py | 189 + utils/tsdev.sh | 101 +- utils/update_release.sh | 29 + 541 files changed, 52447 insertions(+), 6198 deletions(-) create mode 100644 AUTHORS create mode 100644 CONTRIBUTING.md create mode 100644 config/dpkg/changelog create mode 100644 config/dpkg/clean create mode 100644 config/dpkg/compat create mode 100644 config/dpkg/control create mode 100644 config/dpkg/copyright create mode 100644 config/dpkg/python3-timesketch.install create mode 100755 config/dpkg/rules create mode 100644 config/dpkg/source/format create mode 100644 config/dpkg/timesketch-data.dirs create mode 100644 config/dpkg/timesketch-data.install create mode 100644 config/dpkg/timesketch-server.dirs create mode 100644 config/dpkg/timesketch-server.install create mode 100644 config/dpkg/timesketch-server.postinst create mode 100644 config/dpkg/timesketch-server.timesketch.default create mode 100644 config/dpkg/timesketch-server.timesketch.service create mode 100644 config/dpkg/timesketch-server.timesketch.socket create mode 100644 dependencies.ini create mode 100644 docker/dev/build/custom.css create mode 100644 docker/dev/build/snippets.json create mode 100644 docker/dev/build/timesketch/README.md create mode 100644 docker/dev/build/timesketch/main.js create mode 100644 docker/dev/build/timesketch/timesketch.yaml create mode 100644 docker/release/build/Dockerfile-latest create mode 100644 docker/release/build/cloudbuild.yaml create mode 100644 docker/release/docker-compose.yml create mode 100644 docs/guides/admin/load-dfiq.md create mode 100644 docs/guides/user/notebook.md create mode 100644 end_to_end_tests/cli_client_e2e_test.py create mode 100644 end_to_end_tests/tsctl_test.py create mode 100644 notebooks/MUS2019_CTF.ipynb create mode 100644 notebooks/OSDFCon Demo.ipynb create mode 100644 notebooks/SigmaPortFileToDatabase.ipynb create mode 100644 notebooks/Sigma_test_Notebook.ipynb create mode 100644 notebooks/Stolen_Szechuan_Sauce_Analysis.ipynb create mode 100644 notebooks/Stolen_Szechuan_Sauce_Data_Upload.ipynb create mode 100644 notebooks/add_a_single_event_to_a_sketch.ipynb create mode 100644 notebooks/colab-timesketch-demo.ipynb create mode 100644 notebooks/debugging_timesketch.ipynb create mode 100644 setup.cfg create mode 100644 test_dependencies.ini create mode 100644 timesketch.ini create mode 100644 timesketch/api/v1/resources/llm.py create mode 100644 timesketch/frontend-ng/dist/css/index.c0639a89.css create mode 100644 timesketch/frontend-ng/dist/js/chunk-vendors.87bc6782.js create mode 100644 timesketch/frontend-ng/dist/js/chunk-vendors.87bc6782.js.map create mode 100644 timesketch/frontend-ng/dist/js/index.25b58337.js create mode 100644 timesketch/frontend-ng/dist/js/index.25b58337.js.map create mode 100644 timesketch/frontend-ng/dist/js/login.009201af.js create mode 100644 timesketch/frontend-ng/dist/js/login.009201af.js.map create mode 100644 timesketch/frontend-ng/public/empty-state.png create mode 100644 timesketch/frontend-ng/src/filters/FormatTimestamp.js create mode 100644 timesketch/frontend-ng/src/filters/ToISO8601.js create mode 100644 timesketch/frontend-v3/dist/assets/index-B0IAEnPZ.js create mode 100644 timesketch/frontend-v3/dist/assets/index-DfjbSsV6.css create mode 100644 timesketch/frontend-v3/dist/assets/materialdesignicons-webfont-B7mPwVP_.ttf create mode 100644 timesketch/frontend-v3/dist/assets/materialdesignicons-webfont-CSr8KVlo.eot create mode 100644 timesketch/frontend-v3/dist/assets/materialdesignicons-webfont-Dp5v-WZN.woff2 create mode 100644 timesketch/frontend-v3/dist/assets/materialdesignicons-webfont-PXm3-2wK.woff create mode 100644 timesketch/frontend-v3/dist/empty-state.png create mode 100644 timesketch/frontend-v3/dist/favicon.ico create mode 100644 timesketch/frontend-v3/dist/index.html create mode 100644 timesketch/frontend-v3/dist/timesketch-color.png create mode 100644 timesketch/frontend-v3/public/empty-state.png create mode 100644 timesketch/frontend-v3/src/components/Canvas.vue create mode 100644 timesketch/frontend-v3/src/components/LeftPanel/ExampleLeftBar.vue create mode 100644 timesketch/frontend-v3/src/components/LeftPanel/Search.vue create mode 100644 timesketch/frontend-v3/src/components/RenameSketch.vue create mode 100644 timesketch/frontend-v3/src/components/SettingsDialog.vue create mode 100644 timesketch/frontend-v3/src/components/ShareCard.vue create mode 100644 timesketch/frontend-v3/src/components/UploadForm.vue create mode 100644 timesketch/frontend-v3/src/components/UploadFormButton.vue create mode 100644 timesketch/frontend-v3/src/mixins.js create mode 100644 timesketch/frontend/.browserslistrc create mode 100644 timesketch/frontend/.editorconfig create mode 100644 timesketch/frontend/.eslintrc.js create mode 100644 timesketch/frontend/.prettierrc create mode 100644 timesketch/frontend/Logo Files/Horizontal/ts-logo-horizontal-color.eps create mode 100644 timesketch/frontend/Logo Files/Horizontal/ts-logo-horizontal-color.png create mode 100644 timesketch/frontend/Logo Files/Horizontal/ts-logo-horizontal-color.svg create mode 100644 timesketch/frontend/Logo Files/Horizontal/ts-logo-horizontal-reversed.eps create mode 100644 timesketch/frontend/Logo Files/Horizontal/ts-logo-horizontal-reversed.png create mode 100644 timesketch/frontend/Logo Files/Horizontal/ts-logo-horizontal-reversed.svg create mode 100644 timesketch/frontend/Logo Files/Mark Only/timesketch-color.eps create mode 100644 timesketch/frontend/Logo Files/Mark Only/timesketch-color.png create mode 100644 timesketch/frontend/Logo Files/Mark Only/timesketch-color.svg create mode 100644 timesketch/frontend/Logo Files/Mark Only/timesketch-white.eps create mode 100644 timesketch/frontend/Logo Files/Mark Only/timesketch-white.png create mode 100644 timesketch/frontend/Logo Files/Mark Only/timesketch-white.svg create mode 100644 timesketch/frontend/Logo Files/Text Only/ts-text-color.eps create mode 100644 timesketch/frontend/Logo Files/Text Only/ts-text-color.png create mode 100644 timesketch/frontend/Logo Files/Text Only/ts-text-color.svg create mode 100644 timesketch/frontend/Logo Files/Text Only/ts-text-white.eps create mode 100644 timesketch/frontend/Logo Files/Text Only/ts-text-white.png create mode 100644 timesketch/frontend/Logo Files/Text Only/ts-text-white.svg create mode 100644 timesketch/frontend/Logo Files/Vertical/ts-logo-vertical-color.eps create mode 100644 timesketch/frontend/Logo Files/Vertical/ts-logo-vertical-color.png create mode 100644 timesketch/frontend/Logo Files/Vertical/ts-logo-vertical-color.svg create mode 100644 timesketch/frontend/Logo Files/Vertical/ts-logo-vertical-reversed.eps create mode 100644 timesketch/frontend/Logo Files/Vertical/ts-logo-vertical-reversed.png create mode 100644 timesketch/frontend/Logo Files/Vertical/ts-logo-vertical-reversed.svg create mode 100644 timesketch/frontend/README.md create mode 100644 timesketch/frontend/babel.config.js create mode 100644 timesketch/frontend/dist/css/chunk-common.673b3577.css create mode 100644 timesketch/frontend/dist/css/chunk-vendors.96a655cf.css create mode 100644 timesketch/frontend/dist/favicon.ico create mode 100644 timesketch/frontend/dist/fonts/fa-solid-900.0c6bfc66.eot create mode 100644 timesketch/frontend/dist/fonts/fa-solid-900.b9625119.ttf create mode 100644 timesketch/frontend/dist/fonts/fa-solid-900.d745348d.woff create mode 100644 timesketch/frontend/dist/fonts/fa-solid-900.d824df7e.woff2 create mode 100644 timesketch/frontend/dist/img/fa-solid-900.37bc7099.svg create mode 100644 timesketch/frontend/dist/index.html create mode 100644 timesketch/frontend/dist/js/chunk-common.d12c964e.js create mode 100644 timesketch/frontend/dist/js/chunk-common.d12c964e.js.map create mode 100644 timesketch/frontend/dist/js/chunk-vendors.91a8ae5d.js create mode 100644 timesketch/frontend/dist/js/chunk-vendors.91a8ae5d.js.map create mode 100644 timesketch/frontend/dist/js/index.55262dae.js create mode 100644 timesketch/frontend/dist/js/index.55262dae.js.map create mode 100644 timesketch/frontend/dist/js/login.10bd00b4.js create mode 100644 timesketch/frontend/dist/js/login.10bd00b4.js.map create mode 100644 timesketch/frontend/dist/login.html create mode 100644 timesketch/frontend/dist/timesketch-color.png create mode 100644 timesketch/frontend/dist/timesketch-logo-black.svg create mode 100644 timesketch/frontend/dist/timesketch-logo-white.svg create mode 100644 timesketch/frontend/dist/timesketch-white.png create mode 100644 timesketch/frontend/jsconfig.json create mode 100644 timesketch/frontend/package.json create mode 100644 timesketch/frontend/postcss.config.js create mode 100644 timesketch/frontend/public/favicon.ico create mode 100644 timesketch/frontend/public/index.html create mode 100644 timesketch/frontend/public/login.html create mode 100644 timesketch/frontend/public/timesketch-color.png create mode 100644 timesketch/frontend/public/timesketch-logo-black.svg create mode 100644 timesketch/frontend/public/timesketch-logo-white.svg create mode 100644 timesketch/frontend/public/timesketch-white.png create mode 100644 timesketch/frontend/src/App.vue create mode 100644 timesketch/frontend/src/assets/main.scss create mode 100644 timesketch/frontend/src/components/Aggregation/Aggregation.vue create mode 100644 timesketch/frontend/src/components/Aggregation/AggregationCompact.vue create mode 100644 timesketch/frontend/src/components/Aggregation/AggregationGroupCompact.vue create mode 100644 timesketch/frontend/src/components/Aggregation/AggregationListDropdown.vue create mode 100644 timesketch/frontend/src/components/Aggregation/AggregatorListDropdown.vue create mode 100644 timesketch/frontend/src/components/Aggregation/BarChart.vue create mode 100644 timesketch/frontend/src/components/Aggregation/TableChart.vue create mode 100644 timesketch/frontend/src/components/Aggregation/VegaLiteChart.vue create mode 100644 timesketch/frontend/src/components/Analyze/ActiveAnalysisSessions.vue create mode 100644 timesketch/frontend/src/components/Analyze/AnalyzerHistory.vue create mode 100644 timesketch/frontend/src/components/Analyze/AnalyzerSessionDetail.vue create mode 100644 timesketch/frontend/src/components/AppNavbarMain.vue create mode 100644 timesketch/frontend/src/components/AppNavbarSecondary.vue create mode 100644 timesketch/frontend/src/components/Common/CreateSketchForm.vue create mode 100644 timesketch/frontend/src/components/Common/CreateViewForm.vue create mode 100644 timesketch/frontend/src/components/Common/Dropdown.vue create mode 100644 timesketch/frontend/src/components/Common/DynamicForm.vue create mode 100644 timesketch/frontend/src/components/Common/DynamicFormDatetimeInput.vue create mode 100644 timesketch/frontend/src/components/Common/DynamicFormSelectInput.vue create mode 100644 timesketch/frontend/src/components/Common/DynamicFormTextInput.vue create mode 100644 timesketch/frontend/src/components/Common/ExplorePreview.vue create mode 100644 timesketch/frontend/src/components/Common/TsContextMenu.vue create mode 100644 timesketch/frontend/src/components/Common/TsDynamicTable.vue create mode 100644 timesketch/frontend/src/components/Common/TsIOCMenu.vue create mode 100644 timesketch/frontend/src/components/Common/TsIocCompose.vue create mode 100644 timesketch/frontend/src/components/Common/UploadForm.vue create mode 100644 timesketch/frontend/src/components/Common/ViewList.vue create mode 100644 timesketch/frontend/src/components/Common/ViewListCompact.vue create mode 100644 timesketch/frontend/src/components/Common/ViewListDropdown.vue create mode 100644 timesketch/frontend/src/components/Explore/EventList.vue create mode 100644 timesketch/frontend/src/components/Explore/EventListCompact.vue create mode 100644 timesketch/frontend/src/components/Explore/EventListRow.vue create mode 100644 timesketch/frontend/src/components/Explore/EventListRowDetail.vue create mode 100644 timesketch/frontend/src/components/Explore/SearchDropdown.vue create mode 100644 timesketch/frontend/src/components/Explore/SearchHistoryButtons.vue create mode 100644 timesketch/frontend/src/components/Explore/SearchHistoryTree.vue create mode 100644 timesketch/frontend/src/components/Explore/SearchHistoryTreeNode.vue create mode 100644 timesketch/frontend/src/components/Explore/TimeFilter.vue create mode 100644 timesketch/frontend/src/components/Explore/TimelineChip.vue create mode 100644 timesketch/frontend/src/components/Explore/TimelinePicker.vue create mode 100644 timesketch/frontend/src/components/Graph/Graph.vue create mode 100644 timesketch/frontend/src/components/Graph/GraphList.vue create mode 100644 timesketch/frontend/src/components/Graph/GraphPluginList.vue create mode 100644 timesketch/frontend/src/components/Home/Graph/Graph.vue create mode 100644 timesketch/frontend/src/components/Home/Graph/GraphList.vue create mode 100644 timesketch/frontend/src/components/Home/Graph/GraphPluginList.vue create mode 100644 timesketch/frontend/src/components/Home/SketchList.vue create mode 100644 timesketch/frontend/src/components/Overview/ShareForm.vue create mode 100644 timesketch/frontend/src/components/Overview/SketchMetrics.vue create mode 100644 timesketch/frontend/src/components/Overview/SketchSummary.vue create mode 100644 timesketch/frontend/src/components/Sigma/SigmaList.vue create mode 100644 timesketch/frontend/src/components/Stories/CreateStoryForm.vue create mode 100644 timesketch/frontend/src/components/Stories/StoryList.vue create mode 100644 timesketch/frontend/src/components/Timelines/TimelineList.vue create mode 100644 timesketch/frontend/src/components/Timelines/TimelineListDropdown.vue create mode 100644 timesketch/frontend/src/components/Timelines/TimelineListItem.vue create mode 100644 timesketch/frontend/src/definitions.js create mode 100644 timesketch/frontend/src/filters/Capitalize.js create mode 100644 timesketch/frontend/src/filters/CompactBytes.js create mode 100644 timesketch/frontend/src/filters/CompactNumber.js create mode 100644 timesketch/frontend/src/filters/FilterChip.js create mode 100644 timesketch/frontend/src/filters/FormatTimestamp.js create mode 100644 timesketch/frontend/src/main.js create mode 100644 timesketch/frontend/src/router.js create mode 100644 timesketch/frontend/src/store.js create mode 100644 timesketch/frontend/src/utils/RegisterAppComponents.js create mode 100644 timesketch/frontend/src/utils/RegisterAppFilters.js create mode 100644 timesketch/frontend/src/utils/RestApiClient.js create mode 100644 timesketch/frontend/src/utils/SigmaRuleTemplates.js create mode 100644 timesketch/frontend/src/utils/tagMetadata.js create mode 100644 timesketch/frontend/src/views/Aggregate.vue create mode 100644 timesketch/frontend/src/views/Analyze.vue create mode 100644 timesketch/frontend/src/views/Attributes.vue create mode 100644 timesketch/frontend/src/views/Explore.vue create mode 100644 timesketch/frontend/src/views/Graph.vue create mode 100644 timesketch/frontend/src/views/GraphExplore.vue create mode 100644 timesketch/frontend/src/views/GraphOverview.vue create mode 100644 timesketch/frontend/src/views/Home.vue create mode 100644 timesketch/frontend/src/views/Intelligence.vue create mode 100644 timesketch/frontend/src/views/Overview.vue create mode 100644 timesketch/frontend/src/views/SavedSearches.vue create mode 100644 timesketch/frontend/src/views/Sigma.vue create mode 100644 timesketch/frontend/src/views/SigmaOverview.vue create mode 100644 timesketch/frontend/src/views/Sketch.vue create mode 100644 timesketch/frontend/src/views/Story.vue create mode 100644 timesketch/frontend/src/views/StoryContent.vue create mode 100644 timesketch/frontend/src/views/StoryOverview.vue create mode 100644 timesketch/frontend/src/views/Timelines.vue create mode 100644 timesketch/frontend/tests/unit/.eslintrc.js create mode 100644 timesketch/frontend/tests/unit/iocmenu.spec.js create mode 100644 timesketch/frontend/vue.config.js create mode 100644 timesketch/lib/llms/features/__init__.py create mode 100644 timesketch/lib/llms/features/interface.py create mode 100644 timesketch/lib/llms/features/llm_summarize.py create mode 100644 timesketch/lib/llms/features/llm_summarize_test.py create mode 100644 timesketch/lib/llms/features/manager.py create mode 100644 timesketch/lib/llms/features/manager_test.py create mode 100644 timesketch/lib/llms/features/nl2q.py create mode 100644 timesketch/lib/llms/features/nl2q_test.py create mode 100644 timesketch/lib/llms/providers/__init__.py create mode 100644 timesketch/lib/llms/providers/aistudio.py create mode 100644 timesketch/lib/llms/providers/interface.py create mode 100644 timesketch/lib/llms/providers/manager.py create mode 100644 timesketch/lib/llms/providers/manager_test.py create mode 100644 timesketch/lib/llms/providers/ollama.py create mode 100644 timesketch/lib/llms/providers/vertexai.py create mode 100644 utils/generate_sample_data.py create mode 100755 utils/update_release.sh diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000000..f2d05bae4d --- /dev/null +++ b/AUTHORS @@ -0,0 +1,10 @@ +Timesketch - Collaborative timeline analysis +https://github.com/google/timesketch/ + +Timesketch is developed by (in alphabetical order): + +* Google Inc. (*@google.com) +* Johan Berggren (jberggren@gmail.com) + +To reach the authors, please use the Timesketch development mailing +list . diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..42d6a63834 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,59 @@ +### Contributing + +#### Before you contribute + +We love contributions! Read this page (including the small print at the end). + +Before we can use your code, you must sign the [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1) (CLA), which you can do online. The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code. We also need to be sure of various other things—for instance that you'll tell us if you know that your code infringes on other people's patents. You don't have to sign the CLA until after you've submitted your code for review and a member has approved it, but you must do it before we can put your code into our codebase. Before you start working on a larger contribution, you should get in touch with us first through the issue tracker with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on. + +We use the github [fork and pull review process](https://help.github.com/articles/using-pull-requests) to review all contributions. First, fork the timesketch repository by following the [github instructions](https://help.github.com/articles/fork-a-repo). Then check out your personal fork: + + $ git clone https://github.com//timesketch.git + +Add an upstream remote so you can easily keep up to date with the main repository: + + $ git remote add upstream https://github.com/google/timesketch.git + +To update your local repo from the main: + + $ git pull upstream master + +Please follow the Style Guide and make your changes. Once you're ready for review make sure the tests pass: + + $ yarn install + $ python ./run_tests.py + +Commit your changes to your personal fork and then use the GitHub Web UI to create and send the pull request. We'll review and merge the change. + +#### Code review + +All submissions, including submissions by project members, require review. To keep the code base maintainable and readable all code is developed using a similar coding style. It ensures: + +The code is easy to maintain and understand. As a developer you'll sometimes find yourself thinking hmm, what is the code supposed to do here. It is important that you should be able to come back to code 5 months later and still quickly understand what it supposed to be doing. Also for other people that want to contribute it is necessary that they need to be able to quickly understand the code. Be that said, quick-and-dirty solutions might work in the short term, but we'll ban them from the code base to gain better long term quality. +With the code review process we ensure that at least two eyes looked over the code in hopes of finding potential bugs or errors (before they become bugs and errors). This also improves the overall code quality and makes sure that every developer knows to (largely) expect the same coding style. + +Exception: Auto generated UI builds +PRs with only auto generated builds of the UI frontend (no new code) made by core project members (repo admins and maintainers with merge permissions) may be merged without review (by repo admins). Rational: All code in the build have already been reviewed. + +#### Documentation review + +One exception from the code review policy outlined above is simple documentation updates and additions made by core project members (repo admins and maintainers with merge permissions). These can be merged without review. + +Note: Any change that affects the layout and structure of the site (timesketch.org) has to go through the review process and any update from external contributors has to be reviewed as well. + +#### Style guide + +We primarily follow the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html). Various Timesketch specific additions/variations are: + +- Quote strings as ' or """ instead of " +- Textual strings should be Unicode strings and hence defined as u'string' + Use the format() function instead of the %-way of formatting strings. + Use positional or parameter format specifiers with typing e.g. '{0:s}' or '{text:s}' instead of '{0}', '{}' or '{:s}'. If we ever want to have language specific output strings we don't need to change the entire codebase. It also makes is easier in determining what type every parameter is expected to be. +- Use "cls" as the name of the class variable in preference of "klass" +- When catching exceptions use "as exception:" not some alternative form like "as error:" or "as details:" +- Use textual pylint overrides e.g. "# pylint: disable=no-self-argument" instead of "# pylint: disable=E0213". For a list of overrides see: http://docs.pylint.org/features.html + +#### The small print + +Contributions made by corporations are covered by a different agreement than +the one above, the Software Grant and Corporate Contributor License Agreement. diff --git a/MANIFEST.in b/MANIFEST.in index 7c1575a99d..0ce6b862e1 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,11 +1,13 @@ -include LICENSE README.md +include AUTHORS LICENSE README.md include requirements.txt test_requirements.txt include run_tests.py exclude .gitignore exclude *.pyc recursive-include config * recursive-include data * +recursive-include timesketch/frontend/dist * recursive-include timesketch/frontend-ng/dist * +recursive-include timesketch/lib/experimental *.cql recursive-include timesketch/static * recursive-include timesketch/templates * recursive-exclude timesketch *.pyc diff --git a/api_client/python/setup.py b/api_client/python/setup.py index 9aa9c25d24..e46a238dbb 100644 --- a/api_client/python/setup.py +++ b/api_client/python/setup.py @@ -15,9 +15,12 @@ """This is the setup file for the project.""" from __future__ import unicode_literals -from setuptools import find_packages, setup +from setuptools import find_packages +from setuptools import setup + from timesketch_api_client import version + long_description = ( "The Timesketch API client provides you with a set of Python libraries " "to connect to your Timesketch (https://github.com/google/timesketch) " diff --git a/api_client/python/timesketch_api_client/aggregation.py b/api_client/python/timesketch_api_client/aggregation.py index dbcd9db8d6..e5be486a1b 100644 --- a/api_client/python/timesketch_api_client/aggregation.py +++ b/api_client/python/timesketch_api_client/aggregation.py @@ -93,11 +93,11 @@ def _run_aggregator( """Run an aggregator class. Args: - aggregator_name: the name of the aggregator class. - parameters: a dict with the parameters for the aggregation class. - search_id: an optional integer value with a primary key to a + aggregator_name (str): the name of the aggregator class. + parameters (dict): a dict with the parameters for the aggregation class. + search_id (int): an optional integer value with a primary key to a saved search. - chart_type: string with the chart type. + chart_type (str): string with the chart type. Returns: A dict with the aggregation results. @@ -136,13 +136,13 @@ def _run_aggregator( return error.get_response_json(response, logger) - # pylint: disable=arguments-differ + # pylint: disable=arguments-renamed def from_saved(self, aggregation_id): """Initialize the aggregation object from a saved aggregation. Args: - aggregation_id: integer value for the stored - aggregation (primary key). + aggregation_id (int): integer value for the stored + aggregation (primary key). """ resource_uri = "sketches/{0:d}/aggregation/{1:d}/".format( self._sketch.id, aggregation_id @@ -188,7 +188,8 @@ def from_manual(self, aggregate_dsl, **kwargs): """Initialize the aggregation object by running an aggregation DSL. Args: - aggregate_dsl: OpenSearch aggregation query DSL string. + aggregate_dsl (str): OpenSearch aggregation query DSL string. + kwargs: Optional arguments """ super().from_manual(**kwargs) resource_url = "{0:s}/sketches/{1:d}/aggregation/explore/".format( @@ -225,12 +226,12 @@ def from_aggregator_run( """Initialize the aggregation object by running an aggregator class. Args: - aggregator_name: name of the aggregator class to run. - aggregator_parameters: a dict with the parameters of the aggregator + aggregator_name (str): name of the aggregator class to run. + aggregator_parameters (dict): a dict with the parameters of the aggregator class. - search_id: an optional integer value with a primary key to a saved + search_id (int): an optional integer value with a primary key to a saved search. - chart_type: optional string with the chart type. + chart_type (str): optional string with the chart type. """ self.type = "aggregator_run" self._parameters = aggregator_parameters @@ -600,7 +601,7 @@ def from_dict(self, group_dict): agg_obj.from_saved(agg_id) self._aggregations.append(agg_obj) - # pylint: disable=arguments-differ + # pylint: disable=arguments-renamed def from_saved(self, group_id): """Feed group data from a group ID. diff --git a/api_client/python/timesketch_api_client/aggregation_test.py b/api_client/python/timesketch_api_client/aggregation_test.py index 737de7d2c1..61f3d9c786 100644 --- a/api_client/python/timesketch_api_client/aggregation_test.py +++ b/api_client/python/timesketch_api_client/aggregation_test.py @@ -13,11 +13,13 @@ # limitations under the License. """Tests for the Timesketch API aggregation object.""" import unittest +import mock import altair as alt -import mock -from . import aggregation, client, test_lib +from . import aggregation +from . import client +from . import test_lib class AggregationTest(unittest.TestCase): @@ -29,6 +31,7 @@ def setUp(self): self.api_client = client.TimesketchApi("http://127.0.0.1", "test", "test") self.sketch = self.api_client.get_sketch(1) + # pylint: disable=protected-access def test_init(self): """Tests the Aggregation init method.""" aggregation_obj = aggregation.Aggregation(self.sketch) diff --git a/api_client/python/timesketch_api_client/client.py b/api_client/python/timesketch_api_client/client.py index a8db97f4d3..74cf0f68b0 100644 --- a/api_client/python/timesketch_api_client/client.py +++ b/api_client/python/timesketch_api_client/client.py @@ -14,20 +14,34 @@ """Timesketch API client.""" from __future__ import unicode_literals -import logging +import time import os +import logging import sys -import webbrowser +# pylint: disable=wrong-import-order import bs4 -import google.auth.transport.requests -import pandas import requests -from google_auth_oauthlib import flow as googleauth_flow -from requests.exceptions import ConnectionError + +# pylint: disable=redefined-builtin +from requests.exceptions import ConnectionError, RequestException from urllib3.exceptions import InsecureRequestWarning +import webbrowser + +# pylint: disable-msg=import-error +from google_auth_oauthlib import flow as googleauth_flow +import google.auth.transport.requests +import pandas + +from . import credentials +from . import definitions +from . import error +from . import index +from . import sketch +from . import user +from . import version +from . import sigma -from . import credentials, definitions, error, index, sigma, sketch, user, version logger = logging.getLogger("timesketch_api.client") @@ -93,6 +107,7 @@ def __init__( self._flow = None if not create_session: + # Session needs to be set manually later using set_session() self._session = None return @@ -197,17 +212,17 @@ def _create_oauth_session( """Return an OAuth session. Args: - client_id: The client ID if OAUTH auth is used. - client_secret: The OAUTH client secret if OAUTH is used. - client_secrets_file: Path to the JSON file that contains the client + client_id (str): The client ID if OAUTH auth is used. + client_secret (str): The OAUTH client secret if OAUTH is used. + client_secrets_file (str): Path to the JSON file that contains the client secrets, in the client_secrets format. - host: Host address the OAUTH web server will bind to. - port: Port the OAUTH web server will bind to. - open_browser: A boolean, if set to false (default) a browser window + host (str): Host address the OAUTH web server will bind to. + port (int): Port the OAUTH web server will bind to. + open_browser (bool): A boolean, if set to false (default) a browser window will not be automatically opened. - run_server: A boolean, if set to true (default) a web server is + run_server (bool): A boolean, if set to true (default) a web server is run to catch the OAUTH request and response. - skip_open: A booelan, if set to True (defaults to False) an + skip_open (bool): A booelan, if set to True (defaults to False) an authorization URL is printed on the screen to visit. This is only valid if run_server is set to False. @@ -309,14 +324,14 @@ def _create_session( """Create authenticated HTTP session for server communication. Args: - username: User to authenticate as. - password: User password. - verify: Verify server SSL certificate. - client_id: The client ID if OAUTH auth is used. - client_secret: The OAUTH client secret if OAUTH is used. - auth_mode: The authentication mode to use. Supported values are + username (str): User to authenticate as. + password (str): User password. + verify (bool): Verify server SSL certificate. + client_id (str): The client ID if OAUTH auth is used. + client_secret (str): The OAUTH client secret if OAUTH is used. + auth_mode (str): The authentication mode to use. Supported values are 'userpass' (username/password combo), 'http-basic' - (HTTP Basic authentication) and oauth. + (HTTP Basic authentication) and oauth Returns: Instance of requests.Session. @@ -334,10 +349,6 @@ def _create_session( session = requests.Session() - # GCP IAP - if token := os.getenv("AUTHORIZATION_TOKEN"): - session.headers = {"Authorization": f"Bearer {token}"} - # If using HTTP Basic auth, add the user/pass to the session if auth_mode == "http-basic": session.auth = (username, password) @@ -356,105 +367,241 @@ def _create_session( return session def fetch_resource_data(self, resource_uri, params=None): - """Make a HTTP GET request. + """Makes an HTTP GET request to the specified resource URI with retries. + + This method attempts to fetch data from the Timesketch API. It implements + a manual retry mechanism with a fixed 1-second backoff between attempts + if the initial request fails or returns an empty (but valid JSON) response. + Retries occur for network connection errors, API errors (non-20x status codes), + JSON decoding errors, or if the API returns a successful (20x) response + with a "falsy" JSON payload (e.g., null, empty list/dictionary). + Args: - resource_uri: The URI to the resource to be fetched. - params: Dict of URL parameters to send in the GET request. + resource_uri (str): The URI to the resource to be fetched. + params (dict, optional): A dictionary of URL parameters to send + in the GET request. Defaults to None. Returns: - Dictionary with the response data. + dict: A dictionary containing the JSON response data from the API. Raises: - ValueError: If response could not be JSON-decoded after - DEFAULT_RETRY_COUNT attempts. - RuntimeError: If the API server returns an error or empty. + requests.exceptions.ConnectionError: If a connection error persists + after all retry attempts. + ValueError: If the API response cannot be JSON-decoded after all + retry attempts. + RuntimeError: If the API server returns an error (non-20x status code) + or a "falsy" JSON response (e.g., null, empty list/dict) + after all retry attempts. """ resource_url = "{0:s}/{1:s}".format(self.api_root, resource_uri) - retry_count = 0 + # Start attempt count from 0, first loop with set it to 1 + attempt = 0 result = None while True: - retry_count += 1 - response = self.session.get(resource_url, params=params) + attempt += 1 + # If this is not the first attempt, wait before trying again + if attempt > 1: + backoff_time = 0.5 * (2 ** (attempt - 2)) + logger.info( + "Waiting %.1fs before next attempt for request '%s'.", + backoff_time, + resource_url, + ) + time.sleep(backoff_time) + try: + response = self.session.get(resource_url, params=params) result = error.get_response_json(response, logger) if result: return result except RuntimeError as e: - if retry_count >= self.DEFAULT_RETRY_COUNT: - raise RuntimeError( - "Error for request '{0:s}' - '{1!s}'".format(resource_url, e) - ) from e + if attempt >= self.DEFAULT_RETRY_COUNT: + # Re-raise the original error after exhausting retries + error_msg = f"Error for request '{resource_url}' - '{e!s}'" + raise RuntimeError(error_msg) from e logger.warning( - "[{0:d}/{1:d}] Parsing the repsonse for request '{2:s}'" - "failed. Trying again...".format( - retry_count, self.DEFAULT_RETRY_COUNT, resource_url - ) + "[%d/%d] API error (RuntimeError) for request '%s' " + "failed. Error: %s. Trying again...", + attempt, + self.DEFAULT_RETRY_COUNT, + resource_url, + str(e), ) except ValueError as e: - if retry_count >= self.DEFAULT_RETRY_COUNT: - raise ValueError( - "Error parsing response for request '{0:s}' - {1!s}".format( - resource_url, e - ) - ) from e + if attempt >= self.DEFAULT_RETRY_COUNT: + # Re-raise the original error after exhausting retries + error_msg = ( + f"Error parsing response for request '{resource_url}'" + f" - {e!s}" + ) + raise ValueError(error_msg) from e logger.warning( - "[{0:d}/{1:d}] Parsing the JSON repsonse for request " - "'{2:s}' failed. Trying again...".format( - retry_count, self.DEFAULT_RETRY_COUNT, resource_url + "[%d/%d] Parsing the JSON response for request '%s' " + "failed. Error: %s. Trying again...", + attempt, + self.DEFAULT_RETRY_COUNT, + resource_url, + e, + ) + except ConnectionError as e: # Explicitly catch connection errors + if attempt >= self.DEFAULT_RETRY_COUNT: + # Re-raise the original error after exhausting retries + error_msg = ( + f"Connection error for request '{resource_url}' " + f"after {self.DEFAULT_RETRY_COUNT} attempts: {e!s}" ) + raise ConnectionError(error_msg) from e + + logger.warning( + "[%d/%d] Connection error for request '%s': %s. Trying again...", + attempt, + self.DEFAULT_RETRY_COUNT, + resource_url, + e, ) - if retry_count >= self.DEFAULT_RETRY_COUNT: - raise RuntimeError( + if attempt >= self.DEFAULT_RETRY_COUNT: + error_msg = ( "Unable to fetch JSON resource data for request: '{0:s}'" " - Response: '{1!s}'".format(resource_url, result) ) + raise RuntimeError(error_msg) def create_sketch(self, name, description=None): """Create a new sketch. + This method attempts to create a new sketch on the Timesketch server. + It implements a retry mechanism with exponential backoff if the initial + request fails due to network issues, API errors, or unexpected + response formats. + Args: - name: Name of the sketch. - description: Description of the sketch. + name (str): Name of the sketch. Cannot be empty. + description (str): Optional description of the sketch. If not + provided, the sketch name will be used as the description. Returns: - Instance of a Sketch object. + Instance of a Sketch object representing the newly created sketch. Raises: - RuntimeError: If response does not contain an 'objects' key after - DEFAULT_RETRY_COUNT attempts. + ValueError: If the provided sketch name is empty, or if the API + response cannot be JSON-decoded after all retry attempts. + requests.exceptions.ConnectionError: If a connection error persists + after all retry attempts. + RuntimeError: If the API server returns an error (non-20x status code), + or if the expected 'objects' structure with a sketch ID is not + found in the API response after all retry attempts. """ if not description: description = name - retry_count = 0 - objects = None - while True: - resource_url = "{0:s}/sketches/".format(self.api_root) - form_data = {"name": name, "description": description} - response = self.session.post(resource_url, json=form_data) - response_dict = error.get_response_json(response, logger) - objects = response_dict.get("objects") - if objects: - break - retry_count += 1 + if not name: + raise ValueError("Sketch name cannot be empty") + resource_url = "{0:s}/sketches/".format(self.api_root) + form_data = {"name": name, "description": description} + last_exception = None - if retry_count >= self.DEFAULT_RETRY_COUNT: - raise RuntimeError("Unable to create a new sketch.") + for attempt in range(self.DEFAULT_RETRY_COUNT): + response = self.session.post(resource_url, json=form_data) + try: + response_dict = error.get_response_json(response, logger) + objects = response_dict.get("objects") + + if ( + objects + and isinstance(objects, list) + and len(objects) > 0 + and isinstance(objects[0], dict) + and "id" in objects[0] + ): + sketch_id = objects[0]["id"] + return self.get_sketch(sketch_id) + + # Handle cases where 'objects' is missing, not a list, empty, + # or its first element is not a dict or lacks an 'id'. + # This assumes a 2xx response, as get_response_json would + # raise otherwise. + log_message = ( + "API for sketch creation returned an unexpected 'objects' " + "format or it was empty." + ) + logger.warning( + "[%d/%d] %s Response: %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + log_message, + response_dict, + ) + last_exception = RuntimeError( + f"{log_message} Response: {response_dict!s}" + ) - sketch_id = objects[0]["id"] - return self.get_sketch(sketch_id) + except RequestException as e: + logger.warning( + "[%d/%d] Request error creating sketch '%s': %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + name, + e, + ) + last_exception = e + except ValueError as e: # JSON decoding error + logger.warning( + "[%d/%d] JSON error creating sketch '%s': %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + name, + e, + ) + last_exception = e + except RuntimeError as e: # Non-20x status + logger.warning( + "[%d/%d] API error creating sketch '%s': %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + name, + e, + ) + last_exception = e + + if attempt < self.DEFAULT_RETRY_COUNT - 1: + backoff_time = 0.5 * (2**attempt) # Exponential backoff + logger.info( + "Waiting %.1fs before next attempt to create sketch '%s'.", + backoff_time, + name, + ) + time.sleep(backoff_time) + else: + # All attempts failed + error_message_detail = ( + "All {0:d} attempts to create sketch '{1:s}' failed.".format( + self.DEFAULT_RETRY_COUNT, name + ) + ) + logger.error("%s Last error: %s", error_message_detail, last_exception) + if last_exception: + raise RuntimeError( + f"{error_message_detail} Last error: {last_exception!s}" + ) from last_exception + raise RuntimeError(error_message_detail) + + # Fallback, should ideally be unreachable. + raise RuntimeError( + "Failed to create sketch '{0:s}' after all retries " + "(unexpected loop exit).".format(name) + ) def create_user(self, username, password): """Create a new user. Args: - username: Name of the user - password: Password of the user + username (str): Name of the user + password (str): Password of the user Returns: True if user created successfully. @@ -525,18 +672,19 @@ def get_sketch(self, sketch_id): """ return sketch.Sketch(sketch_id, api=self) - def get_aggregator_info(self, name="", as_dict=True): + def get_aggregator_info(self, name="", as_pandas=False): """Returns information about available aggregators. Args: - name: String with the name of an aggregator. If the name is not + name (str): String with the name of an aggregator. If the name is not provided, a list with all aggregators is returned. - as_dict: Boolean indicating that the results will be returned - as a dict. + as_pandas (bool): Boolean indicating that the results will be returned + as a Pandas DataFrame instead of a list of dicts. Returns: A list with dict objects with the information about aggregators, - unless as_dict is set to False, then the function returns a DataFrame object. + unless as_pandas is set, then the function returns a DataFrame + object. """ resource_uri = "aggregation/info/" @@ -548,7 +696,7 @@ def get_aggregator_info(self, name="", as_dict=True): else: response_json = self.fetch_resource_data(resource_uri) - if as_dict: + if not as_pandas: return response_json lines = [] @@ -565,8 +713,7 @@ def get_aggregator_info(self, name="", as_dict=True): "name" ) line_dict["field_{0:d}_description".format(field_index + 1)] = ( - field.get("description") - ) + field.get("description")) # fmt: skip lines.append(line_dict) return pandas.DataFrame(lines) @@ -575,15 +722,15 @@ def list_sketches(self, per_page=50, scope="user", include_archived=True): """Get a list of all open sketches that the user has access to. Args: - per_page: Number of items per page when paginating. Default is 50. - scope: What scope to get sketches as. Default to user. + per_page (int): Number of items per page when paginating. Default is 50. + scope (str): What scope to get sketches as. Default to user. user: sketches owned by the user recent: sketches that the user has actively searched in shared: Get sketches that can be accessed admin: Get all sketches if the user is an admin archived: get archived sketches search: pass additional search query - include_archived: If archived sketches should be returned. + include_archived (bool): If archived sketches should be returned. Yields: Sketch objects instances. @@ -625,6 +772,124 @@ def get_searchindex(self, searchindex_id): """ return index.SearchIndex(searchindex_id, api=self) + def create_searchindex(self, searchindex_name: str, opensearch_index_name: str): + """Create a new SearchIndex. + + This method attempts to create a new searchindex on the Timesketch server. + It implements a retry mechanism with exponential backoff if the initial + request fails due to network issues, API errors, or unexpected + response formats. + + Args: + searchindex_name: Name for the searchindex. + opensearch_index_name: The name of the index in opensearch. + + Returns: + Instance of a SearchIndex object. + + Raises: + RuntimeError: If the SearchIndex fails to create after all retries, + or if the API returns an unexpected response format. + requests.exceptions.RequestException: If a connection error persists + after all retries. + ValueError: If the API response cannot be JSON-decoded after all retries. + """ + resource_url = f"{self.api_root}/searchindices/" + form_data = { + "searchindex_name": searchindex_name, + "es_index_name": opensearch_index_name, + } + last_exception = None + + for attempt in range(self.DEFAULT_RETRY_COUNT): + try: + response = self.session.post(resource_url, json=form_data) + response_dict = error.get_response_json( + response, logger + ) # Raises RuntimeError for non-20x, ValueError for JSON decode + objects = response_dict.get("objects") + + if ( + objects + and isinstance(objects, list) + and len(objects) > 0 + and isinstance(objects[0], dict) + and "id" in objects[0] + ): + searchindex_id = objects[0]["id"] + return index.SearchIndex(searchindex_id, api=self) + + log_message = ( + "API for searchindex creation returned an unexpected 'objects' " + "format or it was empty." + ) + logger.warning( + "[%d/%d] %s Response: %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + log_message, + response_dict, + ) + last_exception = RuntimeError( + "{0:s} Response: {1!s}".format(log_message, response_dict) + ) + + except RequestException as e: + logger.warning( + "[%d/%d] Request error creating searchindex '%s': %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + searchindex_name, + e, + ) + last_exception = e + except ValueError as e: # JSON decoding error + logger.warning( + "[%d/%d] JSON error creating searchindex '%s': %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + searchindex_name, + e, + ) + last_exception = e + except RuntimeError as e: # Non-20x status or other API error + logger.warning( + "[%d/%d] API error creating searchindex '%s': %s. Retrying...", + attempt + 1, + self.DEFAULT_RETRY_COUNT, + searchindex_name, + e, + ) + last_exception = e + + if attempt < self.DEFAULT_RETRY_COUNT - 1: + backoff_time = 0.5 * (2**attempt) # Exponential backoff + logger.info( + "Waiting %.1fs before next attempt to create searchindex '%s'.", + backoff_time, + searchindex_name, + ) + time.sleep(backoff_time) + else: + # All attempts failed + error_message_detail = ( + "All {0:d} attempts to create searchindex '{1:s}' failed.".format( + self.DEFAULT_RETRY_COUNT, searchindex_name + ) + ) + logger.error("%s Last error: %s", error_message_detail, last_exception) + if last_exception: + last_exception = RuntimeError( + f"{0:s} Response: {1!s}".format(log_message, response_dict) + ) + raise RuntimeError(error_message_detail) + + # Fallback, should ideally be unreachable. + raise RuntimeError( + "Failed to create searchindex '{0:s}' after all retries " + "(unexpected loop exit).".format(searchindex_name) + ) + def check_celery_status(self, job_id=""): """Return information about outstanding celery tasks or a specific one. @@ -671,18 +936,19 @@ def refresh_oauth_token(self): request = google.auth.transport.requests.Request() self.credentials.credential.refresh(request) - def list_sigmarules(self, as_dict=True): + def list_sigmarules(self, as_pandas=False): """Fetches Sigma rules from the database. Fetches all Sigma rules stored in the database on the system and returns a list of SigmaRule objects of the rules. Args: - as_dict: Boolean indicating that the results will be returned a list of SigmaRuleObjects as a dict or Pandas DataFrame. + as_pandas (bool): Boolean indicating that the results will be returned + as a Pandas DataFrame instead of a list of SigmaRuleObjects. Returns: - List of Sigme rule object instances or - - a pandas Dataframe with all rules if as_dict is False. + - a pandas Dataframe with all rules if as_pandas is True. Raises: ValueError: If no rules are found. @@ -693,7 +959,7 @@ def list_sigmarules(self, as_dict=True): if not response: raise ValueError("No rules found.") - if not as_dict: + if as_pandas: return pandas.DataFrame.from_records(response.get("objects")) for rule_dict in response["objects"]: @@ -719,7 +985,7 @@ def create_sigmarule(self, rule_yaml): is required to parse the rule. Args: - rule_yaml: YAML of the Sigma Rule. + rule_yaml (str): YAML of the Sigma Rule. Returns: Instance of a Sigma object. diff --git a/api_client/python/timesketch_api_client/client_test.py b/api_client/python/timesketch_api_client/client_test.py index bbc51b1626..33c748b1ae 100644 --- a/api_client/python/timesketch_api_client/client_test.py +++ b/api_client/python/timesketch_api_client/client_test.py @@ -15,7 +15,6 @@ from __future__ import unicode_literals import unittest - import mock from . import client @@ -36,12 +35,7 @@ def test_fetch_resource_data(self): response = self.api_client.fetch_resource_data("sketches/") self.assertIsInstance(response, dict) - def test_create_sketch(self): - """Test to create a sketch.""" - sketch = self.api_client.create_sketch("test", "test") - self.assertEqual(sketch.id, 1) - self.assertEqual(sketch.name, "test") - self.assertEqual(sketch.description, "test") + # TODO: Add test for create_sketch() def test_get_sketch(self): """Test to get a sketch.""" diff --git a/api_client/python/timesketch_api_client/config.py b/api_client/python/timesketch_api_client/config.py index 26a1316e09..5085536ee8 100644 --- a/api_client/python/timesketch_api_client/config.py +++ b/api_client/python/timesketch_api_client/config.py @@ -251,8 +251,8 @@ def load_config_file( config_file_path = os.path.join(home_path, self.RC_FILENAME) if not os.path.isfile(config_file_path): - fw = open(config_file_path, "a") - fw.close() + with open(config_file_path, "a", encoding="utf-8") as fw: + fw.close() config = configparser.ConfigParser() try: @@ -340,8 +340,8 @@ def save_config( config = configparser.ConfigParser() if not os.path.isfile(file_path): - fw = open(file_path, "a") - fw.close() + with open(file_path, "a", encoding="utf-8") as fw: + fw.close() # Read in other sections in the config file as well. try: @@ -379,7 +379,7 @@ def save_config( cred_key = cred_key.decode("utf-8") config[section]["cred_key"] = cred_key - with open(file_path, "w") as fw: + with open(file_path, "w", encoding="utf-8") as fw: config.write(fw) def set_config(self, name: Text, value: Any): @@ -435,6 +435,7 @@ def get_client( except IOError as e: logger.error("Unable to load the config file, is it valid?") logger.error("Error: %s", e) + return None try: configure_missing_parameters( @@ -452,6 +453,7 @@ def get_client( "message is %s", e, ) + return None except IOError as e: logger.error("Unable to get a client, with error: %s", e) logger.error( @@ -461,6 +463,7 @@ def get_client( "both files. Or you could have supplied a wrong " "password to undecrypt the token file." ) + return None def configure_missing_parameters( diff --git a/api_client/python/timesketch_api_client/config_test.py b/api_client/python/timesketch_api_client/config_test.py index 57264c88da..cdb13ef797 100644 --- a/api_client/python/timesketch_api_client/config_test.py +++ b/api_client/python/timesketch_api_client/config_test.py @@ -96,7 +96,7 @@ def test_save_config(self): config_obj.save_config(fw.name) fw.seek(0) - with open(fw.name, "r") as fh: + with open(fw.name, "r", encoding="utf-8") as fh: data = fh.read() lines = [x.strip() for x in data.split("\n") if x] diff --git a/api_client/python/timesketch_api_client/crypto.py b/api_client/python/timesketch_api_client/crypto.py index 3626891524..9ae324f216 100644 --- a/api_client/python/timesketch_api_client/crypto.py +++ b/api_client/python/timesketch_api_client/crypto.py @@ -138,6 +138,7 @@ def load_credentials(self, file_path="", password="", config_assistant=None): Raises: IOError: If not able to decrypt the data. + OSError: If the file does not exist. Returns: Credential object (oauth2.credentials.Credentials) read from diff --git a/api_client/python/timesketch_api_client/graph.py b/api_client/python/timesketch_api_client/graph.py index 53f2d3cf6d..1f7469ad41 100644 --- a/api_client/python/timesketch_api_client/graph.py +++ b/api_client/python/timesketch_api_client/graph.py @@ -18,11 +18,13 @@ import logging import dateutil.parser -import networkx as nx -import numpy import pandas +import numpy +import networkx as nx + +from . import error +from . import resource -from . import error, resource logger = logging.getLogger("timesketch_api.graph") @@ -229,7 +231,9 @@ def from_graph(self, graph_obj): self._created_at = time self._updated_at = time - def from_manual(self, data, **kwargs): + def from_manual( + self, data=None, **kwargs + ): # pylint: disable=arguments-differ; pytype: disable=signature-mismatch """Generate a new graph using a dictionary. Args: @@ -304,11 +308,11 @@ def from_plugin(self, plugin_name, plugin_config=None, refresh=False): self._parse_graph_dict(cache_dict) self._description = f"Graph created from the {plugin_name} plugin." - def from_saved(self, graph_id): + def from_saved(self, graph_id): # pylint: disable=arguments-renamed """Initialize the graph object from a saved graph. Args: - graph_id: integer value for the saved graph (primary key). + graph_id (int): integer value for the saved graph (primary key). Raises: ValueError: If issues came up during processing. diff --git a/api_client/python/timesketch_api_client/resource.py b/api_client/python/timesketch_api_client/resource.py index 6d7958683e..96ea5f1fc9 100644 --- a/api_client/python/timesketch_api_client/resource.py +++ b/api_client/python/timesketch_api_client/resource.py @@ -16,14 +16,19 @@ class BaseResource: - """Base resource object.""" + """Base class for Timesketch API resources. + + This class provides common functionality for interacting with API + resources, such as lazy loading of data. + """ def __init__(self, api, resource_uri): - """Initialize object. + """Initializes the BaseResource. Args: api: An instance of TimesketchApi object. - resource_uri: The URI part of the API resource to call. + resource_uri: The specific URI path for this resource + (e.g., "sketches/1/"). """ self.api = api self.resource_uri = resource_uri @@ -32,11 +37,15 @@ def __init__(self, api, resource_uri): def lazyload_data(self, refresh_cache=False): """Load resource data once and cache the result. + This method fetches data from the API for this resource if it hasn't + been fetched yet, or if a cache refresh is requested. The fetched + data is stored in `self.resource_data`. + Args: - refresh_cache: Boolean indicating if to update cache. + refresh_cache (bool): If True, forces a refresh of the cached data. Returns: - Dictionary with resource data. + dict: A dictionary containing the resource data from the API. """ if not self.resource_data or refresh_cache: self.resource_data = self.api.fetch_resource_data(self.resource_uri) @@ -44,10 +53,10 @@ def lazyload_data(self, refresh_cache=False): @property def data(self): - """Property to fetch resource data. + """Property to access the resource's data. Returns: - Dictionary with resource data. + dict: A dictionary containing the resource data from the API. """ return self.lazyload_data() diff --git a/api_client/python/timesketch_api_client/scenario.py b/api_client/python/timesketch_api_client/scenario.py index 3782402987..ea0054752e 100644 --- a/api_client/python/timesketch_api_client/scenario.py +++ b/api_client/python/timesketch_api_client/scenario.py @@ -159,7 +159,7 @@ def getScenarioTemplateList(api): api: An instance of TimesketchApi object. Returns: - list: A list of Scenario tempaltes. + list: A list of Scenario templates. """ resource_url = f"{api.api_root}/scenarios/" response = api.session.get(resource_url) @@ -175,7 +175,7 @@ def getQuestionTemplateList(api): api: An instance of TimesketchApi object. Returns: - list: A list of Question tempaltes. + list: A list of Question templates. """ resource_url = f"{api.api_root}/questions/" response = api.session.get(resource_url) diff --git a/api_client/python/timesketch_api_client/search.py b/api_client/python/timesketch_api_client/search.py index 3778aaba2d..a4649f8d87 100644 --- a/api_client/python/timesketch_api_client/search.py +++ b/api_client/python/timesketch_api_client/search.py @@ -19,7 +19,10 @@ import pandas -from . import error, resource, searchtemplate +from . import error +from . import resource +from . import searchtemplate + logger = logging.getLogger("timesketch_api.search") @@ -257,7 +260,7 @@ def add_end_time(self, end_time): try: dt = datetime.datetime.strptime(end_time, self._DATE_FORMAT_MICROSECONDS) - except ValueError as exc: + except ValueError: try: dt = datetime.datetime.strptime(end_time, self._DATE_FORMAT) except ValueError as exc: @@ -285,7 +288,7 @@ def add_start_time(self, start_time): try: dt = datetime.datetime.strptime(start_time, self._DATE_FORMAT_MICROSECONDS) - except ValueError as exc: + except ValueError: try: dt = datetime.datetime.strptime(start_time, self._DATE_FORMAT) except ValueError as exc: @@ -655,7 +658,7 @@ def expected_size(self): _ = self._execute_query(count=True) return self._total_elastic_size - def from_manual( + def from_manual( # pylint: disable=arguments-differ self, query_string=None, query_dsl=None, @@ -713,11 +716,11 @@ def from_manual( self.resource_data = {} - def from_saved(self, search_id): + def from_saved(self, search_id): # pylint: disable=arguments-renamed """Initialize the search object from a saved search. Args: - search_id: integer value for the saved + search_id (int): integer value for the saved search (primary key). """ resource_uri = f"sketches/{self._sketch.id}/views/{search_id}/" @@ -1078,7 +1081,7 @@ def scrolling_enable(self): self._scrolling = True def to_dict(self): - """Returns a dict with the respone of the query.""" + """Returns a dict with the response of the query.""" if self._raw_response is None: self._execute_query() if self._raw_response is None: @@ -1124,23 +1127,32 @@ def to_pandas(self): for result in self._raw_response.get("objects", []): source = result.get("_source", {}) - - # Remove internal Timesketch fields - for key in list(source.keys()): - if key.startswith("__"): - source.pop(key) + if not return_fields or "_id" in return_field_list: + source["_id"] = result.get("_id") + if not return_fields or "_type" in return_field_list: + source["_type"] = result.get("_type") + if not return_fields or "_index" in return_field_list: + source["_index"] = result.get("_index") + if not return_fields or "_source" in return_field_list: + source["_source"] = timelines.get(result.get("__ts_timeline_id")) + if not return_fields or "__ts_timeline_id" in return_field_list: + source["_source"] = timelines.get(result.get("__ts_timeline_id")) return_list.append(source) data_frame = pandas.DataFrame(return_list) - try: - data_frame["datetime"] = pandas.to_datetime( - data_frame.datetime, utc=True, format="ISO8601", errors="coerce" - ) - except pandas.errors.OutOfBoundsDatetime: - pass - except AttributeError: - pass + if "datetime" in data_frame: + try: + data_frame["datetime"] = pandas.to_datetime(data_frame.datetime) + except pandas.errors.OutOfBoundsDatetime: + pass + elif "timestamp" in data_frame: + try: + data_frame["datetime"] = pandas.to_datetime( + data_frame.timestamp / 1e6, utc=True, unit="s" + ) + except pandas.errors.OutOfBoundsDatetime: + pass return data_frame diff --git a/api_client/python/timesketch_api_client/searchtemplate.py b/api_client/python/timesketch_api_client/searchtemplate.py index a00d7c6f90..544484ffc0 100644 --- a/api_client/python/timesketch_api_client/searchtemplate.py +++ b/api_client/python/timesketch_api_client/searchtemplate.py @@ -69,8 +69,8 @@ def from_saved(self, template_id, sketch_id=0): """Initialize the search template from a saved template, by ID value. Args: - template_id: integer value for the saved search template. - sketch_id: optional integer value for a sketch ID. If not + template_id (int): integer value for the saved search template. + sketch_id (int): optional integer value for a sketch ID. If not provided, an attempt is made to figure it out. Raises: diff --git a/api_client/python/timesketch_api_client/sketch.py b/api_client/python/timesketch_api_client/sketch.py index 34e26e5acd..f96fdbfe00 100644 --- a/api_client/python/timesketch_api_client/sketch.py +++ b/api_client/python/timesketch_api_client/sketch.py @@ -15,17 +15,29 @@ from __future__ import unicode_literals import copy +import os import json +import time import logging -import os import pandas -from . import aggregation, analyzer, definitions, error, graph +from requests.exceptions import RequestException + + +from . import analyzer +from . import aggregation +from . import definitions +from . import error +from . import graph from . import index as api_index from . import resource +from . import search +from . import searchtemplate +from . import story +from . import timeline from . import scenario as scenario_lib -from . import search, searchtemplate, story, timeline + logger = logging.getLogger("timesketch_api.sketch") @@ -42,7 +54,7 @@ class Sketch(resource.BaseResource): """ # Add in necessary fields in data ingested via a different mechanism. - _NECESSARY_DATA_FIELDS = frozenset(["timestamp_desc", "datetime"]) + _NECESSARY_DATA_FIELDS = frozenset(["timestamp", "datetime", "message"]) def __init__(self, sketch_id, api, sketch_name=None): """Initializes the Sketch object. @@ -56,7 +68,7 @@ def __init__(self, sketch_id, api, sketch_name=None): self.api = api self._archived = None self._sketch_name = sketch_name - super().__init__(api=api, resource_uri=f"sketches/{self.id}/") + super().__init__(api=api, resource_uri=f"sketches/{self.id}") @property def acl(self): @@ -392,6 +404,10 @@ def create_view(self, name, query_string="", query_dsl="", query_filter=None): Returns: A search.Search object that has been saved to the database. """ + logger.warning( + "View objects will be deprecated shortly, use search.Search " + "and call the search_obj.save() function to save a search." + ) if not (query_string or query_dsl): raise ValueError("You need to supply a query string or a dsl") @@ -409,11 +425,11 @@ def create_view(self, name, query_string="", query_dsl="", query_filter=None): search_obj.save() return search_obj - def create_story(self, title): + def create_story(self, title: str): """Create a story object. Args: - title: the title of the story. + title (str): the title of the story. Raises: RuntimeError: if a story wasn't created for some reason. @@ -463,17 +479,17 @@ def add_to_acl( """Add users or groups to the sketch ACL. Args: - user_list: optional list of users to add to the ACL + user_list (list[str]): optional list of users to add to the ACL of the sketch. Each user is a string. - group_list: optional list of groups to add to the ACL + group_list (list[str]): optional list of groups to add to the ACL of the sketch. Each user is a string. - make_public: Optional boolean indicating the sketch should be + make_public (bool): Optional boolean indicating the sketch should be marked as public. - permissions: optional list of permissions (read, write, delete). + permissions (list[str]): optional list of permissions (read, write, delete). If not the default set of permissions are applied (read, write) - Returns: - A boolean indicating whether the ACL change was successful. + Returns: + A boolean indicating whether the ACL change was successful. """ if not user_list and not group_list and not make_public: return False @@ -706,9 +722,9 @@ def get_story(self, story_id=None, story_title=None): """Returns a story object that is stored in the sketch. Args: - story_id: an integer indicating the ID of the story to + story_id (int): an integer indicating the ID of the story to be fetched. Defaults to None. - story_title: a string with the title of the story. Optional + story_title (str): a string with the title of the story. Optional and defaults to None. Returns: @@ -745,6 +761,10 @@ def get_view(self, view_id=None, view_name=None): Returns a None if neither view_id or view_name is defined or if the search does not exist. """ + logger.warning( + "This function is about to be deprecated, use " + "get_saved_search() instead." + ) return self.get_saved_search(search_id=view_id, search_name=view_name) @@ -752,9 +772,9 @@ def get_saved_search(self, search_id=None, search_name=None): """Returns a saved search object that is stored in the sketch. Args: - view_id: an integer indicating the ID of the view to + search_id (int): an integer indicating the ID of the saved search to be fetched. Defaults to None. - view_name: a string with the name of the view. Optional + search_name (str): a string with the name of the saved search. Optional and defaults to None. Returns: @@ -779,9 +799,9 @@ def get_timeline(self, timeline_id=None, timeline_name=None): """Returns a timeline object that is stored in the sketch. Args: - timeline_id: an integer indicating the ID of the timeline to + timeline_id (int): an integer indicating the ID of the timeline to be fetched. Defaults to None. - timeline_name: a string with the name of the timeline. Optional + timeline_name (str): a string with the name of the timeline. Optional and defaults to None. Returns: @@ -857,6 +877,10 @@ def list_views(self): Returns: List of search object (instance of search.Search). """ + logger.warning( + "This function will soon be deprecated, use list_saved_searches() " + "instead." + ) return self.list_saved_searches() def list_saved_searches(self): @@ -935,28 +959,7 @@ def list_timelines(self): timelines.append(timeline_obj) return timelines - def upload(self, timeline_name, file_path, es_index=None): - """Deprecated function to upload data, does nothing. - - Args: - timeline_name: Name of the resulting timeline. - file_path: Path to the file to be uploaded. - es_index: Index name for the ES database - - Raises: - RuntimeError: If this function is used, since it has been - deprecated in favor of the importer client. - """ - message = ( - "This function has been deprecated, use the CLI tool: " - "timesketch_importer: https://github.com/google/timesketch/blob/" - "master/docs/UploadData.md#using-the-importer-clie-tool or the " - "importer library: https://github.com/google/timesketch/blob/" - "master/docs/UploadDataViaAPI.md" - ) - logger.error(message) - raise RuntimeError(message) - + # pylint: disable=unused-argument def add_timeline(self, searchindex): """Deprecated function to add timeline to sketch. @@ -981,9 +984,9 @@ def explore( query_filter=None, view=None, return_fields=None, + as_pandas=False, max_entries=None, file_name="", - as_dict=False, as_object=False, ): """Explore the sketch. @@ -992,10 +995,12 @@ def explore( query_string (str): OpenSearch query string. query_dsl (str): OpenSearch query DSL as JSON string. query_filter (dict): Filter for the query as a dict. - view: View object instance (optional). + view (search.Search): View object instance (optional). return_fields (str): A comma separated string with a list of fields that should be included in the response. Optional and defaults to None. + as_pandas (bool): Optional bool that determines if the results + should be returned back as a dictionary or a Pandas DataFrame. max_entries (int): Optional integer denoting a best effort to limit the output size to the number of events. Events are read in, 10k at a time so there may be more events in the answer back @@ -1005,21 +1010,25 @@ def explore( returned back as a dict or a pandas DataFrame. The ZIP file will contain a METADATA file and a CSV with the results from the query. - as_dict (bool): Optional bool that determines whether the - function will return a dict. as_object (bool): Optional bool that determines whether the - function will return a search object back. + function will return a search object back instead of raw + results. Returns: - pandas DataFrame with query results, a dict if as_dict is set to - True or a search.Search object if as_object is set to True. - If file_name is provided then no value will be returned. + Dictionary with query results, a pandas DataFrame if as_pandas + is set to True or a search.Search object if as_object is set + to True. If file_name is provided then no value will be + returned. Raises: ValueError: if unable to query for the results. RuntimeError: if the query is missing needed values, or if the sketch is archived. """ + logger.warning( + "Using this function is discouraged, please consider using " + "the search.Search object instead, which is more flexible." + ) if not (query_string or query_filter or query_dsl or view): raise RuntimeError("You need to supply a query or view") @@ -1030,6 +1039,10 @@ def explore( search_obj = search.Search(sketch=self) if view: + logger.warning( + "View objects will be deprecated soon, use search.Search " + "objects instead." + ) search_obj.from_saved(view.id) else: @@ -1046,10 +1059,10 @@ def explore( if file_name: return search_obj.to_file(file_name) - if as_dict: - return search_obj.to_dict() + if as_pandas: + return search_obj.to_pandas() - return search_obj.to_pandas() + return search_obj.to_dict() def list_available_analyzers(self): """Returns a list of available analyzers.""" @@ -1071,14 +1084,14 @@ def run_analyzer( """Run an analyzer on a timeline. Args: - analyzer_name: the name of the analyzer class to run against the + analyzer_name (str): the name of the analyzer class to run against the timeline. - analyzer_kwargs: optional dict with parameters for the analyzer. + analyzer_kwargs (dict): optional dict with parameters for the analyzer. This is optional and just for those analyzers that can accept further parameters. - timeline_id: the ID of the timeline. This is optional and only + timeline_id (int): the ID of the timeline. This is optional and only required if timeline_name is not set. - timeline_name: the name of the timeline in the timesketch UI. This + timeline_name (str): the name of the timeline in the timesketch UI. This is optional and only required if timeline_id is not set. If there are more than a single timeline with the same name a timeline_id is required. @@ -1090,6 +1103,14 @@ def run_analyzer( If the analyzer runs successfully return back an AnalyzerResult object. """ + # TODO: Deprecate this function. + logger.warning( + "This function is about to be deprecated, please use the " + "`.run_analyzer()` function of a timeline object instead. " + "This function does not support all functionality of the newer " + "implementation in the timeline object." + ) + if self.is_archived(): raise error.UnableToRunAnalyzer( "Unable to run an analyzer on an archived sketch." @@ -1143,13 +1164,13 @@ def remove_acl( """Remove users or groups to the sketch ACL. Args: - user_list: optional list of users to remove from the ACL + user_list (list[str]): optional list of users to remove from the ACL of the sketch. Each user is a string. - group_list: optional list of groups to remove from the ACL + group_list (list[str]): optional list of groups to remove from the ACL of the sketch. Each user is a string. - remove_public: Optional boolean indicating the sketch should be + remove_public (bool): Optional boolean indicating the sketch should be no longer marked as public. - permissions: optional list of permissions (read, write, delete). + permissions (list[str]): optional list of permissions (read, write, delete). If not the default set of permissions are applied (read, write) Returns: @@ -1191,13 +1212,14 @@ def aggregate(self, aggregate_dsl): """Run an aggregation request on the sketch. Args: - aggregate_dsl: OpenSearch aggregation query DSL string. + aggregate_dsl (str): OpenSearch aggregation query DSL string. Returns: An aggregation object (instance of Aggregation). Raises: ValueError: if unable to query for the results. + RuntimeError: if the query is missing needed values """ if self.is_archived(): raise ValueError("Unable to run an aggregation on an archived sketch.") @@ -1279,11 +1301,11 @@ def store_aggregation( """Store an aggregation in the sketch. Args: - name: a name that will be associated with the aggregation. - description: description of the aggregation, visible in the UI. - aggregator_name: name of the aggregator class. - aggregator_parameters: parameters of the aggregator. - chart_type: string representing the chart type. + name (str): a name that will be associated with the aggregation. + description (str): description of the aggregation, visible in the UI. + aggregator_name (str): name of the aggregator class. + aggregator_parameters (dict): parameters of the aggregator. + chart_type (str): string representing the chart type. Raises: RuntimeError: if the client is unable to store the aggregation. @@ -1294,6 +1316,12 @@ def store_aggregation( if self.is_archived(): raise RuntimeError("Unable to store an aggregator on an archived sketch.") + # TODO: Deprecate this function. + logger.warning( + "This function is about to be deprecated, please use the " + "`.save()` function of an aggregation object instead" + ) + aggregator_obj = self.run_aggregator(aggregator_name, aggregator_parameters) aggregator_obj.name = name aggregator_obj.description = description @@ -1309,11 +1337,11 @@ def comment_event(self, event_id, index, comment_text): """Adds a comment to a single event. Args: - event_id: id of the event - index: The OpenSearch index name - comment_text: text to add as a comment + event_id (str): id of the event + index (str): The OpenSearch index name + comment_text (str): text to add as a comment Returns: - a json data of the query. + a json data of the query. """ if self.is_archived(): raise RuntimeError("Unable to comment on an event in an archived sketch.") @@ -1404,67 +1432,18 @@ def label_events(self, events, label_name): response = self.api.session.post(resource_url, json=form_data) return error.get_response_json(response, logger) - def remove_label_event(self, event, label_name): - """Remove a label from an event. - - Args: - event: JSON object representing an event. - label_name: String to label the event with. - - Returns: - Dictionary with query results. - """ - if self.is_archived(): - raise RuntimeError("Unable to label events in an archived sketch.") - - form_data = { - "annotation": label_name, - "annotation_type": "label", - "event_id": event.get("_id"), - "searchindex_id": event.get("_index"), - } - resource_url = "{0:s}/sketches/{1:d}/event/annotate/".format( - self.api.api_root, self.id - ) - response = self.api.session.delete(resource_url, json=form_data) - return error.get_response_json(response, logger) - - def build_event(self, event): - event = [ - { - "_id": event.get("_id"), - "_index": event.get("_index"), - "_type": "generic_event", - } - ] - - return event - - def star_events(self, events): - for event in events["objects"]: - - if "__ts_star" in event.get("_source").get("label"): - continue - - event = self.build_event(event) - - self.label_events(event, "__ts_star") - - def remove_star_events(self, events): - for event in events["objects"]: - - if not "__ts_star" in event.get("_source").get("label"): - continue - - self.remove_label_event(event, "__ts_star") - def untag_events(self, events, tags_to_remove: list): """Removes a list of tags from a list of events. The upper limit is 500 (events or tags) based on the API. Args: - events: events dict. + events (list): events dict. Must have the structure: + "events": [ + { + "_id": event_id, + "_index": index, + } tags_to_remove: list of tags to remove Returns: @@ -1475,7 +1454,7 @@ def untag_events(self, events, tags_to_remove: list): form_data = { "tags_to_remove": tags_to_remove, - "events": events["objects"], + "events": events, } resource_url = "{0:s}/sketches/{1:d}/event/untag/".format( self.api.api_root, self.id @@ -1495,7 +1474,7 @@ def untag_event(self, event_id: str, index, tag: str): Args: event_id: id of the event - index: The OpenSearch index name + index (str): The OpenSearch index name tag: tag to remove Returns: @@ -1523,9 +1502,9 @@ def tag_events(self, events, tags, verbose=False): """Tags one or more events with a list of tags. Args: - events: Array of JSON objects representing events. - tags: List of tags (str) to add to the events. - verbose: Bool that determines whether extra information + events (list): Array of JSON objects representing events. + tags (list[str]): List of tags (str) to add to the events. + verbose (bool): Bool that determines whether extra information is added to the meta dict that gets returned. Raises: @@ -1544,8 +1523,6 @@ def tag_events(self, events, tags, verbose=False): if not all(isinstance(x, str) for x in tags): raise ValueError("Tags need to be a list of strings.") - events = [self.build_event(event)[0] for event in events["objects"]] - form_data = { "tag_string": json.dumps(tags), "events": events, @@ -1555,15 +1532,26 @@ def tag_events(self, events, tags, verbose=False): self.api.api_root, self.id ) response = self.api.session.post(resource_url, json=form_data) - return error.get_response_json(response, logger) + status = error.check_return_status(response, logger) + if not status: + return { + "number_of_events": len(events), + "number_of_events_with_tag": 0, + "success": status, + } + + response_json = error.get_response_json(response, logger) + meta = response_json.get("meta", {}) + meta["total_number_of_events_sent_by_client"] = len(events) + return meta def search_by_label( - self, label_name, return_fields=None, max_entries=None, as_dict=True + self, label_name, return_fields=None, max_entries=None, as_pandas=False ): """Searches for all events containing a given label. Args: - label_name: A string representing the label to search for. + label_name (str): A string representing the label to search for. return_fields (str): A comma separated string with a list of fields that should be included in the response. Optional and defaults to None. @@ -1571,7 +1559,7 @@ def search_by_label( the output size to the number of events. Events are read in, 10k at a time so there may be more events in the answer back than this number denotes, this is a best effort. - as_dict: Optional bool that determines if the results should + as_pandas (bool): Optional bool that determines if the results should be returned back as a dictionary or a Pandas DataFrame. Returns: @@ -1580,6 +1568,11 @@ def search_by_label( if self.is_archived(): raise RuntimeError("Unable to search for labels in an archived sketch.") + logger.warning( + "This function will be deprecated soon. Use the search.Search " + "object instead and add a search.LabelChip to search for labels." + ) + query = { "nested": { "path": "timesketch_label", @@ -1597,7 +1590,7 @@ def search_by_label( query_dsl=json.dumps({"query": query}), return_fields=return_fields, max_entries=max_entries, - as_dict=as_dict, + as_pandas=as_pandas, ) def add_scenario(self, uuid=None, dfiq_id=None, name=None): @@ -1780,16 +1773,17 @@ def add_event(self, message, date, timestamp_desc, attributes=None, tags=None): """Adds an event to the sketch specific timeline. Args: - message: A string that will be used as the message string. - date: A string with the timestamp of the message. This should be + message (str): A string that will be used as the message string. + date (str): A string with the timestamp of the message. This should be in a human readable format, eg: "2020-09-03T22:52:21". - timestamp_desc : Description of the timestamp. - attributes: A dict of extra attributes to add to the event. - tags: A list of strings to include as tags. + timestamp_desc (str): Description of the timestamp. + attributes (dict): A dict of extra attributes to add to the event. + tags (list[str]): A list of strings to include as tags. Raises: ValueError: If tags is not a list of strings or attributes is not a dict. + RuntimeError: If sketch is archived. Returns: Dictionary with query results. @@ -1924,10 +1918,167 @@ def export(self, file_path): with open(file_path, "wb") as fw: fw.write(response.content) + def create_timeline(self, searchindex_id: int, timeline_name: str): + """Creates a Timeline in this Sketch + + This method attempts to create a new timeline associated with this sketch + on the Timesketch server. It links the sketch to an existing SearchIndex + that contains the event data. It implements a retry mechanism with + exponential backoff if the initial request fails due to network issues, + API errors, or unexpected response formats. + + Args: + searchindex_id (int): The ID of the SearchIndex that holds the data + for this timeline. + timeline_name (str): The name of the timeline + + Returns: + An instance of a Timeline object representing the newly created + timeline. + + Raises: + RuntimeError: If the Timeline fails to create after all retries, + or if the API returns an unexpected response format. + requests.exceptions.RequestException: If a connection error persists + after all retries. + ValueError: If the API response cannot be JSON-decoded after all + retries + """ + + resource_url = f"{self.api.api_root}/sketches/{self.id}/timelines/" + form_data = {"timeline": searchindex_id, "timeline_name": timeline_name} + last_exception = None + + for attempt in range(self.api.DEFAULT_RETRY_COUNT): + try: + response = self.api.session.post(resource_url, json=form_data) + # error.get_response_json raises RuntimeError for non-20x, + # ValueError for JSON decode issues. + response_dict = error.get_response_json(response, logger) + objects = response_dict.get("objects") + + if ( + objects + and isinstance(objects, list) + and len(objects) > 0 + and isinstance(objects[0], dict) + and "id" in objects[0] + and "name" in objects[0] + and "searchindex" in objects[0] + and isinstance(objects[0].get("searchindex"), dict) + and "index_name" in objects[0].get("searchindex", {}) + ): + timeline_dict = objects[0] + return timeline.Timeline( + timeline_id=timeline_dict["id"], + sketch_id=self.id, + api=self.api, + name=timeline_dict["name"], + searchindex=timeline_dict["searchindex"]["index_name"], + ) + + log_message = ( + "API for timeline creation returned an unexpected 'objects' " + "format or it was empty." + ) + logger.warning( + "[%d/%d] %s Response: %s. Retrying...", + attempt + 1, + self.api.DEFAULT_RETRY_COUNT, + log_message, + response_dict, + ) + last_exception = RuntimeError( + f"{log_message} Response: {response_dict!s}" + ) + + except RequestException as e: + logger.warning( + "[%d/%d] Request error creating timeline '%s': %s. Retrying...", + attempt + 1, + self.api.DEFAULT_RETRY_COUNT, + timeline_name, + e, + ) + last_exception = e + except (ValueError, RuntimeError) as e: # Covers JSON and non-20x errors + logger.warning( + "[%d/%d] API/JSON error creating timeline '%s': %s. Retrying...", + attempt + 1, + self.api.DEFAULT_RETRY_COUNT, + timeline_name, + e, + ) + last_exception = e + + if attempt < self.api.DEFAULT_RETRY_COUNT - 1: + backoff_time = 0.5 * (2**attempt) # Exponential backoff + logger.info( + "Waiting %.1fs before next attempt to create timeline '%s'.", + backoff_time, + timeline_name, + ) + time.sleep(backoff_time) + else: + # All attempts failed + error_message_detail = ( + f"All {self.api.DEFAULT_RETRY_COUNT} attempts to create " + f"timeline '{timeline_name}' failed." + ) + logger.error("%s Last error: %s", error_message_detail, last_exception) + if last_exception: + raise RuntimeError( + f"{error_message_detail} Last error: {last_exception!s}" + ) from last_exception + raise RuntimeError(error_message_detail) + + # Fallback, should ideally be unreachable. + raise RuntimeError( + f"Failed to create timeline '{timeline_name}' after all retries " + "(unexpected loop exit)." + ) + + def create_datasource( + self, timeline_id: int, provider: str, context: str, data_label: str + ): + """Creates a datasource + + Args: + timeline_id (int): id of the Timeline that this datasource is part of. + provider (str): Name of the application that collected the data. + context (str): Context on how the data was collected. + data_label (str): Data label for the uploaded data. + + Raises: + ValueError: If the datasource object fails to create + + Returns: + Dictionary with the datasource object + """ + resource_url = f"{self.api.api_root}/sketches/{self.id}/datasource/" + form_data = { + "timeline_id": timeline_id, + "provider": provider, + "context": context, + "data_label": data_label, + } + response = self.api.session.post(resource_url, json=form_data) + if response.status_code not in definitions.HTTP_STATUS_CODE_20X: + error.error_message( + response, + message="Error creating a datasource object", + error=ValueError, + ) + + response_json = error.get_response_json(response, logger) + return response_json + def generate_timeline_from_es_index( self, es_index_name, name, + index_name="", + description="", provider="Manually added to OpenSearch", context="Added via API client", data_label="OpenSearch", @@ -1942,17 +2093,19 @@ def generate_timeline_from_es_index( Timeline) for Timesketch to be able to properly support it. Args: - es_index_name: name of the index in OpenSearch. - name: string with the name of the timeline. - description: optional string with a description of the timeline. - provider: optional string with the provider name for the data + es_index_name (str): name of the index in OpenSearch. + name (str): string with the name of the timeline. + index_name (str): optional string for the SearchIndex name, defaults + to the same as the es_index_name. + description (str): optional string with a description of the timeline. + provider (str): optional string with the provider name for the data source of the imported data. Defaults to "Manually added to OpenSearch". - context: optional string with the context for the data upload, + context (str): optional string with the context for the data upload, defaults to "Added via API client". - data_label: optional string with the data label of the OpenSearch + data_label (str): optional string with the data label of the OpenSearch data, defaults to "OpenSearch". - status: Optional string, if provided will be used as a status + status (str): Optional string, if provided will be used as a status for the searchindex, valid options are: "ready", "fail", "processing", "timeout". Defaults to "ready". @@ -1969,34 +2122,21 @@ def generate_timeline_from_es_index( if not name: raise ValueError("Timeline name needs to be provided.") - # Step 1: Create a SearchIndex. - resource_url = f"{self.api.api_root}/searchindices/" - form_data = { - "searchindex_name": es_index_name, - "es_index_name": es_index_name, - } - response = self.api.session.post(resource_url, json=form_data) - - if response.status_code not in definitions.HTTP_STATUS_CODE_20X: - error.error_message( - response, - message="Error creating searchindex", - error=ValueError, - ) - - response_dict = error.get_response_json(response, logger) - objects = response_dict.get("objects") - if not objects: - raise ValueError( - "Unable to create a SearchIndex, try again or file an " - "issue on GitHub." - ) + # Step 1: Make sure the index doesn't exist already. + for index_obj in self.api.list_searchindices(): + if index_obj is None: + continue + if index_obj.index_name == es_index_name: + raise ValueError("Unable to add the ES index, since it already exists.") - searchindex_id = objects[0].get("id") + # Step 2: Create a SearchIndex. + searchindex_name = index_name or es_index_name + searchindex = self.api.create_searchindex(searchindex_name, es_index_name) - # Step 2: Verify mappings to make sure data conforms. - index_obj = api_index.SearchIndex(searchindex_id, api=self.api) + # Step 3: Verify mappings to make sure data conforms. + index_obj = api_index.SearchIndex(searchindex.id, api=self.api) index_fields = set(index_obj.fields) + if not self._NECESSARY_DATA_FIELDS.issubset(index_fields): index_obj.status = "fail" raise ValueError( @@ -2011,54 +2151,28 @@ def generate_timeline_from_es_index( if status: index_obj.status = status - # Step 3: Create the Timeline. - resource_url = f"{self.api.api_root}/sketches/{self.id}/timelines/" - form_data = {"timeline": searchindex_id, "timeline_name": name} - response = self.api.session.post(resource_url, json=form_data) - - if response.status_code not in definitions.HTTP_STATUS_CODE_20X: - error.error_message( - response, - message="Error creating a timeline object", - error=ValueError, - ) - - response_dict = error.get_response_json(response, logger) - objects = response_dict.get("objects") - if not objects: - raise ValueError( - "Unable to create a Timeline, try again or file an issue on GitHub." - ) + # Step 4: Create the Timeline. + created_timeline = self.create_timeline(searchindex.id, name) - timeline_dict = objects[0] - - timeline_obj = timeline.Timeline( - timeline_id=timeline_dict["id"], - sketch_id=self.id, - api=self.api, - name=timeline_dict["name"], - searchindex=timeline_dict["searchindex"]["index_name"], - ) - - # Step 4: Add a DataSource object. - resource_url = f"{self.api.api_root}/sketches/{self.id}/datasource/" + # Step 5: Add the timeline ID into the dataset. + resource_url = f"{self.api.api_root}/sketches/{self.id}/event/add_timeline_id/" form_data = { - "timeline_id": timeline_dict["id"], - "provider": provider, - "context": context, - "data_label": data_label, + "searchindex_id": searchindex.id, + "timeline_id": created_timeline.id, } response = self.api.session.post(resource_url, json=form_data) + if response.status_code not in definitions.HTTP_STATUS_CODE_20X: error.error_message( response, - message="Error creating a datasource object", + message="Unable to add timeline identifier to data", error=ValueError, ) - _ = error.get_response_json(response, logger) + # Step 6: Add a DataSource object. + self.create_datasource(created_timeline.id, provider, context, data_label) - return timeline_obj + return created_timeline def run_data_finder(self, start_date, end_date, rule_names, timelines=None): """Runs the data finder . diff --git a/api_client/python/timesketch_api_client/story.py b/api_client/python/timesketch_api_client/story.py index 6bf49faf3f..c4e1ef3641 100644 --- a/api_client/python/timesketch_api_client/story.py +++ b/api_client/python/timesketch_api_client/story.py @@ -554,11 +554,11 @@ def add_aggregation(self, agg_obj, chart_type="table", index=-1): """Adds an aggregation object to the story. Args: - agg_obj: an aggregation object (instance of aggregation.Aggregation) + agg_obj (aggregation.Aggregation): an aggregation object chart_type (str): string indicating the type of aggregation, can be: "table" or the name of the chart to be used, eg "barcharct", "hbarchart". Defaults to "table". - index: an integer, if supplied determines where the new + index (int): an integer, if supplied determines where the new block will be added. If not supplied it will be appended at the end. @@ -623,8 +623,8 @@ def add_saved_search(self, search_obj, index=-1): """Add a saved search to the story. Args: - search_obj: a search object (instance of search.Search) - index: an integer, if supplied determines where the new + search_obj (search.Search): a search object + index (int): an integer, if supplied determines where the new block will be added. If not supplied it will be appended at the end. diff --git a/api_client/python/timesketch_api_client/test_lib.py b/api_client/python/timesketch_api_client/test_lib.py index 4614e968d3..86b3899683 100644 --- a/api_client/python/timesketch_api_client/test_lib.py +++ b/api_client/python/timesketch_api_client/test_lib.py @@ -23,6 +23,7 @@ def mock_session(): class MockHeaders: """Mock requests HTTP headers.""" + # pylint: disable=unused-argument @staticmethod def update(*args, **kwargs): """Mock header update method.""" @@ -37,11 +38,13 @@ def __init__(self): self.headers = MockHeaders() self._post_done = False + # pylint: disable=unused-argument @staticmethod def get(*args, **kwargs): """Mock GET request handler.""" return mock_response(*args, **kwargs) + # pylint: disable=unused-argument def post(self, *args, **kwargs): """Mock POST request handler.""" kwargs["method"] = "POST" @@ -52,6 +55,7 @@ def post(self, *args, **kwargs): return MockSession() +# pylint: disable=unused-argument def mock_response(*args, **kwargs): """Mocks HTTP response.""" @@ -212,13 +216,9 @@ def json(self): }, "objects": [ { - "_id": 1234, - "_index": "test", - "_source": { - "datetime": "2012-03-14T08:12:03.998281", - "id": 1, - "name": "test", - }, + "id": 1, + "name": "test", + "searchindex": {"id": 1234, "index_name": "test"}, } ], } @@ -229,13 +229,9 @@ def json(self): }, "objects": [ { - "_id": 42, - "_index": "even_more_test", - "_source": { - "datetime": "2012-03-14T08:12:03.998281", - "id": 2, - "name": "more_test", - }, + "id": 2, + "name": "more_test", + "searchindex": {"id": 42, "index_name": "even_more_test"}, } ], } @@ -371,7 +367,7 @@ def json(self): }, "falsepositives": ["Unknown"], "level": "high", - "search_query": '(data_type:("shell\\:zsh\\:history" OR "bash\\:history\\:command" OR "apt\\:history\\:line" OR "selinux\\:line") AND "*apt\\-get\\ install\\ foobar*")', + "search_query": '(data_type:("shell\\:zsh\\:history" OR "bash\\:history\\:command" OR "apt\\:history\\:line" OR "selinux\\:line") AND "*apt\\-get\\ install\\ foobar*")', # pylint: disable=line-too-long "file_name": "N/A", "file_relpath": "N/A", } @@ -458,7 +454,7 @@ def json(self): }, "falsepositives": ["Unknown"], "level": "high", - "search_query": '(data_type:("shell\\:zsh\\:history" OR "bash\\:history\\:command" OR "apt\\:history\\:line" OR "selinux\\:line") AND "*apt\\-get\\ install\\ foobar*")', + "search_query": '(data_type:("shell\\:zsh\\:history" OR "bash\\:history\\:command" OR "apt\\:history\\:line" OR "selinux\\:line") AND "*apt\\-get\\ install\\ foobar*")', # pylint: disable=line-too-long } ], } @@ -775,8 +771,8 @@ def json(self): url_router = { "http://127.0.0.1": MockResponse(text_data=auth_text_data), "http://127.0.0.1/api/v1/sketches/": MockResponse(json_data=sketch_list_data), - "http://127.0.0.1/api/v1/sketches/1/": MockResponse(json_data=sketch_data), - "http://127.0.0.1/api/v1/sketches/1/event/?searchindex_id=test_index&event_id=test_event": MockResponse( + "http://127.0.0.1/api/v1/sketches/1": MockResponse(json_data=sketch_data), + "http://127.0.0.1/api/v1/sketches/1/event/?searchindex_id=test_index&event_id=test_event": MockResponse( # pylint: disable=line-too-long json_data=event_data_1 ), "http://127.0.0.1/api/v1/sketches/1/event/attributes/": MockResponse( @@ -812,14 +808,14 @@ def json(self): "http://127.0.0.1/api/v1/sketches/1/archive/": MockResponse( json_data=archive_data ), - "http://127.0.0.1/api/v1/sigma/rule/5266a592-b793-11ea-b3de-0242ac130004": MockResponse( + "http://127.0.0.1/api/v1/sigma/rule/5266a592-b793-11ea-b3de-0242ac130004": MockResponse( # pylint: disable=line-too-long json_data=sigma_rule ), "http://127.0.0.1/api/v1/sigma/": MockResponse(json_data=sigma_list), "http://127.0.0.1/api/v1/sigma/text/": MockResponse( json_data=sigma_rule_text_mock ), - "http://127.0.0.1/api/v1/sigmarules/5266a592-b793-11ea-b3de-0242ac130004": MockResponse( + "http://127.0.0.1/api/v1/sigmarules/5266a592-b793-11ea-b3de-0242ac130004": MockResponse( # pylint: disable=line-too-long json_data=sigmarule_individual ), "http://127.0.0.1/api/v1/sigmarules/": MockResponse(json_data=sigmarule_list), @@ -878,7 +874,6 @@ def json(self): "http://127.0.0.1/api/v1/sketches/1/explore/": MockResponse( json_data=timeline_data ), - "http://127.0.0.1/api/v1/sketches/": MockResponse(json_data=sketch_list_data), } if kwargs.get("empty", False): diff --git a/api_client/python/timesketch_api_client/timeline.py b/api_client/python/timesketch_api_client/timeline.py index 81250eabc8..9c079d957b 100644 --- a/api_client/python/timesketch_api_client/timeline.py +++ b/api_client/python/timesketch_api_client/timeline.py @@ -182,9 +182,9 @@ def run_analyzer(self, analyzer_name, analyzer_kwargs=None, ignore_previous=Fals """Run an analyzer on a timeline. Args: - analyzer_name: a name of an analyzer class to run against the + analyzer_name (str): a name of an analyzer class to run against the timeline. - analyzer_kwargs: optional dict with parameters for the analyzer. + analyzer_kwargs (dict): optional dict with parameters for the analyzer. This is optional and just for those analyzers that can accept further parameters. ignore_previous (bool): an optional bool, if set to True then @@ -228,9 +228,9 @@ def run_analyzers( """Run an analyzer on a timeline. Args: - analyzer_names: a list of analyzer class names to run against the + analyzer_names (list): a list of analyzer class names to run against the timeline. - analyzer_kwargs: optional dict with parameters for the analyzer. + analyzer_kwargs (dict): optional dict with parameters for the analyzer. This is optional and just for those analyzers that can accept further parameters. It is expected that this is a dict with the key value being the analyzer name, and the value being diff --git a/api_client/python/timesketch_api_client/version.py b/api_client/python/timesketch_api_client/version.py index 6fbae0c897..35e6ee0b4a 100644 --- a/api_client/python/timesketch_api_client/version.py +++ b/api_client/python/timesketch_api_client/version.py @@ -14,7 +14,7 @@ """Version information for Timesketch API Client.""" -__version__ = "20250112" +__version__ = "20250408" def get_version(): diff --git a/cli_client/python/timesketch_cli_client/cli.py b/cli_client/python/timesketch_cli_client/cli.py index 54e9168c20..1c31de4c72 100644 --- a/cli_client/python/timesketch_cli_client/cli.py +++ b/cli_client/python/timesketch_cli_client/cli.py @@ -14,21 +14,24 @@ """Timesketch CLI client.""" import sys - import click + from requests.exceptions import ConnectionError as RequestConnectionError + +# pylint: disable=import-error from timesketch_api_client import config as timesketch_config -from timesketch_cli_client.commands import ( - analyze, - config, - events, - importer, - intelligence, - search, - sigma, -) + +# pylint: enable=import-error + +from timesketch_cli_client.commands import analyze +from timesketch_cli_client.commands import config +from timesketch_cli_client.commands import importer +from timesketch_cli_client.commands import intelligence +from timesketch_cli_client.commands import search from timesketch_cli_client.commands import sketch as sketch_command from timesketch_cli_client.commands import timelines +from timesketch_cli_client.commands import events +from timesketch_cli_client.commands import sigma from .definitions import DEFAULT_OUTPUT_FORMAT from .version import get_version @@ -170,5 +173,6 @@ def cli(ctx, sketch, output): cli.add_command(intelligence.intelligence_group) +# pylint: disable=no-value-for-parameter if __name__ == "__main__": cli() diff --git a/cli_client/python/timesketch_cli_client/commands/analyze.py b/cli_client/python/timesketch_cli_client/commands/analyze.py index 0d58087161..7b257c6889 100644 --- a/cli_client/python/timesketch_cli_client/commands/analyze.py +++ b/cli_client/python/timesketch_cli_client/commands/analyze.py @@ -12,11 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. """Commands for analyzing timelines.""" -import json import sys import time +import json import click + from timesketch_api_client import error @@ -41,13 +42,13 @@ def analysis_group(): help="The id of the timeline you want to analyze.", ) @click.pass_context -def run_analyzer(ctx, analyzer_name, timeline_id): +def run_analyzer(ctx: click.Context, analyzer_name: str, timeline_id: int): """Run an analyzer on one or more timelines. Args: - ctx: Click CLI context object. - analyzer_name: Name of the analyzer to run. - timeline_id: Timeline ID of the timeline to analyze. + ctx (click.Context) (required): Click CLI context object. + analyzer_name (str) (required): Name of the analyzer to run. + timeline_id (int) (required): Timeline ID of the timeline to analyze. """ sketch = ctx.obj.sketch timelines = [] @@ -86,11 +87,11 @@ def run_analyzer(ctx, analyzer_name, timeline_id): @analysis_group.command("list") @click.pass_context -def list_analyzers(ctx): +def list_analyzers(ctx: click.Context): """List all available analyzers. Args: - ctx: Click CLI context object. + ctx (click.Context) (required): Click CLI context object. output-format: Output format to use. Available values: 'json','text' or 'tabular' """ @@ -142,14 +143,16 @@ def list_analyzers(ctx): help="Show the results of an analyzer run dependent from the original one.", ) @click.pass_context -def analyzer_results(ctx, analyzer_name, timeline_id, show_dependent): +def analyzer_results( + ctx: click.Context, analyzer_name: str, timeline_id: int, show_dependent: bool +): """Show the results of an analyzer run on one or more timelines. Args: - ctx: Click CLI context object. - analyzer_name: Name of the analyzer that was run. - timeline_id: Timeline ID of the timeline to analyze. - show_dependent: Show dependent analyzers. (default: False) + ctx (click.Context) (required): Click CLI context object. + analyzer_name (str) (required): Name of the analyzer that was run. + timeline_id (int) (required): Timeline ID of the timeline to analyze. + show_dependent (bool) (optional): Show dependent analyzers. (default: False) using output_format json will always include the dependent analyzers """ sketch = ctx.obj.sketch @@ -209,7 +212,7 @@ def analyzer_results(ctx, analyzer_name, timeline_id, show_dependent): f"Dependent: {status} - {result_priority} \ - {result_summary}" ) - except Exception as e: + except Exception as e: # pylint: disable=broad-except click.echo( f"Unable to get results for analyzer [{analyzer_name}] \ on [{timeline.name}]: {e}" diff --git a/cli_client/python/timesketch_cli_client/commands/attribute.py b/cli_client/python/timesketch_cli_client/commands/attribute.py index 8df1df9f38..8dc7c27059 100644 --- a/cli_client/python/timesketch_cli_client/commands/attribute.py +++ b/cli_client/python/timesketch_cli_client/commands/attribute.py @@ -25,8 +25,29 @@ def attribute_group(): @attribute_group.command("list", help="List all attributes.") @click.pass_context -def list_attributes(ctx): - """List all attributes.""" +def list_attributes(ctx: click.Context): + """Lists all attributes associated with the current sketch. + + Retrieves and displays a list of attributes from the current sketch. + The output format is determined by the context's 'output_format' setting. + Supported output formats are 'json' and 'text'. + + Args: + ctx (click.Context): The Click context object, containing the sketch and + output format. + + Outputs: + JSON: If the output format is 'json', the attributes are printed as a + JSON object. + Text: If the output format is 'text' (or an unsupported format), the + attributes are printed in a human-readable format, showing the name, + ontology, and value of each attribute. + Error message: if no attributes are found, or an unsupported output + type is selected. + + Example: + attribute list # Lists all attributes for the current sketch. + """ sketch = ctx.obj.sketch output = ctx.obj.output_format attributes = sketch.attributes @@ -46,12 +67,27 @@ def list_attributes(ctx): @click.option("--name", required=True, help="Name of the attribute.") @click.option("--ontology", required=True, help="Ontology of the attribute.") @click.pass_context -def remove_attribute(ctx, name, ontology): - """Remove an attribute from a sketch. +def remove_attribute(ctx: click.Context, name: str, ontology: str): + """Removes an attribute from the current sketch. + + Removes the attribute specified by its name and ontology from the sketch. + The output format is forced to 'text' for this command. Args: - name: Name of the attribute. - ontology: Ontology of the attribute. + ctx (click.Context): The Click context object, containing the sketch. + name (str): The name of the attribute to remove. + ontology (str): The ontology of the attribute to remove. + + Errors: + * If the specified attribute is not found in the sketch. + * If an unsupported output format is used. + + Outputs: + Text: A message indicating whether the attribute was successfully + removed or not. + + Example: + attribute remove --name "malware_fam" --ontology "threat_intelligence" """ sketch = ctx.obj.sketch if ctx.obj.output_format != "text": @@ -71,18 +107,24 @@ def remove_attribute(ctx, name, ontology): @click.option("--ontology", required=True, help="Ontology of the attribute.") @click.option("--value", required=True, help="Value of the attribute.") @click.pass_context -def add_attribute(ctx, name, ontology, value): - """Add an attribute to a sketch. +def add_attribute(ctx: click.Context, name: str, ontology: str, value: str): + """Adds an attribute to the current sketch. + + Adds an attribute with the specified name, ontology, and value to the sketch. + The output format is forced to 'text' for this command. Args: - name: Name of the attribute. - ontology: Ontology of the attribute. - value: Value of the attribute. + ctx (click.Context): The Click context object, containing the sketch. + name (str): The name of the attribute to add. + ontology (str): The ontology of the attribute to add. + value (str): The value of the attribute to add. - Example: - timesketch sketch add_attribute - --name ticket_id --ontology text --value 12345 + Outputs: + Text: A message confirming the attribute was added, including its name, + ontology, and value. + Example: + attribute add --name ticket_id --ontology text --value 12345 """ sketch = ctx.obj.sketch if ctx.obj.output_format != "text": diff --git a/cli_client/python/timesketch_cli_client/commands/events.py b/cli_client/python/timesketch_cli_client/commands/events.py index 6f8f34feb5..b54f9dd2d1 100644 --- a/cli_client/python/timesketch_cli_client/commands/events.py +++ b/cli_client/python/timesketch_cli_client/commands/events.py @@ -14,6 +14,7 @@ """Commands for events.""" import sys +from typing import Optional import click @@ -139,25 +140,28 @@ def add_event(ctx, message, date, attributes, timestamp_desc): help="Tag to remove from the event.", ) @click.pass_context -def tag_mod(ctx, timeline_id, event_id, tag): - """Remove a Tag from a event. +def tag_mod( + ctx: click.Context, timeline_id: int, event_id: str, tag: Optional[str] = None +) -> None: + """Removes a tag from an event or lists the event's current tags. - This can be used to remove a tag from an event. - - If no tag is specified, the command will return the - current tags for the event. + Removes a specified tag from an event within a timeline. If no tag is provided, + the command lists the event's current tags. Args: - ctx: Click context object. - timeline_id: The ID of the timeline. - event_id: The ID of the event. - tag: The tag to remove from the event. - - Returns: - HTTP response from the API server. - - Raises: - KeyError: If the event does not exist. + ctx (click.Context): The Click context object, containing the sketch. + timeline_id (int): The ID of the timeline containing the event. + event_id (str): The ID of the event to modify. + tag (Optional[str]): The tag to remove from the event, or a comma-separated + list of tags. If None, lists the event's tags. + + Errors: + * If the specified timeline or event does not exist. + * If the specified event does not exist. + + Outputs: + Text: If a tag is specified, a message indicating the tag was removed. + If no tag is specified, the event's current tags are printed. """ sketch = ctx.obj.sketch timeline = sketch.get_timeline(timeline_id=timeline_id) diff --git a/cli_client/python/timesketch_cli_client/commands/events_test.py b/cli_client/python/timesketch_cli_client/commands/events_test.py index c98d99129e..cc0d06ac60 100644 --- a/cli_client/python/timesketch_cli_client/commands/events_test.py +++ b/cli_client/python/timesketch_cli_client/commands/events_test.py @@ -76,72 +76,6 @@ def test_add_event_comment_vs_comments(self): expected_output = "No such option: --comments Did you mean --comment?" assert expected_output in result.output - def test_add_event_tag(self): - """Test to add a tag to an event.""" - runner = CliRunner() - result = runner.invoke( - events_group, - [ - "--output-format", - "json", - "annotate", - "--event-id", - "1", - "--timeline-id", - "1", - "--tag", - "test", - ], - obj=self.ctx, - ) - print(result.output) - print(result.exception) - print(result.exit_code) - assert "['test']" in result.output - - # todo: Fix the remaining tests here - - def test_add_event_tags(self): - """Test to add multiple tags to an event.""" - runner = CliRunner() - result = runner.invoke( - events_group, - [ - "annotate", - "--event-id", - "1", - "--tag", - "test1,test2", - "--timeline-id", - "1", - ], - obj=self.ctx, - ) - - assert 0 is result.exit_code - - def test_add_event_tags_json(self): - """Test to add multiple tags to an event and output as json.""" - runner = CliRunner() - result = runner.invoke( - events_group, - [ - "--output-format", - "json", - "annotate", - "--event-id", - "1", - "--tag", - "test1,test2", - "--timeline-id", - "1", - ], - obj=self.ctx, - ) - - assert "No such event" in result.output - assert 1 is result.exit_code - def test_failed_add_event(self): """Test to add an event to a sketch with an error.""" runner = CliRunner() @@ -165,23 +99,3 @@ def test_add_event(self): obj=self.ctx, ) assert "Event added to sketch: test" in result.output - - def text_no_output_format_defined_in_config(self): - """Test to add an event to a sketch.""" - - self.ctx = test_lib.get_cli_context_no_output() - runner = CliRunner() - result = runner.invoke( - events_group, - [ - "add", - "--message", - "test message", - "--date", - "2023-03-04T11:31:12", - "--timestamp-desc", - "test", - ], - obj=self.ctx, - ) - assert "Event added to sketch: test" in result.output diff --git a/cli_client/python/timesketch_cli_client/commands/importer.py b/cli_client/python/timesketch_cli_client/commands/importer.py index 2eca7e340a..4dd3441692 100644 --- a/cli_client/python/timesketch_cli_client/commands/importer.py +++ b/cli_client/python/timesketch_cli_client/commands/importer.py @@ -16,6 +16,7 @@ import sys import time +from typing import Optional import click from timesketch_import_client import importer as import_client @@ -25,14 +26,14 @@ @click.option("--timeout", type=int, default=600, help="Seconds to wait for indexing.") @click.argument("file_path", type=click.Path(exists=True)) @click.pass_context -def importer(ctx, name, timeout, file_path): +def importer(ctx: click.Context, name: str, timeout: Optional[int], file_path: str): """Import timeline. Args: - ctx: Click CLI context object. - name: Name of the timeline to create. - timeout: Seconds to wait for indexing. - file_path: File path to the file to import. + ctx (click.Context) (required): Click CLI context object. + name (str) (required): Name of the timeline to create. + timeout (int) (optional): Seconds to wait for indexing. + file_path (str) (required): File path to the file to import. """ sketch = ctx.obj.sketch if not name: diff --git a/cli_client/python/timesketch_cli_client/commands/intelligence.py b/cli_client/python/timesketch_cli_client/commands/intelligence.py index 7ed807f07e..6b2f2586c5 100644 --- a/cli_client/python/timesketch_cli_client/commands/intelligence.py +++ b/cli_client/python/timesketch_cli_client/commands/intelligence.py @@ -15,6 +15,7 @@ import sys import json +from typing import Optional, Literal import click @@ -35,13 +36,16 @@ def intelligence_group(): help="Comma separated list of columns to show. (default: ioc,type)", ) @click.pass_context -def list_intelligence(ctx, header, columns): +def list_intelligence( + ctx: click.Context, header: Optional[bool], columns: Optional[str] = None +): """List all intelligence. Args: - ctx: Click context object. - header: Include header in output. (default is to show header) - columns: Comma separated list of columns to show. (default: ioc,type) + ctx (click.Context) (required): Click context object. + header (bool) (optional): Include header in output. (default is to show header) + columns (str) (optional): Comma separated list of columns to show. + (default: ioc,type) Other options: externalURI, tags """ @@ -109,7 +113,14 @@ def list_intelligence(ctx, header, columns): help="Comma separated list of tags.", ) @click.pass_context -def add_intelligence(ctx, ioc, tags, ioc_type="other"): +def add_intelligence( + ctx: click.Context, + ioc: str, + tags: Optional[str] = None, + ioc_type: Optional[ + Literal["ip", "domain", "url", "md5", "sha1", "sha256", "other"] + ] = "other", +): """Add intelligence to a sketch. A sketch can have multiple intelligence entries. Each entry consists of @@ -118,7 +129,7 @@ def add_intelligence(ctx, ioc, tags, ioc_type="other"): Reference: https://timesketch.org/guides/user/intelligence/ Args: - ctx: Click context object. + ctx: (click.Context) (required) Click context object. ioc: IOC value. ioc_type: Type of the intelligence. This is defined in the ontology file. If a string doesn't match any of the aforementioned IOC types, diff --git a/cli_client/python/timesketch_cli_client/commands/intelligence_test.py b/cli_client/python/timesketch_cli_client/commands/intelligence_test.py index 7058c3729f..db3f8889c8 100644 --- a/cli_client/python/timesketch_cli_client/commands/intelligence_test.py +++ b/cli_client/python/timesketch_cli_client/commands/intelligence_test.py @@ -14,11 +14,15 @@ """Tests for intelligence command.""" import unittest - import mock + from click.testing import CliRunner + +# pylint: disable=import-error from timesketch_api_client import test_lib as api_test_lib +# pylint: enable=import-error + from .. import test_lib from .intelligence import intelligence_group @@ -32,11 +36,17 @@ def setUp(self): self.ctx = test_lib.get_cli_context() def test_list_intelligence(self): - """Test to list Sigma rules.""" + """Test the 'intelligence list' command when no intelligence data exists. + + Verifies that the command exits with a non-zero status code and + prints an appropriate message when the sketch has no intelligence + attributes. + """ runner = CliRunner() result = runner.invoke( intelligence_group, ["list"], obj=self.ctx, ) - assert 1 is result.exit_code + assert result.exit_code == 1 + assert "No intelligence found." in result.output diff --git a/cli_client/python/timesketch_cli_client/commands/search.py b/cli_client/python/timesketch_cli_client/commands/search.py index 439082c83a..22198c92bb 100644 --- a/cli_client/python/timesketch_cli_client/commands/search.py +++ b/cli_client/python/timesketch_cli_client/commands/search.py @@ -16,23 +16,44 @@ import json import sys +from typing import Tuple, Optional import click from tabulate import tabulate + from timesketch_api_client import search -def format_output(search_obj, output_format, show_headers, show_internal_columns): - """Format search result output. +def format_output( + search_obj: search.Search, + output_format: str, + show_headers: bool, + show_internal_columns: bool, +): + """Formats search results from a search object into a specified output format. + + Converts search results from an API Search object into a pandas DataFrame + and then formats it according to the provided output format, + header visibility, and internal column visibility. + Supported output formats are 'text', 'csv', 'json', 'jsonl', and 'tabular'. Args: - search_obj: API Search object. - output_format: The format to use (text, csv, json, jsonl, tabular). - show_headers: Boolean indicating if header row should be displayed. - show_internal_columns: Boolean indicating if internal columns should - be displayed. + search_obj (search.Search): The API Search object containing search results. + output_format (str): The desired output format + ('text', 'csv', 'json', 'jsonl', or 'tabular'). + show_headers (bool): If True, includes headers in the output. + show_internal_columns (bool): If True, includes internal columns in the output. Returns: - Search results in the requested output format. + The formatted search results as a string, or None if an error occurs. + + Returns None if the search_obj.to_pandas() returns an empty data frame. + + Raises: + ImportError: If the 'tabulate' library is not installed and 'tabular' + format is selected. + + Example: + format_output(search_object, "csv", True, False) """ dataframe = search_obj.to_pandas() @@ -68,8 +89,22 @@ def format_output(search_obj, output_format, show_headers, show_internal_columns return result -def describe_query(search_obj): - """Print details of a search query and filter.""" +def describe_query(search_obj: search.Search): + """Displays details of a search query and its associated filter. + + Prints the query string, return fields, and formatted filter associated + with a search object. + + Args: + search_obj (search.Search): The search object to describe. + + Outputs: + Text: The query string, return fields, and a formatted JSON + representation of the query filter. + + Example: + describe_query(my_search_object) # Prints details of the search object. + """ filter_pretty = json.dumps(search_obj.query_filter, indent=2) click.echo(f"Query string: {search_obj.query_string}") click.echo(f"Return fields: {search_obj.return_fields}") @@ -133,21 +168,62 @@ def describe_query(search_obj): help="Show all columns including Timesketch internal ones", ) @click.pass_context +# pylint: disable=too-many-arguments def search_group( - ctx, - query, - times, - time_ranges, - labels, - header, - return_fields, - order, - limit, - saved_search, - describe, - show_internal_columns, + ctx: click.Context, + query: str, + times: Tuple[str, ...] = (), + time_ranges: Tuple[Tuple[str, str], ...] = (), + labels: Tuple[str, ...] = (), + header: bool = True, + return_fields: str = "", + order: str = "asc", + limit: int = 40, + saved_search: Optional[int] = None, + describe: bool = False, + show_internal_columns: bool = False, ): - """Search and explore.""" + """Searches and explores events within a Timesketch sketch. + + Executes a search query against a Timesketch sketch, applying various + filters and formatting the output. + Supports queries using OpenSearch query string syntax, date/time filtering, + label filtering, and saved searches. + The output can be formatted as text, CSV, JSON, JSONL, or tabular, + depending on the context's 'output_format' setting. + + Args: + ctx (click.Context): The Click context object, + containing the sketch and output format. + query (str): The search query in OpenSearch query string format + (default: "*"). + times (Tuple[str, ...]): Datetime filters (e.g., "2020-01-01T12:00"). + time_ranges (Tuple[Tuple[str, str], ...]): Datetime range filters + (e.g., ("2020-01-01", "2020-02-01")). + labels (Tuple[str, ...]): Filters events with the specified labels. + header (bool): Toggles header information in the output (default: True). + return_fields (str): Specifies which event fields to show. + order (str): Orders the output ("asc" or "desc") based on the time field + (default: "asc"). + limit (int): Limits the number of events to show (default: 40). + saved_search (Optional[int]): Uses a saved search query and filters by its ID. + describe (bool): Shows the query and filter details and then exits. + show_internal_columns (bool): Shows all columns, including Timesketch + internal ones. + + Raises: + * If an error occurs during date parsing or if a saved search is not found. + * If an error occurs during date parsing. + + Outputs: + Formatted search results in the specified output format + (text, CSV, JSON, JSONL, or tabular). + If '--describe' is used, query details are printed instead. + + Example: + search --query "mal" --time-range "2023-01-01" "2023-01-31" --limit 10 + search --saved-search 123 --describe + """ sketch = ctx.obj.sketch output_format = ctx.obj.output_format search_obj = search.Search(sketch=sketch) @@ -238,18 +314,49 @@ def saved_searches_group(): @saved_searches_group.command("list") @click.pass_context -def list_saved_searches(ctx): - """List saved searches in the sketch.""" +def list_saved_searches(ctx: click.Context): + """Lists all saved searches within the current sketch. + + Retrieves and displays a list of saved searches from the sketch, showing + their IDs and names. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + + Outputs: + Text: A list of saved searches, with each line showing the search ID and name. + + Example: + saved-searches list # Lists all saved searches in the current sketch. + """ sketch = ctx.obj.sketch for saved_search in sketch.list_saved_searches(): click.echo(f"{saved_search.id} {saved_search.name}") @saved_searches_group.command("describe") -@click.argument("search_id", type=int, required=False) +@click.argument("search_id", type=int, required=True) @click.pass_context -def describe_saved_search(ctx, search_id): - """Show details for saved search.""" +def describe_saved_search(ctx: click.Context, search_id: int): + """Displays details of a specific saved search. + + Retrieves and displays the query string and filter details of a saved search, + identified by its ID. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + search_id (int): The ID of the saved search to describe. + + Raises: + click.ClickException: If the specified saved search ID does not exist. + + Outputs: + Text: The query string and formatted JSON representation of the query + filter for the saved search. + + Example: + saved-searches describe 123 # Describes the saved search with ID 123. + """ sketch = ctx.obj.sketch # TODO (berggren): Add support for saved search name. saved_search = sketch.get_saved_search(search_id=search_id) diff --git a/cli_client/python/timesketch_cli_client/commands/search_test.py b/cli_client/python/timesketch_cli_client/commands/search_test.py index ca275de948..bc8edd5b57 100644 --- a/cli_client/python/timesketch_cli_client/commands/search_test.py +++ b/cli_client/python/timesketch_cli_client/commands/search_test.py @@ -15,13 +15,14 @@ import unittest import mock +import pandas as pd from click.testing import CliRunner from timesketch_api_client import test_lib as api_test_lib - from .. import test_lib from .search import saved_searches_group +from .search import search_group EXPECTED_OUTPUT = """query_string: test:"foobar" @@ -54,3 +55,74 @@ def test_describe_saved_search(self): runner = CliRunner() result = runner.invoke(saved_searches_group, ["describe", "1"], obj=self.ctx) assert result.output == EXPECTED_OUTPUT + + def test_describe_non_existent_saved_search(self): + """Test describing a non-existent saved search.""" + runner = CliRunner() + # MockSketch.get_saved_search returns None for IDs not in its list (e.g., 999) + result = runner.invoke(saved_searches_group, ["describe", "999"], obj=self.ctx) + self.assertEqual(result.exit_code, 0) # Command exits 0 even if not found + self.assertIn("No such saved search", result.output) + + @mock.patch("timesketch_cli_client.commands.search.search.Search") + def test_search_describe_flag(self, MockSearchClient): + """Test the 'search --describe' command.""" + # MockSearchClient is the mock for the Search class. + # MockSearchClient.return_value is the mock instance returned by Search(). + mock_search_instance = MockSearchClient.return_value + + # Configure the mock instance's attributes that are read by the command + mock_search_instance.query_string = "test query" + mock_search_instance.query_filter = { + "chips": [{"type": "label", "value": "test"}] + } + mock_search_instance.return_fields = "message,timestamp" + + runner = CliRunner() + result = runner.invoke( + search_group, + [ + "--query", + "test query", + "--label", + "test", + "--return-fields", + "message,timestamp", + "--describe", + ], + obj=self.ctx, + ) + self.assertEqual(result.exit_code, 0) + self.assertIn("Query string: test query", result.output) + self.assertIn("Return fields: message,timestamp", result.output) + self.assertIn('"type": "label"', result.output) + self.assertIn('"value": "test"', result.output) + + @mock.patch("timesketch_cli_client.commands.search.search.Search") + def test_search_with_results_text_output(self, MockSearchClient): + """Test the 'search' command with text output.""" + # MockSearchClient is the mock for the Search class. + # MockSearchClient.return_value is the mock instance returned by Search(). + mock_search_instance = MockSearchClient.return_value + mock_df = pd.DataFrame( + { + "message": ["event1", "event2"], + "timestamp": [1234567890123, 4567890123456], + "datetime": ["2023-01-01T00:00:00", "2023-01-02T00:00:00"], + } + ) + mock_search_instance.to_pandas.return_value = mock_df + mock_search_instance.return_fields = ( + "message,timestamp,datetime" # Explicitly set for clarity + ) + self.ctx.output_format_from_flag = "text" + runner = CliRunner() + result = runner.invoke(search_group, ["--query", "some query"], obj=self.ctx) + + self.assertEqual(result.exit_code, 0) + # Normalize whitespace for robust comparison + normalized_output = " ".join(result.output.split()) + self.assertIn("message timestamp datetime", normalized_output) + self.assertIn("event1 1234567890123 2023-01-01T00:00:00", normalized_output) + self.assertIn("event2 4567890123456 2023-01-02T00:00:00", normalized_output) + mock_search_instance.to_pandas.assert_called_once() diff --git a/cli_client/python/timesketch_cli_client/commands/sigma.py b/cli_client/python/timesketch_cli_client/commands/sigma.py index 4f3a7bad54..0fc22fba06 100644 --- a/cli_client/python/timesketch_cli_client/commands/sigma.py +++ b/cli_client/python/timesketch_cli_client/commands/sigma.py @@ -47,7 +47,7 @@ def list_sigmarules(ctx, header, columns): output = ctx.obj.output_format try: - sigma_rules = api_client.list_sigmarules() + sigma_rules = api_client.list_sigmarules(as_pandas=True) except ValueError as e: click.echo(e) sys.exit(1) diff --git a/cli_client/python/timesketch_cli_client/commands/sigma_test.py b/cli_client/python/timesketch_cli_client/commands/sigma_test.py index d53d3c17eb..5dff0328d3 100644 --- a/cli_client/python/timesketch_cli_client/commands/sigma_test.py +++ b/cli_client/python/timesketch_cli_client/commands/sigma_test.py @@ -14,11 +14,15 @@ """Tests for sigma command.""" import unittest - import mock + from click.testing import CliRunner + +# pylint: disable=import-error from timesketch_api_client import test_lib as api_test_lib +# pylint: enable=import-error + from .. import test_lib from .sigma import sigma_group diff --git a/cli_client/python/timesketch_cli_client/commands/sketch.py b/cli_client/python/timesketch_cli_client/commands/sketch.py index bba16a1087..16b3379295 100644 --- a/cli_client/python/timesketch_cli_client/commands/sketch.py +++ b/cli_client/python/timesketch_cli_client/commands/sketch.py @@ -15,6 +15,7 @@ import time import json +from typing import Optional import click import pandas as pd @@ -33,8 +34,26 @@ def sketch_group(): @sketch_group.command("list", help="List all sketches.") @click.pass_context -def list_sketches(ctx): - """List all sketches.""" +def list_sketches(ctx: click.Context): + """List all sketches from the API. + + Retrieves a list of sketches from the API associated with the given context. + The output is formatted based on the 'output_format' setting within the + context's object. + Supported output formats are 'json' and 'text'. + + Args: + ctx (click.Context): The Click context object, containing the API + client and output format. + + Raises: + click.exceptions.Exit: If an unsupported output format is specified. + + Outputs: + JSON: If the output format is 'json', a JSON representation is printed. + Text: If the output format is 'text', a formatted table is printed. + Error message: If an unsupported output format is specified + """ api_client = ctx.obj.api output = ctx.obj.output_format sketches = [] @@ -57,9 +76,27 @@ def list_sketches(ctx): help="Describe the active sketch", ) @click.pass_context -def describe_sketch(ctx): - """Describe the active sketch. - Attributes only in JSON output format.""" +def describe_sketch(ctx: click.Context) -> None: + """Displays details of the active sketch. + + Displays the name, description, and status of the active sketch. + If the output format is 'json', all sketch attributes are displayed. + + Args: + ctx (click.Context): The Click context object, containing the sketch + and output format. + + Raises: + * If an unsupported output format is specified. + + Outputs: + Text: The name, description, and status of the sketch. + JSON: All attributes of the sketch object. + Error message: if the output format is not text or json. + + Example: + sketch describe # Displays details of the active sketch. + """ sketch = ctx.obj.sketch output = ctx.obj.output_format @@ -83,12 +120,24 @@ def describe_sketch(ctx): help="Description of the sketch (optional).", ) @click.pass_context -def create_sketch(ctx, name, description): - """Create a new sketch. +def create_sketch( + ctx: click.Context, name: str, description: Optional[str] = None +) -> None: + """Creates a new sketch. + + Creates a new Timesketch sketch with the specified name and optional description. Args: - name: Name of the sketch. - description: Description of the sketch (optional). + ctx (click.Context): The Click context object, containing the API client. + name (str): The name of the new sketch. + description (Optional[str]): The description of the new sketch + (defaults to the name if not provided). + + Outputs: + Text: A message confirming the sketch creation and its name. + + Example: + sketch create --name "My New Sketch" --description "Analysis of incident X" """ api_client = ctx.obj.api if not description: @@ -100,11 +149,24 @@ def create_sketch(ctx, name, description): @sketch_group.command("export", help="Export a sketch") @click.option("--filename", required=True, help="Filename to export to.") @click.pass_context -def export_sketch(ctx, filename): +def export_sketch(ctx: click.Context, filename: str) -> None: """Export a sketch to a file. + Exports all events within the active sketch to a specified file. + The export process can take a significant amount of time depending on the + sketch size. + Args: - filename: Filename to create + ctx (click.Context): The Click context object, containing the sketch. + filename (str): The name of the file to export the sketch data to. + + Raises: + click.exceptions.Exit: If a ValueError occurs during the export process. + + Outputs: + Text: Messages indicating the start, progress, and completion of the + export process, including the time taken. + Error message: If a ValueError occurs during export. """ sketch = ctx.obj.sketch click.echo("Executing export . . . ") @@ -129,8 +191,23 @@ def export_sketch(ctx, filename): @sketch_group.command("archive", help="Archive a sketch") @click.pass_context -def archive_sketch(ctx): - """Archive a sketch.""" +def archive_sketch(ctx: click.Context) -> None: + """Archive a sketch. + + Archives the active sketch, making it read-only and preventing further + modifications. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + + Raises: + click.exceptions.Exit: If the sketch is already archived or the user + lacks permissions to archive it. + + Outputs: + Text: A message indicating whether the sketch was successfully archived. + Error message: If the sketch is already archived or the user lacks permissions. + """ sketch = ctx.obj.sketch # if sketch is already archived error if sketch.is_archived(): @@ -148,8 +225,21 @@ def archive_sketch(ctx): @sketch_group.command("unarchive", help="Unarchive a sketch") @click.pass_context -def unarchive_sketch(ctx): - """Unarchive a sketch.""" +def unarchive_sketch(ctx: click.Context) -> None: + """Unarchive a sketch. + + Unarchives a previously archived sketch, allowing modifications to be made again. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + + Raises: + click.exceptions.Exit: If the sketch is not archived. + + Outputs: + Text: A message indicating whether the sketch was successfully unarchived. + Error message: If the sketch is not archived. + """ sketch = ctx.obj.sketch # if sketch is not archived error if not sketch.is_archived(): @@ -163,8 +253,19 @@ def unarchive_sketch(ctx): @sketch_group.command("add_label", help="Add a label to a sketch") @click.option("--label", required=True, help="Name of label to add.") @click.pass_context -def add_label(ctx, label): - """Add a label to a sketch.""" +def add_label(ctx: click.Context, label: str) -> None: + """Add a label to a sketch. + + Adds a specified label to the active sketch. Labels can be used to + categorize and organize sketches. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + label (str): The label to add. + + Outputs: + Text: A message indicating that the label was added. + """ sketch = ctx.obj.sketch sketch.add_sketch_label(label) click.echo("Label added") @@ -172,8 +273,17 @@ def add_label(ctx, label): @sketch_group.command("list_label", help="List labels of sketch") @click.pass_context -def list_label(ctx): - """List labels of a sketch.""" +def list_label(ctx: click.Context) -> None: + """List labels of a sketch. + + Lists all labels currently associated with the active sketch. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + + Outputs: + Text: A list of labels associated with the sketch. + """ sketch = ctx.obj.sketch click.echo(sketch.labels) @@ -181,8 +291,188 @@ def list_label(ctx): @sketch_group.command("remove_label", help="Remove a label from a sketch") @click.option("--label", required=True, help="Name of label to remove.") @click.pass_context -def remove_label(ctx, label): - """Remove a label from a sketch.""" +def remove_label(ctx: click.Context, label: str) -> None: + """Remove a label from a sketch. + + Removes a specified label from the active sketch. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + label (str): The label to remove. + + Outputs: + Text: A message indicating that the label was removed. + """ sketch = ctx.obj.sketch sketch.remove_sketch_label(label) click.echo("Label removed.") + + +@sketch_group.command( + "export-only-with-annotations", + help="Export events with comments, stars, OR labels.", # Updated help +) +@click.option( + "--filename", required=True, help="Filename to export annotated events to." +) +@click.option( + "--output-format", + type=click.Choice(["csv", "jsonl"], case_sensitive=False), + default="csv", + show_default=True, + help="Format for the exported event data.", +) +@click.option( + "--limit", + type=int, + default=0, # Default 0 means no limit (fetch all) + help="Maximum number of unique annotated events to export (0 for all). " + "Applied *after* combining results.", +) +@click.pass_context +def export_only_with_annotations( + ctx: click.Context, filename: str, output_format: str, limit: int +) -> None: + """Export sketch events that have comments, stars, OR labels to a file. + + This command performs separate API searches for events with comments, + events with stars, and events with other tags (user labels). It then + combines and deduplicates the results before exporting. + + Note: This command relies on API searches. It also does not include sketch + metadata or merge database annotations like the server-side + 'tsctl export-sketch' command. Fetching results for multiple searches + can take longer and consume more memory. + + Args: + ctx (click.Context): The Click context object, containing the sketch. + filename (str): The name of the file to export the annotated events to. + output_format (str): The desired output format ('csv' or 'jsonl'). + limit (int): Maximum number of unique annotated events to export (0 for all). + + Raises: + click.exceptions.Exit: If an error occurs during the export process. + + Outputs: + Text: Messages indicating the start, progress, and completion of the + export process, including the time taken and number of events. + File: The specified output file containing the exported event data. + """ + sketch = ctx.obj.sketch + click.echo(f"Exporting events with comments, stars, OR labels to {filename}...") + click.echo("Performing multiple searches, this may take a while.") + if limit == 0: + click.echo( + click.style( + "WARNING: Fetching up to 10,000 results for each search type" + "(comments, stars, labels). " + "This might consume significant memory. The --limit 0 applies" + "to the combined, unique set from these searches.", + fg="yellow", + ) + ) + + start_time = time.time() + all_events_df = ( + pd.DataFrame() + ) # Initialize an empty DataFrame to hold combined results + + search_max_entries = 10000 # Use a large number for 'unlimited' search + + search_types = { + "comments": {"chip": "comment", "query": None}, + "stars": {"chip": "star", "query": None}, + # Search for tags, excluding the internal star tag + "labels": { + "chip": None, + "query": '_exists_:tag AND NOT tag.keyword:"__ts_star"', + }, + } + + try: + for search_name, config in search_types.items(): + click.echo(f" Searching for events with {search_name}...") + search_obj = search.Search(sketch=sketch) + search_obj.query_string = None # Clear default query + search_obj.max_entries = search_max_entries # Fetch many results + + # If adding all the chips to one search, it would do an AND search + if config["chip"] == "comment": + comment_chip = search.LabelChip() + comment_chip.use_comment_label() + search_obj.add_chip(comment_chip) + elif config["chip"] == "star": + star_chip = search.LabelChip() + star_chip.use_star_label() + search_obj.add_chip(star_chip) + elif config["query"]: + search_obj.query_string = config["query"] + + # Fetch results into a DataFrame + try: + events_df = search_obj.to_pandas() + if not events_df.empty: + click.echo(f" Found {len(events_df)} events.") + # Concatenate results, ignore index to avoid conflicts + all_events_df = pd.concat( + [all_events_df, events_df], ignore_index=True + ) + else: + click.echo(" Found 0 events.") + except Exception as search_err: # pylint: disable=broad-except + click.echo( + f" WARNING: Error during search for {search_name}: {search_err}", + err=True, + ) + # Continue to next search type + + if all_events_df.empty: + click.echo("\nNo annotated events found across all search types.") + return + + # Deduplicate based on event ID ('_id' column) + # Keep the first occurrence if duplicates exist + click.echo( + f"Combining and deduplicating results (found {len(all_events_df)} total)..." + ) + # Ensure '_id' column exists before deduplicating + if "_id" not in all_events_df.columns: + click.echo( + "ERROR: '_id' column not found in results, cannot deduplicate.", + err=True, + ) + ctx.exit(1) + + final_df = all_events_df.drop_duplicates(subset=["_id"], keep="first") + deduplicated_count = len(final_df) + click.echo(f"Found {deduplicated_count} unique annotated events.") + + # Apply limit if specified + if 0 < limit < deduplicated_count: + click.echo(f"Applying limit of {limit} events.") + final_df = final_df.head(limit) + exported_count = limit + else: + exported_count = deduplicated_count + + click.echo(f"Writing {exported_count} events to file...") + + # Write the final DataFrame to the file + with open(filename, "w", encoding="utf-8") as fh: + if output_format == "csv": + fh.write(final_df.to_csv(index=False, header=True, lineterminator="\n")) + elif output_format == "jsonl": + fh.write( + final_df.to_json(orient="records", lines=True, date_format="iso") + + "\n" + ) + + end_time = time.time() + click.echo( + f"\nExport finished: {exported_count} unique annotated events written." + ) + click.echo(f"Export took {end_time - start_time:.2f} seconds.") + + except Exception as e: # pylint: disable=broad-except + click.echo(f"\nError during export: {e}", err=True) + ctx.exit(1) diff --git a/cli_client/python/timesketch_cli_client/commands/sketch_test.py b/cli_client/python/timesketch_cli_client/commands/sketch_test.py index c83e02a4b9..03092288aa 100644 --- a/cli_client/python/timesketch_cli_client/commands/sketch_test.py +++ b/cli_client/python/timesketch_cli_client/commands/sketch_test.py @@ -15,6 +15,7 @@ import unittest import mock +import pandas as pd from click.testing import CliRunner @@ -33,13 +34,303 @@ def setUp(self): self.ctx = test_lib.get_cli_context() def test_list_sketches(self): - """Test to list sketches.""" + """Test the 'sketch list' command. + + Verifies that the command executes successfully and that the output + contains the expected sketch information in text format. + """ runner = CliRunner() + self.ctx.output_format_from_flag = "text" result = runner.invoke(sketch_group, ["list"], obj=self.ctx) - assert result.output == "1 test\n" + self.assertIn("1 test", result.output) def test_describe_sketch(self): - """Test to get details for a sketch.""" + """Test the 'sketch describe' command. + + Verifies that the command executes successfully and that the output + contains the expected sketch name and description in text format. + """ + runner = CliRunner() + original_ctx_obj = self.ctx + + # Set the output_format_from_flag directly on the existing context object. + # The `output_format` property will pick this up. + original_ctx_obj.output_format_from_flag = "text" + + result = runner.invoke(sketch_group, ["describe"], obj=original_ctx_obj) + expected_output = "Name: test\nDescription: test\nStatus: Unknown\n" + self.assertEqual( + result.output, expected_output, f"Unexpected output: {result.output}" + ) + + @mock.patch( + "timesketch_cli_client.commands.sketch.open", new_callable=mock.mock_open + ) + @mock.patch("timesketch_cli_client.commands.sketch.search.Search", autospec=True) + def test_export_only_with_annotations_csv_success( + self, mock_search_class, mock_file_open_func + ): + """Test successful export of annotated events to CSV.""" runner = CliRunner() - result = runner.invoke(sketch_group, ["describe"], obj=self.ctx) - assert result.output == "Name: test\nDescription: test\n" + + df_comments = pd.DataFrame( + { + "_id": ["event1", "event4"], + "message": ["comment_msg1", "shared_msg_comment"], + "field_c": ["c1", "c4"], + } + ) + df_stars = pd.DataFrame( + { + "_id": ["event2", "event4"], + "message": ["star_msg2", "shared_msg_star"], + "field_s": ["s2", "s4"], + } + ) + df_labels = pd.DataFrame( + { + "_id": ["event3", "event5", "event4"], + "message": ["label_msg3", "label_msg5", "shared_msg_label"], + "field_l": ["l3", "l5", "l4"], + } + ) + + # Configure mock Search instances + mock_search_inst_comments = mock.MagicMock() + mock_search_inst_comments.to_pandas.return_value = df_comments + + mock_search_inst_stars = mock.MagicMock() + mock_search_inst_stars.to_pandas.return_value = df_stars + + mock_search_inst_labels = mock.MagicMock() + mock_search_inst_labels.to_pandas.return_value = df_labels + + mock_search_class.side_effect = [ + mock_search_inst_comments, + mock_search_inst_stars, + mock_search_inst_labels, + ] + + result = runner.invoke( + sketch_group, + ["export-only-with-annotations", "--filename", "output.csv"], + obj=self.ctx, + ) + + self.assertEqual(result.exit_code, 0, result.output) + self.assertIn( + "Exporting events with comments, stars, OR labels to output.csv...", + result.output, + ) + self.assertIn("Searching for events with comments...", result.output) + self.assertIn("Found 2 events.", result.output) # For comments + self.assertIn("Searching for events with stars...", result.output) + self.assertIn("Found 2 events.", result.output) # For stars + self.assertIn("Searching for events with labels...", result.output) + self.assertIn("Found 3 events.", result.output) # For labels + self.assertIn( + "Combining and deduplicating results (found 7 total)...", result.output + ) + self.assertIn("Found 5 unique annotated events.", result.output) + self.assertIn("Writing 5 events to file...", result.output) + self.assertIn( + "Export finished: 5 unique annotated events written.", result.output + ) + + mock_file_open_func.assert_called_once_with("output.csv", "w", encoding="utf-8") + + # Construct expected CSV + # Order of concatenation: comments, stars, labels. drop_duplicates keeps first. + # Event4 from comments should be kept. + expected_df = pd.DataFrame( + { + "_id": ["event1", "event4", "event2", "event3", "event5"], + "message": [ + "comment_msg1", + "shared_msg_comment", + "star_msg2", + "label_msg3", + "label_msg5", + ], + "field_c": ["c1", "c4", pd.NA, pd.NA, pd.NA], + "field_s": [pd.NA, pd.NA, "s2", pd.NA, pd.NA], + "field_l": [pd.NA, pd.NA, pd.NA, "l3", "l5"], + } + ) + # Pandas to_csv by default fills NA with empty strings + expected_csv = expected_df.to_csv(index=False, header=True, lineterminator="\n") + + written_content = mock_file_open_func.return_value.write.call_args[0][0] + self.assertEqual(written_content, expected_csv) + + @mock.patch( + "timesketch_cli_client.commands.sketch.open", new_callable=mock.mock_open + ) + @mock.patch("timesketch_cli_client.commands.sketch.search.Search", autospec=True) + def test_export_only_with_annotations_jsonl_with_limit( + self, mock_search_class, mock_file_open_func + ): + """Test successful export to JSONL with a limit.""" + runner = CliRunner() + + df_comments = pd.DataFrame({"_id": ["event1"], "message": ["comment_msg1"]}) + df_stars = pd.DataFrame({"_id": ["event2"], "message": ["star_msg2"]}) + df_labels = pd.DataFrame({"_id": ["event3"], "message": ["label_msg3"]}) + + mock_search_inst_comments = mock.MagicMock() + mock_search_inst_comments.to_pandas.return_value = df_comments + mock_search_inst_stars = mock.MagicMock() + mock_search_inst_stars.to_pandas.return_value = df_stars + mock_search_inst_labels = mock.MagicMock() + mock_search_inst_labels.to_pandas.return_value = df_labels + mock_search_class.side_effect = [ + mock_search_inst_comments, + mock_search_inst_stars, + mock_search_inst_labels, + ] + + result = runner.invoke( + sketch_group, + [ + "export-only-with-annotations", + "--filename", + "output.jsonl", + "--output-format", + "jsonl", + "--limit", + "2", + ], + obj=self.ctx, + ) + self.assertEqual(result.exit_code, 0, result.output) + self.assertIn("Found 3 unique annotated events.", result.output) + self.assertIn("Applying limit of 2 events.", result.output) + self.assertIn("Writing 2 events to file...", result.output) + self.assertIn( + "Export finished: 2 unique annotated events written.", result.output + ) + + mock_file_open_func.assert_called_once_with( + "output.jsonl", "w", encoding="utf-8" + ) + + expected_df = pd.DataFrame( + {"_id": ["event1", "event2"], "message": ["comment_msg1", "star_msg2"]} + ) + expected_jsonl = ( + expected_df.to_json(orient="records", lines=True, date_format="iso") + "\n" + ) + written_content = mock_file_open_func.return_value.write.call_args[0][0] + self.assertEqual(written_content, expected_jsonl) + + @mock.patch( + "timesketch_cli_client.commands.sketch.open", new_callable=mock.mock_open + ) + @mock.patch("timesketch_cli_client.commands.sketch.search.Search", autospec=True) + def test_export_only_with_annotations_no_results( + self, mock_search_class, mock_file_open_func + ): + """Test export when no annotated events are found.""" + runner = CliRunner() + + empty_df = pd.DataFrame( + columns=["_id", "message"] + ) # Ensure _id column for logic + + mock_search_inst = mock.MagicMock() + mock_search_inst.to_pandas.return_value = empty_df + mock_search_class.return_value = mock_search_inst # Same mock for all 3 calls + + result = runner.invoke( + sketch_group, + ["export-only-with-annotations", "--filename", "output.csv"], + obj=self.ctx, + ) + + self.assertEqual(result.exit_code, 0, result.output) + self.assertIn( + "No annotated events found across all search types.", result.output + ) + mock_file_open_func.assert_not_called() + + @mock.patch( + "timesketch_cli_client.commands.sketch.open", new_callable=mock.mock_open + ) + @mock.patch("timesketch_cli_client.commands.sketch.search.Search", autospec=True) + def test_export_only_with_annotations_search_error( + self, mock_search_class, mock_file_open_func + ): + """Test export when one of the searches fails.""" + runner = CliRunner() + + df_comments = pd.DataFrame({"_id": ["event1"], "message": ["comment_msg1"]}) + df_labels = pd.DataFrame({"_id": ["event3"], "message": ["label_msg3"]}) + + mock_search_inst_comments = mock.MagicMock() + mock_search_inst_comments.to_pandas.return_value = df_comments + + mock_search_inst_stars = mock.MagicMock() + mock_search_inst_stars.to_pandas.side_effect = Exception("Star search failed!") + + mock_search_inst_labels = mock.MagicMock() + mock_search_inst_labels.to_pandas.return_value = df_labels + + mock_search_class.side_effect = [ + mock_search_inst_comments, + mock_search_inst_stars, + mock_search_inst_labels, + ] + + result = runner.invoke( + sketch_group, + ["export-only-with-annotations", "--filename", "output.csv"], + obj=self.ctx, + ) + self.assertEqual( + result.exit_code, 0, result.output + ) # Should still succeed overall + self.assertIn( + "WARNING: Error during search for stars: Star search failed!", result.output + ) + self.assertIn( + "Found 2 unique annotated events.", result.output + ) # event1 and event3 + self.assertIn("Writing 2 events to file...", result.output) + + mock_file_open_func.assert_called_once_with("output.csv", "w", encoding="utf-8") + expected_df = pd.DataFrame( + {"_id": ["event1", "event3"], "message": ["comment_msg1", "label_msg3"]} + ) + expected_csv = expected_df.to_csv(index=False, header=True, lineterminator="\n") + written_content = mock_file_open_func.return_value.write.call_args[0][0] + self.assertEqual(written_content, expected_csv) + + @mock.patch("timesketch_cli_client.commands.sketch.search.Search", autospec=True) + def test_export_only_with_annotations_id_column_missing(self, mock_search_class): + """Test export fails if _id column is missing from results.""" + runner = CliRunner() + + df_no_id = pd.DataFrame({"message": ["some_message"]}) + + mock_search_inst_comments = mock.MagicMock() + mock_search_inst_comments.to_pandas.return_value = df_no_id + mock_search_inst_others = mock.MagicMock() + mock_search_inst_others.to_pandas.return_value = pd.DataFrame() + + mock_search_class.side_effect = [ + mock_search_inst_comments, + mock_search_inst_others, + mock_search_inst_others, + ] + + result = runner.invoke( + sketch_group, + ["export-only-with-annotations", "--filename", "output.csv"], + obj=self.ctx, + ) + + self.assertEqual(result.exit_code, 1, result.output) + self.assertIn( + "ERROR: '_id' column not found in results, cannot deduplicate.", + result.output, + ) diff --git a/cli_client/python/timesketch_cli_client/commands/timelines.py b/cli_client/python/timesketch_cli_client/commands/timelines.py index 0cff905d81..f7ac810858 100644 --- a/cli_client/python/timesketch_cli_client/commands/timelines.py +++ b/cli_client/python/timesketch_cli_client/commands/timelines.py @@ -23,11 +23,11 @@ def timelines_group(): @timelines_group.command("list") @click.pass_context -def list_timelines(ctx): +def list_timelines(ctx: click.Context): """List all timelines in the sketch. Args: - ctx: Click CLI context object. + ctx (click.Context): Click CLI context object. """ sketch = ctx.obj.sketch for timeline in sketch.list_timelines(): @@ -37,12 +37,30 @@ def list_timelines(ctx): @timelines_group.command("describe") @click.argument("timeline-id", type=int, required=True) @click.pass_context -def describe_timeline(ctx, timeline_id): - """Show details for a timeline. +def describe_timeline(ctx: click.Context, timeline_id: int): + """Displays detailed information about a timeline. + + Retrieves and displays details about a timeline within the current sketch, + including its name, index, status, event count, color, fields, and + associated datasources. + The output format is determined by the context's 'output_format' setting. + Supported output formats are 'json' and 'text'. Args: - ctx: Click CLI context object. - timeline-id: Timeline ID from argument. + ctx (click.Context): The Click context object, containing the sketch + and output format. + timeline_id (int): The ID of the timeline to describe. + + Outputs: + JSON: If the output format is 'json', the timeline's resource data + is printed as JSON. + Text: If the output format is 'text' (or an unsupported format), + detailed information about the timeline is printed in a + human-readable format. + Error message: if the timeline id is not found. + + Example: + timeline describe 1 # Displays details for timeline 1. """ sketch = ctx.obj.sketch output = ctx.obj.output_format @@ -85,13 +103,29 @@ def describe_timeline(ctx, timeline_id): @click.argument("timeline-id", type=int, required=True) @click.argument("new-name", type=str, required=True) @click.pass_context -def rename_timeline(ctx, timeline_id, new_name): - """Rename a timeline. +def rename_timeline(ctx: click.Context, timeline_id: int, new_name: str): + """Renames a timeline within the current sketch. + + The timeline is identified by its integer ID, and its name is changed to + the provided new name. + The output format is determined by the context's 'output_format' setting. + Supported output formats are 'json' and 'text'. Args: - ctx: Click CLI context object. - timeline-id: Timeline ID from argument. - new-name: New Timeline name + ctx (click.Context): The Click context object, containing the + sketch and output format. + timeline_id (int): The ID of the timeline to rename. + new_name (str): The new name for the timeline. + + Outputs: + JSON: If the output format is 'json', the timeline's resource data is + printed as JSON. + Text: If the output format is 'text' (or an unsupported format), + the new timeline name is printed. + Error message: if the timeline id is not found. + + Example: + timeline rename 1 "New Timeline Name" # Renames timeline 1. """ sketch = ctx.obj.sketch output = ctx.obj.output_format @@ -117,13 +151,13 @@ def rename_timeline(ctx, timeline_id, new_name): @timelines_group.command("delete") @click.argument("timeline-id", type=int, required=True) @click.pass_context -def delete_timeline(ctx, timeline_id): +def delete_timeline(ctx: click.Context, timeline_id: int): """Delete a timeline. (Will mark a timeline as deleted, but the Opensearch Index will remain) Args: - ctx: Click CLI context object. - timeline-id: Timeline ID from argument to be deleted. + ctx (click.Context) (required): Click CLI context object. + timeline_id (int) (required): Timeline ID from argument to be deleted. """ sketch = ctx.obj.sketch timeline = sketch.get_timeline(timeline_id=timeline_id) @@ -144,13 +178,19 @@ def delete_timeline(ctx, timeline_id): @click.argument("timeline-id", type=int, required=True) @click.argument("color", type=str, required=True) @click.pass_context -def timeline_change_color(ctx, timeline_id, color): - """Change the color of a timeline (in HEX color code) +def timeline_change_color(ctx: click.Context, timeline_id: int, color: str): + """Changes the color of a timeline within the current sketch. + + The color is specified as a hexadecimal string (without the leading '#'). + The timeline is identified by its integer ID. Args: - ctx: Click CLI context object. - timeline-id: Timeline ID from argument to be modified. - color: Hex value of color to be used for the timeline + ctx (click.Context): The Click context object, containing the sketch. + timeline_id (int): The ID of the timeline to modify. + color (str): The hexadecimal color code (e.g., "AAAA" or "AABB11"). + + Example: + timeline color 1 AABBCC # Changes the color of timeline 1 to AABBCC. """ sketch = ctx.obj.sketch timeline = sketch.get_timeline(timeline_id=timeline_id) diff --git a/cli_client/python/timesketch_cli_client/commands/timelines_test.py b/cli_client/python/timesketch_cli_client/commands/timelines_test.py index 272fed0093..d7f0ae6ce1 100644 --- a/cli_client/python/timesketch_cli_client/commands/timelines_test.py +++ b/cli_client/python/timesketch_cli_client/commands/timelines_test.py @@ -36,10 +36,13 @@ def test_list_timelines(self): """Test to list timelines.""" runner = CliRunner() result = runner.invoke(timelines_group, ["list"], obj=self.ctx) - assert result.output == "1 test\n2 test\n" + assert "1 test" in result.output + assert "2 test\n" in result.output def test_describe_timeline(self): """Test to get detail for a timeline.""" runner = CliRunner() result = runner.invoke(timelines_group, ["describe", "1"], obj=self.ctx) - assert result.output == "Name: test\nIndex: test\n" + assert "Name: test" in result.output + assert "Index: test" in result.output + assert "Event count: 0" in result.output diff --git a/cli_client/python/timesketch_cli_client/version.py b/cli_client/python/timesketch_cli_client/version.py index 3bb4dc5a97..2d87f4056c 100644 --- a/cli_client/python/timesketch_cli_client/version.py +++ b/cli_client/python/timesketch_cli_client/version.py @@ -13,7 +13,7 @@ # limitations under the License. """Version information for the Timesketch CLI client.""" -__version__ = "20250112" +__version__ = "20250408" def get_version(): diff --git a/config/dpkg/changelog b/config/dpkg/changelog new file mode 100644 index 0000000000..6cee068e6d --- /dev/null +++ b/config/dpkg/changelog @@ -0,0 +1,5 @@ +timesketch (20210224-1) unstable; urgency=low + + * Auto-generated + + -- Timesketch development team Wed, 24 Feb 2021 16:45:28 +0100 diff --git a/config/dpkg/clean b/config/dpkg/clean new file mode 100644 index 0000000000..509b0434bc --- /dev/null +++ b/config/dpkg/clean @@ -0,0 +1,4 @@ +timesketch/*.pyc +timesketch/*/*.pyc +timesketch/*/*/*.pyc +*.pyc diff --git a/config/dpkg/compat b/config/dpkg/compat new file mode 100644 index 0000000000..ec635144f6 --- /dev/null +++ b/config/dpkg/compat @@ -0,0 +1 @@ +9 diff --git a/config/dpkg/control b/config/dpkg/control new file mode 100644 index 0000000000..3183c97360 --- /dev/null +++ b/config/dpkg/control @@ -0,0 +1,36 @@ +Source: timesketch +Section: python +Priority: extra +Maintainer: Timesketch development team +Build-Depends: debhelper (>= 9), dh-python, dh-systemd (>= 1.5), python3-all (>= 3.6~), python3-setuptools, python3-pip +Standards-Version: 4.1.4 +X-Python3-Version: >= 3.6 +Homepage: http://timesketch.org + +Package: timesketch-data +Architecture: all +Depends: ${misc:Depends} +Description: Data files for Timesketch + Timesketch is a web based tool for collaborative forensic + timeline analysis. Using sketches you and your collaborators can easily + organize timelines and analyze them all at the same time. Add meaning + to your raw data with rich annotations, comments, tags and stars. + +Package: python3-timesketch +Architecture: all +Depends: timesketch-data (>= ${binary:Version}), python3-alembic (>= 1.3.2), python3-altair (>= 4.1.0), python3-amqp (>= 2.2.1), python3-aniso8601 (>= 1.2.1), python3-asn1crypto (>= 0.24.0), python3-attr (>= 19.1.0), python3-bcrypt (>= 3.1.3), python3-billiard (>= 3.5.0.3), python3-blinker (>= 1.4), python3-bs4 (>= 4.6.3), python3-celery (>= 4.4.0), python3-certifi (>= 2017.7.27.1), python3-cffi (>= 1.10.0), python3-chardet (>= 3.0.4), python3-ciso8601 (>= 2.1.1), python3-click (>= 6.7), python3-cryptography (>= 2.4.1), python3-datasketch (>= 1.5.0), python3-dateutil (>= 2.6.1), python3-editor (>= 1.0.3), python3-elasticsearch (>= 7.5.1), python3-entrypoints (>= 0.2.3), python3-flask (>= 1.1.1), python3-flask-bcrypt (>= 0.7.1), python3-flask-login (>= 0.4.1), python3-flask-migrate (>= 2.5.2), python3-flask-restful (>= 0.3.7), python3-flask-script (>= 2.0.6), python3-flask-sqlalchemy (>= 2.4.1), python3-flaskext.wtf (>= 0.14.2), python3-google-auth (>= 2.32.0), python3-google-auth-oauthlib (>= 0.4.1), python3-gunicorn (>= 19.7.1), python3-idna (>= 2.6), python3-itsdangerous (>= 0.24), python3-jinja2 (>= 2.10), python3-jsonschema (>= 2.6.0), python3-jwt (>= 1.7.1), python3-kombu (>= 4.1.0), python3-mako (>= 1.0.7), python3-markdown (>= 3.2.2), python3-markupsafe (>= 1.0), python3-networkx (>= 2.4), python3-numpy (>= 1.17.5), python3-oauthlib (>= 3.1.0), python3-pandas (>= 0.25.3), python3-parameterized (>= 0.6.1), python3-prometheus-client (>= 0.9.0), python3-prometheus-flask-exporter (>= 0.18.1), python3-pycparser (>= 2.18), python3-pyrsistent (>= 0.14.11), python3-redis (>= 3.3.11), python3-requests (>= 2.23.0), python3-requests-oauthlib (>= 1.3.0), python3-sigmatools (>= 0.15.0), python3-six (>= 1.10.0), python3-sqlalchemy (>= 1.3.12), python3-tabulate (>= 0.8.6), python3-toolz (>= 0.8.2), python3-tz, python3-urllib3 (>= 1.24.1), python3-vine (>= 1.1.4), python3-werkzeug (>= 0.14.1), python3-wtforms (>= 2.2.1), python3-xlrd (>= 1.2.0), python3-xmltodict (>= 0.12.0), python3-yaml (>= 3.10), python3-zipp (>= 0.5), ${python3:Depends}, ${misc:Depends} +Description: Python 3 module of Timesketch + Timesketch is a web based tool for collaborative forensic + timeline analysis. Using sketches you and your collaborators can easily + organize timelines and analyze them all at the same time. Add meaning + to your raw data with rich annotations, comments, tags and stars. + +Package: timesketch-server +Architecture: all +Depends: apt-transport-https, gunicorn, python3-psycopg2, python3-timesketch (>= ${binary:Version}), ${python3:Depends}, ${misc:Depends} +Recommends: elasticsearch, openjdk-8-jre-headless, postgresql, redis-server +Description: Timesketch server + Timesketch is a web based tool for collaborative forensic + timeline analysis. Using sketches you and your collaborators can easily + organize timelines and analyze them all at the same time. Add meaning + to your raw data with rich annotations, comments, tags and stars. diff --git a/config/dpkg/copyright b/config/dpkg/copyright new file mode 100644 index 0000000000..92c4a38df9 --- /dev/null +++ b/config/dpkg/copyright @@ -0,0 +1,27 @@ +Format: http://dep.debian.net/deps/dep5 +Upstream-Name: timesketch +Source: https://github.com/google/timesketch/ + +Files: * +Copyright: 2014 The Timesketch Project Authors. +License: Apache-2.0 + +Files: debian/* +Copyright: 2019 The Timesketch Project Authors. +License: Apache-2.0 + +License: Apache-2.0 + 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. + . + On Debian systems, the complete text of the Apache version 2.0 license + can be found in "/usr/share/common-licenses/Apache-2.0". diff --git a/config/dpkg/python3-timesketch.install b/config/dpkg/python3-timesketch.install new file mode 100644 index 0000000000..203c98cc12 --- /dev/null +++ b/config/dpkg/python3-timesketch.install @@ -0,0 +1,7 @@ +usr/lib/python3*/dist-packages/timesketch/*.py +usr/lib/python3*/dist-packages/timesketch/*/*.py +usr/lib/python3*/dist-packages/timesketch/*/*/*.py +usr/lib/python3*/dist-packages/timesketch/*/*/*/*.py +usr/lib/python3*/dist-packages/timesketch/frontend/dist/* +usr/lib/python3*/dist-packages/timesketch/frontend/dist/*/* +usr/lib/python3*/dist-packages/timesketch*.egg-info/* diff --git a/config/dpkg/rules b/config/dpkg/rules new file mode 100755 index 0000000000..2ce7fa4610 --- /dev/null +++ b/config/dpkg/rules @@ -0,0 +1,24 @@ +#!/usr/bin/make -f + +%: + dh $@ --buildsystem=pybuild --with=python3,systemd + +.PHONY: override_dh_auto_test +override_dh_auto_test: + +.PHONY: override_dh_auto_install +override_dh_auto_install: + dh_auto_install + rm -f debian/tmp/usr/lib/python3*/dist-packages/timesketch-*.egg-info/requires.txt + +.PHONY: override_dh_installinit +override_dh_installinit: + dh_installinit --name=timesketch + +.PHONY: override_dh_python3 +override_dh_python3: + dh_python3 -p timesketch-server --shebang=/usr/bin/python3 + +.PHONY: override_dh_systemd_enable +override_dh_systemd_enable: + dh_systemd_enable --name=timesketch diff --git a/config/dpkg/source/format b/config/dpkg/source/format new file mode 100644 index 0000000000..163aaf8d82 --- /dev/null +++ b/config/dpkg/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/config/dpkg/timesketch-data.dirs b/config/dpkg/timesketch-data.dirs new file mode 100644 index 0000000000..f492301442 --- /dev/null +++ b/config/dpkg/timesketch-data.dirs @@ -0,0 +1 @@ +/usr/share/timesketch diff --git a/config/dpkg/timesketch-data.install b/config/dpkg/timesketch-data.install new file mode 100644 index 0000000000..f8c5665072 --- /dev/null +++ b/config/dpkg/timesketch-data.install @@ -0,0 +1 @@ +data/* usr/share/timesketch diff --git a/config/dpkg/timesketch-server.dirs b/config/dpkg/timesketch-server.dirs new file mode 100644 index 0000000000..bf1393bced --- /dev/null +++ b/config/dpkg/timesketch-server.dirs @@ -0,0 +1 @@ +/var/log/timesketch diff --git a/config/dpkg/timesketch-server.install b/config/dpkg/timesketch-server.install new file mode 100644 index 0000000000..e772481755 --- /dev/null +++ b/config/dpkg/timesketch-server.install @@ -0,0 +1 @@ +usr/bin diff --git a/config/dpkg/timesketch-server.postinst b/config/dpkg/timesketch-server.postinst new file mode 100644 index 0000000000..df271eabe7 --- /dev/null +++ b/config/dpkg/timesketch-server.postinst @@ -0,0 +1,47 @@ +#!/bin/sh +set -e + +. /usr/share/debconf/confmodule + +case "$1" in + configure) + logdir="/var/log/timesketch" + + # Allow local admin to override + if ! dpkg-statoverride --list "$logdir" >/dev/null; then + chown root:adm $logdir + chmod 0755 $logdir + fi + + # Secure default logfiles on fresh installations + if [ -z "$2" ]; then + access_log="$logdir/access.log" + error_log="$logdir/error.log" + + if [ ! -e "$access_log" ]; then + touch "$access_log" + chmod 640 "$access_log" + chown www-data:adm "$access_log" + fi + + if [ ! -e "$error_log" ]; then + touch "$error_log" + chmod 640 "$error_log" + chown www-data:adm "$error_log" + fi + fi + + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/config/dpkg/timesketch-server.timesketch.default b/config/dpkg/timesketch-server.timesketch.default new file mode 100644 index 0000000000..4b040e223a --- /dev/null +++ b/config/dpkg/timesketch-server.timesketch.default @@ -0,0 +1,201 @@ +# Timesketch configuration +# +# The default location for this configuration file is in /etc/timesketch/timesketch.conf +# If you put it somewhere else you can pass the path to tsctl +# Example: +# +# $ tsctl -c /path/to/this/timesketch.conf runserver + +# Show debug information. +# Note: It is a security risk to have this enabled in production. +DEBUG = False + +# Key for signing cookies and for CSRF protection. +# +# This should be a unique random string. Don't share this with anyone. +# To generate a key, you can for example use openssl: +# $ openssl rand -base64 32 +SECRET_KEY = '' + +# Setup the database. +# +# For more options, see the official documentation: +# https://pythonhosted.org/Flask-SQLAlchemy/config.html +# By default sqlite is used. +# +# NOTE: SQLite should only be used in development. Use PostgreSQL or MySQL in +# production instead. +SQLALCHEMY_DATABASE_URI = 'postgresql://:@localhost/timesketch' + +# Configure where your Elasticsearch server is located. +# +# Make sure that the Elasticsearch server is properly secured and not accessible +# from the internet. See the following link for more information: +# http://www.elasticsearch.org/blog/scripting-security/ +ELASTIC_HOST = '127.0.0.1' +ELASTIC_PORT = 9200 + +#------------------------------------------------------------------------------- +# Single Sign On (SSO) configuration. + +# Your web server can handle authentication for you by setting a environment +# variable when the user is successfully authenticated. The standard environment +# variable is REMOTE_USER and this is the default, but if your SSO system uses +# another name you can configure that here. + +SSO_ENABLED = False +SSO_USER_ENV_VARIABLE = 'REMOTE_USER' + +# Some SSO systems provides group information as environment variable. +# Timesketch can automatically create groups and add users as members. +# To enable this feature just provide the environment variable used in the SSO +# system of use. +SSO_GROUP_ENV_VARIABLE = None + +# Different systems use different separators in the string returned in the +# environment variable. +SSO_GROUP_SEPARATOR = ';' + +# Some SSO systems uses a special prefix for the group name to indicate that +# the user is not a member of that group. Set this if that is the case, i.e. +# '-'. +SSO_GROUP_NOT_MEMBER_SIGN = None + +#------------------------------------------------------------------------------- +# Google Cloud Identity-Aware Proxy (Cloud IAP) authentication configuration. + +# Cloud IAP controls access to your Timesketch server running on Google Cloud +# Platform. Cloud IAP works by verifying a user’s identity and determining if +# that user should be allowed to access the server. +# +# For this feature you will need to configure your Cloud IAP and HTTPS load- +# balancer. Follow the official documentation to get everything ready: +# https://cloud.google.com/iap/docs/enabling-compute-howto + +# Enable Cloud IAP authentication support. +GOOGLE_IAP_ENABLED = False + +# This information is available via the Google Cloud console: +# https://cloud.google.com/iap/docs/signed-headers-howto +GOOGLE_IAP_PROJECT_NUMBER = '' +GOOGLE_IAP_BACKEND_ID = '' + +# DON'T EDIT: Google IAP expected audience is based on Cloud project number and +# backend ID. +GOOGLE_IAP_AUDIENCE = '/projects/{}/global/backendServices/{}'.format( + GOOGLE_IAP_PROJECT_NUMBER, + GOOGLE_IAP_BACKEND_ID +) + +GOOGLE_IAP_ALGORITHM = 'ES256' +GOOGLE_IAP_ISSUER = 'https://cloud.google.com/iap' +GOOGLE_IAP_PUBLIC_KEY_URL = 'https://www.gstatic.com/iap/verify/public_key' + +#------------------------------------------------------------------------------- +# Google Cloud OpenID Connect (OIDC) authentication configuration. + +# Cloud OIDC controls access to your Timesketch server running on Google Cloud +# Platform. Cloud OIDC works by verifying a user’s identity and determining if +# that user should be allowed to access the server. + +# Enable Cloud OIDC authentication support. +GOOGLE_OIDC_ENABLED = False + +GOOGLE_OIDC_CLIENT_ID = None +GOOGLE_OIDC_CLIENT_SECRET = None + +# Limit access to a specific Google GSuite domain. +GOOGLE_OIDC_HOSTED_DOMAIN = None + +# Additional Google GSuite domains allowed API access. +GOOGLE_OIDC_API_ALLOWED_DOMAINS = [] + +# If populated only these users (email addresses) will be able to login to +# this server. This can be used when access should be limited to a specific +# set of users. +GOOGLE_OIDC_ALLOWED_USERS = [] + +#------------------------------------------------------------------------------- +# Upload and processing of Plaso storage files. + +# To enable this feature you need to configure an upload directory and +# how to reach the Redis database used by the distributed task queue. +UPLOAD_ENABLED = False + +# Folder for temporarily storage of Plaso dump before being processed and +# inserted into the datastore. +UPLOAD_FOLDER = '/tmp' + +# Celery broker configuration. You need to change ip/port to where your Redis +# server is running. +CELERY_BROKER_URL = 'redis://127.0.0.1:6379' +CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379' + +# Path to plaso data directory. +# If not set, defaults to system prefix + share/plaso +#PLASO_DATA_LOCATION = '/path/to/dir/with/plaso/data/files' + +#------------------------------------------------------------------------------- +# Analyzers + +# Which analyzers to run automatically when a timeline is imported or added to +# a sketch. +AUTO_INDEX_ANALYZERS = [] +AUTO_SKETCH_ANALYZERS = [] + +# Analyzers specific configuration. + +# What data_types to calculate a similarity score for. +SIMILARITY_DATA_TYPES = [] + +# Add all domains that are relevant to your enterprise here. +# All domains in this list are added to the list of watched +# domains and compared to other domains in the timeline to +# attempt to spot "phishy" domains. +DOMAIN_ANALYZER_WATCHED_DOMAINS = [] + +# Defines how deep into the most frequently visited top +# level domains the analyzer should include in its watch list. +DOMAIN_ANALYZER_WATCHED_DOMAINS_THRESHOLD = 10 + +# The minimum Jaccard distance for a domain to be considered +# similar to the domains in the watch list. The lower this number +# is the more domains will be included in the "phishy" domain +# category. +DOMAIN_ANALYZER_WATCHED_DOMAINS_SCORE_THRESHOLD = 0.75 + +# A list of domains that are frequent source of false positives +# in the "phishy" domain comparison, mostly CDNs and similar. +DOMAIN_ANALYZER_EXCLUDE_DOMAINS = ['ytimg.com', 'gstatic.com', 'yimg.com', 'akamaized.net', 'akamaihd.net', 's-microsoft.com', 'images-amazon.com', 'ssl-images-amazon.com', 'wikimedia.org', 'redditmedia.com', 'googleusercontent.com', 'googleapis.com', 'wikipedia.org', 'github.io', 'github.com'] + + +# Threatintel analyzer-specific configuration +# URI root to Yeti's API, e.g. 'https://localhost:8080/api' +YETI_API_ROOT = '' + +# API key to authenticate requests +YETI_API_KEY = '' + +# Labels to narrow down indicator selection +YETI_INDICATOR_LABELS = ['domain'] + +#------------------------------------------------------------------------------- +# Enable experimental UI features. + +ENABLE_EXPERIMENTAL_UI = False + +#------------------------------------------------------------------------------- +# Email notifications. + +ENABLE_EMAIL_NOTIFICATIONS = False +EMAIL_DOMAIN = 'localhost' +EMAIL_FROM_USER = 'nobody' +EMAIL_SMTP_SERVER = 'localhost' + +# Only send emails to these users. +EMAIL_RECIPIENTS = [] + +# Configuration to construct URLs for resources. +EXTERNAL_HOST_URL = 'https://localhost' + +#------------------------------------------------------------------------------- diff --git a/config/dpkg/timesketch-server.timesketch.service b/config/dpkg/timesketch-server.timesketch.service new file mode 100644 index 0000000000..f87d297417 --- /dev/null +++ b/config/dpkg/timesketch-server.timesketch.service @@ -0,0 +1,17 @@ +[Unit] +Description=Timesketch server +Requires=timesketch.socket +After=network.target + +[Service] +PIDFile=/run/timesketch/pid +User=www-data +Group=www-data +RuntimeDirectory=timesketch +ExecStart=/usr/bin/env gunicorn3 --pid /run/timesketch/timesketch.pid --timeout 120 --workers 1 --bind unix:/run/timesketch/socket --access-logfile /var/log/timesketch/access.log --error-logfile /var/log/timesketch/error.log --log-level INFO timesketch.wsgi +ExecReload=/bin/kill -s HUP \$MAINPID +ExecStop=/bin/kill -s TERM \$MAINPID +PrivateTmp=false + +[Install] +WantedBy=multi-user.target diff --git a/config/dpkg/timesketch-server.timesketch.socket b/config/dpkg/timesketch-server.timesketch.socket new file mode 100644 index 0000000000..2f92293f6b --- /dev/null +++ b/config/dpkg/timesketch-server.timesketch.socket @@ -0,0 +1,8 @@ +[Unit] +Description=Timesketch socket + +[Socket] +ListenStream=/run/timesketch/socket + +[Install] +WantedBy=sockets.target diff --git a/contrib/deploy_timesketch.ps1 b/contrib/deploy_timesketch.ps1 index fa908fa818..1e69e2f79f 100644 --- a/contrib/deploy_timesketch.ps1 +++ b/contrib/deploy_timesketch.ps1 @@ -1,6 +1,6 @@ # Requires powershell 6.0 or newer - just because the out-file does not support encoding of UTF8NoBom on older versions. # This is a copy from the official Bash script of Timesketch. https://timesketch.org/ -# https://raw.githubusercontent.com/hnhdev/timesketch/main/contrib/deploy_timesketch.sh +# https://raw.githubusercontent.com/google/timesketch/master/contrib/deploy_timesketch.sh # Some of the functionality might be still missing that is present on the bash script. # Check for the existing timesketch path @@ -66,7 +66,7 @@ $OPENSEARCH_PORT="9200" $OPENSEARCH_MEM_USE_GB=(Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb / 2 $REDIS_ADDRESS="redis" $REDIS_PORT="6379" -$GITHUB_BASE_URL="https://raw.githubusercontent.com/hnhdev/timesketch/main" +$GITHUB_BASE_URL="https://raw.githubusercontent.com/google/timesketch/master" Write-Host "OK" Write-Host "Setting OpenSearch memory allocation to $OPENSEARCH_MEM_USE_GB GB" @@ -127,4 +127,4 @@ Write-Host "3. docker compose exec timesketch-web tsctl create-user " Write-Host "--" Write-Host "WARNING: The server is running without encryption." Write-Host "Follow the instructions to enable SSL to secure the communications:" -Write-Host "https://github.com/hnhdev/timesketch/blob/main/docs/Installation.md" +Write-Host "https://github.com/google/timesketch/blob/master/docs/Installation.md" diff --git a/contrib/deploy_timesketch.sh b/contrib/deploy_timesketch.sh index 80c9cd6e34..0472b4cc80 100755 --- a/contrib/deploy_timesketch.sh +++ b/contrib/deploy_timesketch.sh @@ -81,7 +81,7 @@ OPENSEARCH_PORT=9200 OPENSEARCH_MEM_USE_GB=$(cat /proc/meminfo | grep MemTotal | awk '{printf "%.0f", ($2 / (1024 * 1024) / 2)}') REDIS_ADDRESS="redis" REDIS_PORT=6379 -GITHUB_BASE_URL="https://raw.githubusercontent.com/hnhdev/timesketch/main" +GITHUB_BASE_URL="https://raw.githubusercontent.com/google/timesketch/master" echo "OK" echo "* Setting OpenSearch memory allocation to ${OPENSEARCH_MEM_USE_GB}GB" @@ -132,7 +132,7 @@ echo "OK" echo "* Installation done." if [ -z $START_CONTAINER ]; then - read -p "Would you like to start the containers? [Y/n] (default:no)" START_CONTAINER + read -p "Would you like to start the containers? [y/N]" START_CONTAINER fi if [ "$START_CONTAINER" != "${START_CONTAINER#[Yy]}" ] ;then # this grammar (the #[] operator) means that the variable $start_cnt where any Y or y in 1st position will be dropped if they exist. @@ -150,7 +150,7 @@ else echo echo "WARNING: The server is running without encryption." echo "Follow the instructions to enable SSL to secure the communications:" - echo "https://github.com/google/timesketch/blob/main/docs/Installation.md" + echo "https://github.com/google/timesketch/blob/master/docs/Installation.md" echo echo exit diff --git a/contrib/gcs_importer.py b/contrib/gcs_importer.py index 09dad97cfc..9198daab31 100644 --- a/contrib/gcs_importer.py +++ b/contrib/gcs_importer.py @@ -13,26 +13,29 @@ # limitations under the License. """Google Cloud Storage importer.""" # Unmaintained contrib. Skip linting this file. - +# pylint: skip-file import argparse -import json -import logging +import time import os import sys -import time import uuid +import json +import logging from werkzeug.exceptions import Forbidden from timesketch.app import create_app from timesketch.lib import tasks from timesketch.models import db_session -from timesketch.models.sketch import SearchIndex, Sketch, Timeline +from timesketch.models.sketch import SearchIndex +from timesketch.models.sketch import Sketch +from timesketch.models.sketch import Timeline from timesketch.models.user import User try: - from google.cloud import pubsub_v1, storage + from google.cloud import pubsub_v1 + from google.cloud import storage except ImportError: sys.exit("ERROR: You are missing Google Cloud libraries") diff --git a/contrib/nginx.conf b/contrib/nginx.conf index e879cf9c91..268c929331 100644 --- a/contrib/nginx.conf +++ b/contrib/nginx.conf @@ -8,6 +8,20 @@ http { listen [::]:80; client_max_body_size 0m; location / { + # Unauthenticated ReDoS prevention + set $redos_check ""; + if ($request_uri ~* "(/login)"){ + set $redos_check U; + } + if ($request_method = POST){ + set $redos_check "${redos_check}M"; + } + if ($http_content_type != "application/x-www-form-urlencoded"){ + set $redos_check "${redos_check}CT"; + } + if ($redos_check = UMCT){ + return 403; + } proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; @@ -18,6 +32,20 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } location /legacy/ { + # Unauthenticated ReDoS prevention + set $redos_check ""; + if ($request_uri ~* "(/login)"){ + set $redos_check U; + } + if ($request_method = POST){ + set $redos_check "${redos_check}M"; + } + if ($http_content_type != "application/x-www-form-urlencoded"){ + set $redos_check "${redos_check}CT"; + } + if ($redos_check = UMCT){ + return 403; + } proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; diff --git a/data/gunicorn_config.py b/data/gunicorn_config.py index 4f923d624e..588288315b 100644 --- a/data/gunicorn_config.py +++ b/data/gunicorn_config.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. """Gunicorn configuration for metrics endpoint.""" -import glob import os +import glob import pathlib from prometheus_flask_exporter.multiprocess import GunicornPrometheusMetrics @@ -25,8 +25,7 @@ # Reference: https://github.com/rycus86/prometheus_flask_exporter#wsgi - - +# pylint: disable=unused-argument def when_ready(server): """Start metrics server when Timesketch app is ready.""" # Exit early if we don't have the necessary environment set up. diff --git a/data/timesketch.conf b/data/timesketch.conf index 0d9a47164c..e57fa5846f 100644 --- a/data/timesketch.conf +++ b/data/timesketch.conf @@ -34,6 +34,8 @@ OPENSEARCH_SSL = False OPENSEARCH_VERIFY_CERTS = True OPENSEARCH_TIMEOUT = 10 OPENSEARCH_FLUSH_INTERVAL = 5000 +OPENSEARCH_INDEX_WAIT_TIMEOUT = 10 +OPENSEARCH_MINIMUM_HEALTH = 'yellow' # Be careful when increasing the upper limit since this will impact your # OpenSearch clusters performance and storage requirements! OPENSEARCH_MAPPING_BUFFER = 0.1 @@ -379,16 +381,16 @@ LLM_PROVIDER_CONFIGS = { 'project_id': '', }, }, - 'llm_summarization': { + 'llm_summarize': { 'aistudio': { 'model': 'gemini-2.0-flash-exp', 'project_id': '', }, }, 'default': { - 'aistudio': { - 'api_key': '', - 'model': 'gemini-2.0-flash-exp', + 'ollama': { + 'server_url': '', + 'model': '', }, } } @@ -401,3 +403,10 @@ EXAMPLES_NL2Q = '/etc/timesketch/nl2q/examples_nl2q' # LLM event summarization configuration PROMPT_LLM_SUMMARIZATION = '/etc/timesketch/llm_summarize/prompt.txt' + +#------------------------------------------------------------------------------- +# Timesketch UI Option + +# Get the search processing timelines setting. +# If set to True, the search processing timelines options will be displayed in the UI. +SEARCH_PROCESSING_TIMELINES = False diff --git a/dependencies.ini b/dependencies.ini new file mode 100644 index 0000000000..2ed6f4cd3d --- /dev/null +++ b/dependencies.ini @@ -0,0 +1,349 @@ +[alembic] +dpkg_name: python3-alembic +minimum_version: 1.3.2 +rpm_name: python3-alembic + +[altair] +dpkg_name: python3-altair +minimum_version: 4.1.0 +rpm_name: python3-altair + +[amqp] +dpkg_name: python3-amqp +minimum_version: 2.2.1 +rpm_name: python3-amqp + +[aniso8601] +dpkg_name: python3-aniso8601 +minimum_version: 1.2.1 +rpm_name: python3-aniso8601 + +[asn1crypto] +dpkg_name: python3-asn1crypto +minimum_version: 0.24.0 +rpm_name: python3-asn1crypto + +[attrs] +dpkg_name: python3-attr +minimum_version: 19.1.0 +rpm_name: python3-attrs + +[bcrypt] +dpkg_name: python3-bcrypt +minimum_version: 3.1.3 +rpm_name: python3-bcrypt + +[billiard] +dpkg_name: python3-billiard +minimum_version: 3.5.0.3 +rpm_name: python3-billiard + +[blinker] +dpkg_name: python3-blinker +minimum_version: 1.4 +rpm_name: python3-blinker + +[bs4] +dpkg_name: python3-bs4 +minimum_version: 4.6.3 +pypi_name: beautifulsoup4 +rpm_name: python3-beautifulsoup4 +version_property: __version__ + +[celery] +dpkg_name: python3-celery +minimum_version: 4.4.0 +rpm_name: python3-celery + +[certifi] +dpkg_name: python3-certifi +minimum_version: 2017.7.27.1 +rpm_name: python3-certifi + +[cffi] +dpkg_name: python3-cffi +minimum_version: 1.10.0 +rpm_name: python3-cffi + +[chardet] +dpkg_name: python3-chardet +minimum_version: 3.0.4 +rpm_name: python3-chardet + +[ciso8601] +dpkg_name: python3-ciso8601 +minimum_version: 2.1.1 +rpm_name: python3-ciso8601 + +[Click] +dpkg_name: python3-click +minimum_version: 6.7 +rpm_name: python3-click + +[cryptography] +dpkg_name: python3-cryptography +minimum_version: 2.4.1 +rpm_name: python3-cryptography + +[datasketch] +dpkg_name: python3-datasketch +minimum_version: 1.5.0 +rpm_name: python3-datasketch + +[dateutil] +dpkg_name: python3-dateutil +minimum_version: 2.6.1 +pypi_name: python3-dateutil +rpm_name: python3-dateutil +version_property: __version__ + +[opensearch] +dpkg_name: python3-opensearch +l2tbinaries_name: opensearch-py +minimum_version: 1.0.0 +pypi_name: opensearchpy +rpm_name: python3-opensearch +version_property: __versionstr__ + +[entrypoints] +dpkg_name: python3-entrypoints +minimum_version: 0.2.3 +rpm_name: python3-entrypoints + +[Flask] +dpkg_name: python3-flask +minimum_version: 1.1.1 +rpm_name: python3-flask + +[Flask-Bcrypt] +dpkg_name: python3-flask-bcrypt +minimum_version: 0.7.1 +rpm_name: python3-flask-bcrypt + +[Flask-Login] +dpkg_name: python3-flask-login +minimum_version: 0.4.1 +rpm_name: python3-flask-login + +[Flask-Migrate] +dpkg_name: python3-flask-migrate +minimum_version: 2.5.2 +rpm_name: python3-flask-migrate + +[Flask-RESTful] +dpkg_name: python3-flask-restful +minimum_version: 0.3.7 +rpm_name: python3-flask-restful + +[Flask-Script] +dpkg_name: python3-flask-script +minimum_version: 2.0.6 +rpm_name: python3-flask-script + +[Flask-SQLAlchemy] +dpkg_name: python3-flask-sqlalchemy +minimum_version: 2.4.1 +rpm_name: python3-flask-sqlalchemy + +[Flask-WTF] +dpkg_name: python3-flaskext.wtf +minimum_version: 0.14.2 +rpm_name: python3-flask-wtf + +[google-auth] +dpkg_name: python3-google-auth +minimum_version: 2.32.0 +rpm_name: python3-google-auth + +[google-auth-oauthlib] +dpkg_name: python3-google-auth-oauthlib +minimum_version: 0.4.1 +rpm_name: python3-google-auth-oauthlib + +[gunicorn] +dpkg_name: python3-gunicorn +minimum_version: 19.7.1 +rpm_name: python3-gunicorn + +[idna] +dpkg_name: python3-idna +minimum_version: 2.6 +rpm_name: python3-idna + +[itsdangerous] +dpkg_name: python3-itsdangerous +minimum_version: 0.24 +rpm_name: python3-itsdangerous + +[Jinja2] +dpkg_name: python3-jinja2 +minimum_version: 2.10 +rpm_name: python3-jinja2 + +[jsonschema] +dpkg_name: python3-jsonschema +minimum_version: 2.6.0 +rpm_name: python3-jsonschema + +[kombu] +dpkg_name: python3-kombu +minimum_version: 4.1.0 +rpm_name: python3-kombu + +[Mako] +dpkg_name: python3-mako +minimum_version: 1.0.7 +rpm_name: python3-mako + +[Markdown] +dpkg_name: python3-markdown +minimum_version: 3.2.2 +rpm_name: python3-markdown + +[MarkupSafe] +dpkg_name: python3-markupsafe +minimum_version: 1.0 +rpm_name: python3-markupsafe + +[networkx] +dpkg_name: python3-networkx +minimum_version: 2.4 +rpm_name: python3-networkx + +[numpy] +dpkg_name: python3-numpy +minimum_version: 1.17.5 +rpm_name: python3-numpy + +[oauthlib] +dpkg_name: python3-oauthlib +minimum_version: 3.1.0 +rpm_name: python3-oauthlib + +[pandas] +dpkg_name: python3-pandas +minimum_version: 0.25.3 +rpm_name: python3-pandas + +[parameterized] +dpkg_name: python3-parameterized +minimum_version: 0.6.1 +rpm_name: python3-parameterized + +[prometheus-client] +dpkg_name: python3-prometheus-client +minimum_version: 0.9.0 +rpm_name: python3-prometheus_client + +[prometheus-flask-exporter] +dpkg_name: python3-prometheus-flask-exporter +minimum_version: 0.18.1 +rpm_name: python3-prometheus-flask-exporter + +[pycparser] +dpkg_name: python3-pycparser +minimum_version: 2.18 +rpm_name: python3-pycparser + +[PyJWT] +dpkg_name: python3-jwt +minimum_version: 1.7.1 +rpm_name: python3-jwt + +[pyrsistent] +dpkg_name: python3-pyrsistent +minimum_version: 0.14.11 +rpm_name: python3-pyrsistent + +[python-editor] +dpkg_name: python3-editor +minimum_version: 1.0.3 +rpm_name: python3-editor + +[pytz] +dpkg_name: python3-tz +rpm_name: python3-pytz +version_property: __version__ + +[redis] +dpkg_name: python3-redis +minimum_version: 3.3.11 +rpm_name: python3-redis + +[requests] +dpkg_name: python3-requests +minimum_version: 2.23.0 +rpm_name: python3-requests + +[requests-oauthlib] +dpkg_name: python3-requests-oauthlib +minimum_version: 1.3.0 +rpm_name: python3-requests-oauthlib + +[sigmatools] +dpkg_name: python3-sigmatools +minimum_version: 0.19.1 +rpm_name: python3-sigmatools + +[six] +dpkg_name: python3-six +minimum_version: 1.10.0 +rpm_name: python3-six + +[SQLAlchemy] +dpkg_name: python3-sqlalchemy +minimum_version: 1.3.12 +rpm_name: python3-sqlalchemy + +[tabulate] +dpkg_name: python3-tabulate +minimum_version: 0.8.6 +rpm_name: python3-tabulate + +[toolz] +dpkg_name: python3-toolz +minimum_version: 0.8.2 +rpm_name: python3-toolz + +[urllib3] +dpkg_name: python3-urllib3 +minimum_version: 1.24.1 +rpm_name: python3-urllib3 + +[vine] +dpkg_name: python3-vine +minimum_version: 1.1.4 +rpm_name: python3-vine + +[werkzeug] +dpkg_name: python3-werkzeug +minimum_version: 0.14.1 +rpm_name: python3-werkzeug + +[WTForms] +dpkg_name: python3-wtforms +minimum_version: 2.2.1 +rpm_name: python3-wtforms + +[xlrd] +dpkg_name: python3-xlrd +minimum_version: 1.2.0 +rpm_name: python3-xlrd + +[xmltodict] +dpkg_name: python3-xmltodict +minimum_version: 0.12.0 +rpm_name: python3-xmltodict + +[yaml] +dpkg_name: python3-yaml +l2tbinaries_name: PyYAML +minimum_version: 3.10 +pypi_name: PyYAML +rpm_name: PyYAML +version_property: __version__ + +[zipp] +dpkg_name: python3-zipp +minimum_version: 0.5 +rpm_name: python3-zipp diff --git a/docker/dev/README.md b/docker/dev/README.md index 39e88ad9dc..7231b53612 100644 --- a/docker/dev/README.md +++ b/docker/dev/README.md @@ -1,8 +1,13 @@ -# Docker for development +## Docker for development -## Start the deployment +You can run Timesketch on Docker in development mode. +Make sure to follow the docker [post-install](https://docs.docker.com/engine/install/linux-postinstall/) to run without superuser. If not then make sure to execute all `docker` commands here as *superuser*. -``` +NOTE: It is not recommended to try to run on a system with less than 8 GB of RAM. + +### Start a developer version of docker containers in this directory + +```bash docker compose up -d ``` @@ -10,39 +15,61 @@ The provided container definition runs Timesketch in development mode as a volum If you see the following message you can continue -``` +```text Timesketch development server is ready! ``` +### Find out container ID for the timesketch container -### Start a celery container shell +```bash +CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" +``` +In the output look for CONTAINER ID for the timesketch container + +To write the ID to a variable, use: + +```bash +export CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" ``` -docker exec -it timesketch celery -A timesketch.lib.tasks worker --loglevel info + +and test with + +```bash +echo $CONTAINER_ID ``` -### Start development webserver (and metrics server) +### Start a celery container shell +```bash +docker exec -it $CONTAINER_ID celery -A timesketch.lib.tasks worker --loglevel info ``` -docker exec -it timesketch gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 600 -c /usr/local/src/timesketch/data/gunicorn_config.py timesketch.wsgi:application + +### Start development webserver (and metrics server) + +```bash +docker exec -it $CONTAINER_ID gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 600 -c /usr/local/src/timesketch/data/gunicorn_config.py timesketch.wsgi:application ``` -You now can access your development version at +You now can access your development version at http://127.0.0.1:5000/ Log in with user: dev password: dev +You can also access a metrics dashboard at http://127.0.0.1:3000/ + ### Non-interactive Running the following as a script after `docker compose up -d` will bring up the development environment in the background for you. -``` -docker exec timesketch celery -A timesketch.lib.tasks worker --loglevel info -docker exec timesketch gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 120 timesketch.wsgi:application +```bash +export CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" +docker exec $CONTAINER_ID celery -A timesketch.lib.tasks worker --loglevel info +docker exec $CONTAINER_ID gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 120 timesketch.wsgi:application ``` ### Run tests -``` -docker exec -w /usr/local/src/timesketch -it timesketch python3 run_tests.py --coverage +```bash +docker exec -w /usr/local/src/timesketch -it $CONTAINER_ID python3 run_tests.py --coverage ``` That will run all tests in your docker container. It is recommended to run all tests at least before creating a pull request. @@ -50,13 +77,13 @@ That will run all tests in your docker container. It is recommended to run all t ### Jupyter Notebook To access a Jupyter notebook that has access to the Timesketch development -environment start a browser and visit . The password to +environment start a browser and visit http://localhost:8844/ . The password to gain access is "timesketch". -By default the /tmp directory is mapped as the data directory to store all +By default, the /tmp directory is mapped as the data directory to store all notebooks. To change that, modify the line: -``` +```yaml - /tmp/:/usr/local/src/picadata/ ``` @@ -64,24 +91,31 @@ in the docker-compose.yml file to point to a directory of your choosing. In order for the jupyter notebook to be able to make use of that folder it has to have read and write permission for the user with the UID 1000. -By default the latest checked in code of the timesketch API client and +By default, the latest checked in code of the timesketch API client and timesketch import client are installed. In order to install a new version, if you are modifying the clients you'll need to make sure that the timesketch -source code on your machine is readable by the user with the UID 1000 and gid -1000. If that is done, then the code is mapped into the - /usr/local/src/timesketch folder on the docker container. +source code on your machine is readable by the user with the UID 1000 and +gid 1000. +If that is done, then the code is mapped into the `/usr/local/src/timesketch` +folder on the docker container. New versions of timesketch api client can then be installed using: -```python +```bash !pip install -e /usr/local/src/timesketch/api_client/python/ ``` And the importer client: -```python +```bash !pip install -e /usr/local/src/timesketch/importer_client/python ``` Just remember to restart the kernel runtime in order for the changes to be active. + +To update the docker image run: + +```bash +$ sudo docker image pull us-docker.pkg.dev/osdfir-registry/timesketch/notebook:latest +``` diff --git a/docker/dev/build/10-widgets.py b/docker/dev/build/10-widgets.py index 38ec24d1db..baf47efd43 100644 --- a/docker/dev/build/10-widgets.py +++ b/docker/dev/build/10-widgets.py @@ -1,46 +1,108 @@ +# Copyright 2020 Google Inc. All rights reserved. +# +# 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. +"""Few functions that take advantage of ipywidgets for jupyter. + +These are temporary functions until they have been generalized +and implemented in picatrix. +""" + +# pylint: disable=undefined-variable +# pylint: disable=import-error from picatrix.lib import utils + +import ipydatetime import ipywidgets as widgets -from IPython.display import Markdown -from timesketch_api_client import search, config -from picatrix.lib import state as state_lib +import pytz -import altair as alt -import numpy as np -import pandas as pd +from IPython.display import Markdown -state = state_lib.state() +from timesketch_api_client import search -def generate_connect_button(click_function=None): +# TODO: Generalize and move to picatrix. +def generate_connect_button(click_function = None): """Creates a button and an int form to connect to timesketch.""" - button = widgets.Button(description="Connect to sketch") + button = widgets.Button(description='Connect to sketch') output = widgets.Output() - sketch_field = widgets.IntText(value=1, description="Sketch ID:", disabled=False) + sketch_field = widgets.IntText( + value=1, + description='Sketch ID:', + disabled=False + ) - display(Markdown("## Connect to a sketch")) - display(Markdown("Select a sketch to connect to.")) + display(Markdown('## Connect to a sketch')) + display(Markdown('Select a sketch to connect to.')) display(sketch_field, button, output) def _click_function(_): with output: - id = int(sketch_field.value) - ts_client = config.get_client() - sketch = ts_client.get_sketch(id) + timesketch_set_active_sketch_func(str(sketch_field.value)) + sketch = timesketch_get_sketch_func() try: - display( - Markdown(f"Connected to sketch: {sketch.id}: **{sketch.name}**") - ) - valid = widgets.Valid(value=True, description="Connected") + display(Markdown( + f'Connected to sketch: {sketch.id}: **{sketch.name}**')) + valid = widgets.Valid(value=True, description='Connected') display(valid) - utils.ipython_bind_global("sketch", sketch) - display(Markdown("Sketch object saved to **sketch**")) + utils.ipython_bind_global('sketch', sketch) + display(Markdown('Sketch object saved to **sketch**')) except KeyError: - display(Markdown("**Unable to connect to sketch.**")) - invalid = widgets.Valid(value=False, description="Connected") + display(Markdown('**Unable to connect to sketch.**')) + invalid = widgets.Valid(value=False, description='Connected') display(invalid) if click_function: button.on_click(click_function) else: button.on_click(_click_function) + + +def generate_query_button(): + """Generates a button and form to query Timesketch data.""" + button = widgets.Button(description='Query Timesketch') + query_string_form = widgets.Text( + value='*', + placeholder='Type something', + description='Query String:', + disabled=False + ) + + start_time_form = ipydatetime.DatetimePicker(tzinfo=pytz.utc) + end_time_form = ipydatetime.DatetimePicker(tzinfo=pytz.utc) + + display(Markdown('## Query A Sketch')) + display(query_string_form) + display(Markdown('Start time: '), start_time_form) + display(Markdown('End time: '), end_time_form) + display(button) + + def _click_function(_): + sketch = timesketch_get_sketch_func() + search_obj = search.Search(sketch) + if start_time_form.value and end_time_form.value: + date_chip = search.DateRangeChip() + date_chip.start_time = start_time_form.value.strftime( + '%Y-%m-%dT%H:%M:%S') + date_chip.end_time = end_time_form.value.strftime( + '%Y-%m-%dT%H:%M:%S') + search_obj.add_chip(date_chip) + search_obj.query_string = query_string_form.value + display(Markdown( + f'Query **executed** - returned: {len(search_obj.table)} ' + 'records')) + utils.ipython_bind_global('search_obj', search_obj) + display(Markdown( + 'Results are stored in the **search_obj**')) + + button.on_click(_click_function) diff --git a/docker/dev/build/Dockerfile-notebook b/docker/dev/build/Dockerfile-notebook index 0fe13333c8..645923d167 100644 --- a/docker/dev/build/Dockerfile-notebook +++ b/docker/dev/build/Dockerfile-notebook @@ -1,36 +1,35 @@ -FROM quay.io/jupyter/minimal-notebook:python-3.11 - -USER root - -RUN apt update && \ - apt install -y gcc python3-dev - -USER jovyan - -COPY --chown=1000:100 ./jupyter_server_config.py $HOME/.jupyter/jupyter_server_config.py -COPY --chown=1000:100 ./overrides.json /opt/conda/share/jupyter/lab/settings/overrides.json -COPY --chown=1000:100 --from=timesketch_api_client python $HOME/timesketch_api_client - -RUN pip install jupyter_scheduler jupyterlab-vim jupyter-collaboration jupyterlab-fonts && \ - pip install jupyterlab-lsp "python-lsp-server[all]" && \ - pip install picatrix ipywidgets && \ - pip install pandas[performance,plot-output-formatting] mitreattack-python && \ - pip install -e $HOME/timesketch_api_client - -USER root - -RUN apt remove -y gcc python3-dev - -USER jovyan - -RUN mkdir -p /opt/conda/share/jupyter/nbextensions/snippets/ - -COPY --chown=1000:100 timesketchrc $HOME/.timesketchrc -COPY --chown=1000:100 timesketch_token $HOME/.timesketch.token - -RUN ipython3 profile create - -COPY --chown=1000:100 10-widgets.py $HOME/.ipython/profile_default/startup/10-widgets.py -COPY --chown=1000:100 Template.ipynb $HOME/work - -ENTRYPOINT ["jupyter-lab"] \ No newline at end of file +FROM us-docker.pkg.dev/osdfir-registry/picatrix/picatrix:latest + +USER picatrix + +ENV VIRTUAL_ENV=/home/picatrix/picenv +ENV PATH="$VIRTUAL_ENV/bin:$PATH" +ENV JUPYTER_PORT=8844 + +RUN mkdir -p /home/picatrix/.local/share/jupyter/nbextensions/snippets/ && \ + mkdir -p /home/picatrix/.jupyter/custom + +COPY --chown=1000:1000 docker/dev/build/timesketchrc /home/picatrix/.timesketchrc +COPY --chown=1000:1000 docker/dev/build/timesketch_token /home/picatrix/.timesketch.token +COPY --chown=1000:1000 . /home/picatrix/code +COPY --chown=1000:1000 docker/dev/build/snippets.json /home/picatrix/.local/share/jupyter/nbextensions/snippets/snippets.json +COPY --chown=1000:1000 docker/dev/build/10-widgets.py /home/picatrix/.ipython/profile_default/startup/10-widgets.py +COPY --chown=1000:1000 docker/dev/build/logo.png /home/picatrix/.jupyter/custom/logo.png +COPY --chown=1000:1000 docker/dev/build/custom.css /home/picatrix/.jupyter/custom/custom.css +COPY --chown=1000:1000 docker/dev/build/timesketch /home/picatrix/picenv/share/jupyter/nbextensions/timesketch + +RUN sed -i -e "s/c.NotebookApp.token = 'picatrix'/c.NotebookApp.token = 'timesketch'/g" /home/picatrix/.jupyter/jupyter_notebook_config.py && \ + sed -i -e "s/c.NotebookApp.port = 8899/c.NotebookApp.port = 8844/g" /home/picatrix/.jupyter/jupyter_notebook_config.py && \ + pip install -e /home/picatrix/code/api_client/python && \ + pip install -e /home/picatrix/code/importer_client/python/ && \ + jupyter nbextension enable snippets/main && \ + jupyter nbextension enable timesketch/main && \ + pip install ipydatetime && \ + jupyter nbextension install --user --py ipydatetime && \ + jupyter nbextension enable --user --py ipydatetime + +WORKDIR /usr/local/src/picadata/ +EXPOSE 8844 + +# Run jupyter. +ENTRYPOINT ["jupyter", "notebook"] diff --git a/docker/dev/build/custom.css b/docker/dev/build/custom.css new file mode 100644 index 0000000000..5b2a19ae6c --- /dev/null +++ b/docker/dev/build/custom.css @@ -0,0 +1,11 @@ +#ipython_notebook img{ + display:block; + background: url("logo.png") no-repeat; + background-size: contain; + width: 83px; + height: 35px; + padding-left: 90px; + padding-bottom: 50px; + -moz-box-sizing: border-box; + box-sizing: border-box; +} diff --git a/docker/dev/build/sigma_rules.txt b/docker/dev/build/sigma_rules.txt index 0e11e62b93..699bc0fff3 100644 --- a/docker/dev/build/sigma_rules.txt +++ b/docker/dev/build/sigma_rules.txt @@ -1,7 +1,6 @@ /usr/local/src/sigma/rules/application/rpc_firewall/rpc_firewall_sharphound_recon_sessions.yml -/usr/local/src/sigma/rules/application/spring/appframework_spring_exceptions.yml /usr/local/src/sigma/rules/application/sql/app_sqlinjection_errors.yml -/usr/local/src/sigma/rules/other/godmode_sigma_rule.yml +/usr/local/src/sigma/other/godmode_sigma_rule.yml /usr/local/src/sigma/rules/windows/powershell/powershell_script/posh_ps_icmp_exfiltration.yml /usr/local/src/sigma/rules/windows/powershell/powershell_script/posh_ps_invoke_obfuscation_clip.yml /usr/local/src/sigma/rules/windows/powershell/powershell_script/posh_ps_invoke_obfuscation_obfuscated_iex.yml @@ -20,13 +19,7 @@ /usr/local/src/sigma/rules/windows/powershell/powershell_script/posh_ps_malicious_keywords.yml /usr/local/src/sigma/rules/windows/powershell/powershell_script/posh_ps_susp_keywords.yml /usr/local/src/sigma/rules/windows/powershell/powershell_script/posh_ps_susp_ssl_keyword.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_disabled.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_alert_lsass_access.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_exclusions.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_psexec_wmi_asr.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_amsi_trigger.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_exploit_guard_tamper.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_tamper_protection_trigger.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_disabled.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_history_delete.yml -/usr/local/src/sigma/rules/windows/windefend/win_defender_threat.yml \ No newline at end of file +/usr/local/src/sigma/deprecated/windows/win_defender_disabled.yml +/usr/local/src/sigma/rules/windows/builtin/windefend/win_defender_tamper_protection_trigger.yml +/usr/local/src/sigma/rules/windows/builtin/windefend/win_defender_history_delete.yml +/usr/local/src/sigma/rules/windows/builtin/windefend/win_defender_threat.yml diff --git a/docker/dev/build/snippets.json b/docker/dev/build/snippets.json new file mode 100644 index 0000000000..8b95e175bf --- /dev/null +++ b/docker/dev/build/snippets.json @@ -0,0 +1,81 @@ +{ + "snippets": [ + { + "name": "Example initial import", + "code" : [ + "from timesketch_api_client import search", + "from picatrix.lib import state as state_lib", + "import altair as alt", + "import numpy as np", + "import pandas as pd", + "state = state_lib.state()" + ] + }, + { + "name": "Select a sketch using magics", + "code" : [ + "%timesketch_set_active_sketch 1" + ] + }, + { + "name" : "Select a sketch using a button and a form", + "code" : [ + "# Execute cell in order to generate button.", + "generate_connect_button()" + ] + }, + { + "name" : "Query a sketch using a button and a form", + "code" : [ + "# Execute cell in order to generate button.", + "generate_query_button()" + ] + }, + { + "name": "Search with date range filter", + "code" : [ + "sketch = %timesketch_get_sketch", + "search_obj = search.Search(sketch)", + "date_chip = search.DateRangeChip()", + "date_chip.start_time = '2020-12-24T18:00:00'", + "date_chip.end_time = '2020-12-31T23:59:59'", + "search_obj.add_chip(date_chip)", + "search_obj.query_string = '*'", + "df = search_obj.table" + ] + }, + { + "name": "Run an example aggregation.", + "code" : [ + "sketch = %timesketch_get_sketch", + "params = {", + " 'field': 'domain',", + " 'limit': 10,", + " 'supported_charts': 'hbarchart',", + " 'chart_title': 'Top 10 Domains'", + "}", + " ", + "agg = sketch.run_aggregator(", + " aggregator_name='field_bucket', aggregator_parameters=params)", + " ", + "# You can get the aggregation data as a chart or a dataframe", + "agg.chart", + " ", + "# Enable this to get the results as a table", + "# agg.table", + " ", + "# To save the aggregation you need to create a name and a title.", + "# agg.name = 'Top 10 Domains'", + "# agg.title = 'Top 10 Domains'", + "# agg.save()" + ] + }, + { + "name" : "Get Timesketch client object", + "code" : [ + "# Execute cell in order to get a Timesketch API client instance.", + "client = state.get_from_cache('timesketch_client')" + ] + }, + ] +} diff --git a/docker/dev/build/timesketch/README.md b/docker/dev/build/timesketch/README.md new file mode 100644 index 0000000000..69f3fa3c04 --- /dev/null +++ b/docker/dev/build/timesketch/README.md @@ -0,0 +1,7 @@ +timesketch +========= + +This extension adds few default cells to each new notebook created in this +Timesketch container. + +This is a simple extension with a simple purpose. diff --git a/docker/dev/build/timesketch/main.js b/docker/dev/build/timesketch/main.js new file mode 100644 index 0000000000..a72a44aac5 --- /dev/null +++ b/docker/dev/build/timesketch/main.js @@ -0,0 +1,46 @@ +// Code cell snippets + +define([ + 'base/js/namespace', +], function( + Jupyter, +) { + "use strict"; + + // will be called when the nbextension is loaded + function load_extension() { + var ncells = Jupyter.notebook.ncells(); + if (ncells > 1) { + return true; + } + + var new_cell = Jupyter.notebook.insert_cell_above('markdown', 0); + new_cell.set_text('# Timesketch Notebook\nThis is a base notebook for connecting to a dev instance of Timesketch.\n**Remember to rename the notebook**.'); + new_cell.render(); + new_cell.focus_cell(); + + var new_cell = Jupyter.notebook.insert_cell_below('markdown'); + new_cell.set_text('*If you want to query data you can use the snippets menu, or create a search obj, and to display a table use `display_table(search_obj.table)` or `display_table(data_frame)`*\n\nTo see a list of available helper functions run `%picatrixhelpers` in a cell, or to see a list of functions/magics use `%picatrixmagics`.'); + new_cell.render(); + + var select_cell = Jupyter.notebook.insert_cell_below('code'); + select_cell.set_text('generate_connect_button()'); + + var text_cell = Jupyter.notebook.insert_cell_below('markdown'); + text_cell.set_text('## Select a Sketch.\nNow it is time to select a sketch to use, first execute the cell and then change the ID of the sketch to the one you want, and press the button.'); + text_cell.render(); + + var import_cell = Jupyter.notebook.insert_cell_below('code'); + import_cell.set_text('from timesketch_api_client import search\nfrom picatrix.lib import state as state_lib\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\n\nstate = state_lib.state()'); + + var new_cell = Jupyter.notebook.insert_cell_below('markdown'); + new_cell.set_text('## Import\nTo start a notebook we import few base libraries.\nExecute the cell below by pressing the play button or using "shift + enter"'); + new_cell.render(); + import_cell.focus_cell(); + }; + + // return public methods + return { + load_ipython_extension : load_extension + }; +}); diff --git a/docker/dev/build/timesketch/timesketch.yaml b/docker/dev/build/timesketch/timesketch.yaml new file mode 100644 index 0000000000..619fd93499 --- /dev/null +++ b/docker/dev/build/timesketch/timesketch.yaml @@ -0,0 +1,6 @@ +Type: IPython Notebook Extension +Compatibility: 4.x, 5.x, 6.x +Name: Timesketch +Main: main.js +Link: README.md +Description: Add few default cells to a new notebook. diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index d4c2b27593..170ee4a464 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -1,14 +1,13 @@ version: "3" services: timesketch: - container_name: timesketch - build: - context: ../../ - dockerfile: ./docker/dev/build/Dockerfile + container_name: timesketch-dev + image: us-docker.pkg.dev/osdfir-registry/timesketch/dev:latest command: timesketch ports: - 127.0.0.1:5000:5000 - 127.0.0.1:5001:5001 + - 127.0.0.1:8080:8080 links: - opensearch - postgres @@ -34,18 +33,15 @@ services: opensearch: container_name: opensearch - image: opensearchproject/opensearch:2.19.0 + image: opensearchproject/opensearch:2.15.0 restart: always - ports: - - 127.0.0.1:9200:9200 environment: - discovery.type=single-node - bootstrap.memory_lock=true - network.host=0.0.0.0 - "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g" - "DISABLE_INSTALL_DEMO_CONFIG=true" - - "DISABLE_SECURITY_PLUGIN=true" - - _JAVA_OPTIONS=-XX:UseSVE=0 + - "DISABLE_SECURITY_PLUGIN=true" # TODO: Enable when we have migrated the python client to Opensearch as well. ulimits: memlock: @@ -70,15 +66,21 @@ services: notebook: container_name: notebook - build: - context: build/ - dockerfile: Dockerfile-notebook - additional_contexts: - - timesketch_api_client=../../api_client/ + image: us-docker.pkg.dev/osdfir-registry/timesketch/notebook:latest ports: - - 127.0.0.1:8844:8080 + - 127.0.0.1:8844:8844 restart: on-failure links: - opensearch volumes: - - ../../api_client/python:/home/jovyan/timesketch_api_client + - ../../:/usr/local/src/timesketch/:ro + - /tmp/:/usr/local/src/picadata/ + prometheus: + container_name: prometheus + image: prom/prometheus:v2.24.1 + volumes: + - ./prometheus:/etc/prometheus + ports: + - 127.0.0.1:9090:9090 + command: --config.file=/etc/prometheus/prometheus.yml + diff --git a/docker/dev/restart.sh b/docker/dev/restart.sh index c5c79f0be3..6e92f54948 100755 --- a/docker/dev/restart.sh +++ b/docker/dev/restart.sh @@ -1,4 +1,4 @@ #!/bin/bash -export CONTAINER_ID="$(docker container list -f name=timesketch -q)" +export CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" docker exec -d $CONTAINER_ID celery -A timesketch.lib.tasks worker --loglevel info docker exec -d $CONTAINER_ID gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 600 -c /usr/local/src/timesketch/data/gunicorn_config.py timesketch.wsgi:application diff --git a/docker/dev/start_frontend.sh b/docker/dev/start_frontend.sh index fab093c466..aac1d92c89 100755 --- a/docker/dev/start_frontend.sh +++ b/docker/dev/start_frontend.sh @@ -4,7 +4,7 @@ echo "[i] Script (NOT TESTED) to run the frontend in dev mode" echo "[i] Run this script in timesketch/docker/dev" echo "[i] Remember to run 'docker compose up -d' to start the containers" -CONTAINER_ID="$(docker container list -f name=timesketch -q)" +CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" docker exec -d $CONTAINER_ID celery -A timesketch.lib.tasks worker --loglevel info docker compose exec timesketch yarn install --cwd=/usr/local/src/timesketch/timesketch/frontend docker compose exec -d timesketch yarn run --cwd=/usr/local/src/timesketch/timesketch/frontend build --mode development --watch diff --git a/docker/e2e/Dockerfile b/docker/e2e/Dockerfile index 24b119c2b3..63677f8b9c 100644 --- a/docker/e2e/Dockerfile +++ b/docker/e2e/Dockerfile @@ -29,7 +29,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ADD . /tmp/timesketch RUN pip3 install -r /tmp/timesketch/requirements.txt RUN pip3 install /tmp/timesketch && pip3 install /tmp/timesketch/api_client/python && \ - pip3 install /tmp/timesketch/importer_client/python + pip3 install /tmp/timesketch/importer_client/python && \ + pip3 install /tmp/timesketch/cli_client/python # Copy Timesketch config files into /etc/timesketch RUN mkdir /etc/timesketch diff --git a/docker/e2e/docker-compose.yml b/docker/e2e/docker-compose.yml index b57d1a9dbb..edf04a082f 100644 --- a/docker/e2e/docker-compose.yml +++ b/docker/e2e/docker-compose.yml @@ -34,7 +34,7 @@ services: - TAKE_FILE_OWNERSHIP=1 - discovery.type=single-node - "DISABLE_INSTALL_DEMO_CONFIG=true" - - "DISABLE_SECURITY_PLUGIN=true" + - "DISABLE_SECURITY_PLUGIN=true" # TODO: Enable when we have migrated the python client to Opensearch as well. ulimits: memlock: soft: -1 diff --git a/docker/e2e/docker-entrypoint.sh b/docker/e2e/docker-entrypoint.sh index 8cc9199a76..1f75638e28 100644 --- a/docker/e2e/docker-entrypoint.sh +++ b/docker/e2e/docker-entrypoint.sh @@ -1,77 +1,79 @@ #!/bin/bash -# Install Timesketch in editable mode from volume -pip3 install -e /usr/local/src/timesketch/ +# Run the container the default way +if [ "$1" = 'timesketch' ]; then + # Copy the mappings for plaso ingestion. + cp /usr/local/src/timesketch/data/plaso.mappings /etc/timesketch/ + cp /usr/local/src/timesketch/data/generic.mappings /etc/timesketch/ -# Copy the mappings for plaso ingestion. -cp /usr/local/src/timesketch/data/plaso.mappings /etc/timesketch/ -cp /usr/local/src/timesketch/data/generic.mappings /etc/timesketch/ + # Set SECRET_KEY in /etc/timesketch/timesketch.conf if it isn't already set + if grep -q "SECRET_KEY = ''" /etc/timesketch/timesketch.conf; then + OPENSSL_RAND=$( openssl rand -base64 32 ) + # Using the pound sign as a delimiter to avoid problems with / being output from openssl + sed -i 's#SECRET_KEY = \x27\x3CKEY_GOES_HERE\x3E\x27#SECRET_KEY = \x27'$OPENSSL_RAND'\x27#' /etc/timesketch/timesketch.conf + fi -# Set SECRET_KEY in /etc/timesketch/timesketch.conf if it isn't already set -if grep -q "SECRET_KEY = ''" /etc/timesketch/timesketch.conf; then - OPENSSL_RAND=$( openssl rand -base64 32 ) - # Using the pound sign as a delimiter to avoid problems with / being output from openssl - sed -i 's#SECRET_KEY = \x27\x3CKEY_GOES_HERE\x3E\x27#SECRET_KEY = \x27'$OPENSSL_RAND'\x27#' /etc/timesketch/timesketch.conf -fi - -# Set up the Postgres connection -if [ $POSTGRES_PASSWORD ]; then echo "POSTGRES_PASSWORD usage is discouraged. Use Docker Secrets instead and set POSTGRES_PASSWORD_FILE to /run/secrets/secret-name"; fi -if [ $POSTGRES_PASSWORD_FILE ]; then POSTGRES_PASSWORD=$(cat $POSTGRES_PASSWORD_FILE); fi + # Set up the Postgres connection + if [ $POSTGRES_PASSWORD ]; then echo "POSTGRES_PASSWORD usage is discouraged. Use Docker Secrets instead and set POSTGRES_PASSWORD_FILE to /run/secrets/secret-name"; fi + if [ $POSTGRES_PASSWORD_FILE ]; then POSTGRES_PASSWORD=$(cat $POSTGRES_PASSWORD_FILE); fi -if [ $POSTGRES_USER ] && [ $POSTGRES_PASSWORD ] && [ $POSTGRES_ADDRESS ] && [ $POSTGRES_PORT ]; then - sed -i 's#postgresql://:@localhost#postgresql://'$POSTGRES_USER':'$POSTGRES_PASSWORD'@'$POSTGRES_ADDRESS':'$POSTGRES_PORT'#' /etc/timesketch/timesketch.conf - unset POSTGRES_PASSWORD -else - # Log an error since we need the above-listed environment variables - echo "Please pass values for the POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_ADDRESS, and POSTGRES_PORT environment variables" - exit 1 -fi + if [ $POSTGRES_USER ] && [ $POSTGRES_PASSWORD ] && [ $POSTGRES_ADDRESS ] && [ $POSTGRES_PORT ]; then + sed -i 's#postgresql://:@localhost#postgresql://'$POSTGRES_USER':'$POSTGRES_PASSWORD'@'$POSTGRES_ADDRESS':'$POSTGRES_PORT'#' /etc/timesketch/timesketch.conf + unset POSTGRES_PASSWORD + else + # Log an error since we need the above-listed environment variables + echo "Please pass values for the POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_ADDRESS, and POSTGRES_PORT environment variables" + exit 1 + fi -# Set up the OpenSearch connection -if [ $OPENSEARCH_HOST ] && [ $OPENSEARCH_PORT ]; then - sed -i 's#OPENSEARCH_HOST = \x27127.0.0.1\x27#OPENSEARCH_HOST = \x27'$OPENSEARCH_HOST'\x27#' /etc/timesketch/timesketch.conf - sed -i 's#OPENSEARCH_PORT = 9200#OPENSEARCH_PORT = '$OPENSEARCH_PORT'#' /etc/timesketch/timesketch.conf -else - # Log an error since we need the above-listed environment variables - echo "Please pass values for the OPENSEARCH_HOST and OPENSEARCH_PORT environment variables" -fi + # Set up the OpenSearch connection + if [ $OPENSEARCH_HOST ] && [ $OPENSEARCH_PORT ]; then + sed -i 's#OPENSEARCH_HOST = \x27127.0.0.1\x27#OPENSEARCH_HOST = \x27'$OPENSEARCH_HOST'\x27#' /etc/timesketch/timesketch.conf + sed -i 's#OPENSEARCH_PORT = 9200#OPENSEARCH_PORT = '$OPENSEARCH_PORT'#' /etc/timesketch/timesketch.conf + else + # Log an error since we need the above-listed environment variables + echo "Please pass values for the OPENSEARCH_HOST and OPENSEARCH_PORT environment variables" + fi -# Set up the Redis connection -if [ $REDIS_ADDRESS ] && [ $REDIS_PORT ]; then - sed -i 's#UPLOAD_ENABLED = False#UPLOAD_ENABLED = True#' /etc/timesketch/timesketch.conf - sed -i 's#^CELERY_BROKER_URL =.*#CELERY_BROKER_URL = \x27redis://'$REDIS_ADDRESS':'$REDIS_PORT'\x27#' /etc/timesketch/timesketch.conf - sed -i 's#^CELERY_RESULT_BACKEND =.*#CELERY_RESULT_BACKEND = \x27redis://'$REDIS_ADDRESS':'$REDIS_PORT'\x27#' /etc/timesketch/timesketch.conf -else - # Log an error since we need the above-listed environment variables - echo "Please pass values for the REDIS_ADDRESS and REDIS_PORT environment variables" -fi + # Set up the Redis connection + if [ $REDIS_ADDRESS ] && [ $REDIS_PORT ]; then + sed -i 's#UPLOAD_ENABLED = False#UPLOAD_ENABLED = True#' /etc/timesketch/timesketch.conf + sed -i 's#^CELERY_BROKER_URL =.*#CELERY_BROKER_URL = \x27redis://'$REDIS_ADDRESS':'$REDIS_PORT'\x27#' /etc/timesketch/timesketch.conf + sed -i 's#^CELERY_RESULT_BACKEND =.*#CELERY_RESULT_BACKEND = \x27redis://'$REDIS_ADDRESS':'$REDIS_PORT'\x27#' /etc/timesketch/timesketch.conf + else + # Log an error since we need the above-listed environment variables + echo "Please pass values for the REDIS_ADDRESS and REDIS_PORT environment variables" + fi -# Set up web credentials -if [ -z ${TIMESKETCH_USER:+x} ]; then - TIMESKETCH_USER="admin" - echo "TIMESKETCH_USER set to default: ${TIMESKETCH_USER}"; -fi + # Set up web credentials + if [ -z ${TIMESKETCH_USER:+x} ]; then + TIMESKETCH_USER="admin" + echo "TIMESKETCH_USER set to default: ${TIMESKETCH_USER}"; + fi -if [ $TIMESKETCH_PASSWORD_FILE ]; then TIMESKETCH_PASSWORD=$(cat $TIMESKETCH_PASSWORD_FILE); fi -if [ -z ${TIMESKETCH_PASSWORD:+x} ]; then - TIMESKETCH_PASSWORD="$(openssl rand -base64 32)" - echo "TIMESKETCH_PASSWORD set randomly to: ${TIMESKETCH_PASSWORD}"; -fi + if [ $TIMESKETCH_PASSWORD_FILE ]; then TIMESKETCH_PASSWORD=$(cat $TIMESKETCH_PASSWORD_FILE); fi + if [ -z ${TIMESKETCH_PASSWORD:+x} ]; then + TIMESKETCH_PASSWORD="$(openssl rand -base64 32)" + echo "TIMESKETCH_PASSWORD set randomly to: ${TIMESKETCH_PASSWORD}"; + fi -# Sleep to allow the other processes to start -sleep 5 -tsctl create-user "$TIMESKETCH_USER" --password "$TIMESKETCH_PASSWORD" -unset TIMESKETCH_PASSWORD + # Sleep to allow the other processes to start + sleep 5 + tsctl create-user "$TIMESKETCH_USER" --password "$TIMESKETCH_PASSWORD" + unset TIMESKETCH_PASSWORD -cat <> /etc/timesketch/data_finder.yaml + cat <> /etc/timesketch/data_finder.yaml test_data_finder: - description: Testing the data finder in the e2e test. - notes: Import the partial EVTX file for e2e tests. - query_string: data_type:"windows:evtx:record" AND event_identifier:7036 + description: Testing the data finder in the e2e test. + notes: Import the partial EVTX file for e2e tests. + query_string: data_type:"windows:evtx:record" AND event_identifier:7036 EOF -# Run the Timesketch server (without SSL) -cd /tmp -exec `bash -c "/usr/local/bin/celery -A timesketch.lib.tasks worker --uid nobody --loglevel info & \ -gunicorn --reload -b 0.0.0.0:80 --access-logfile - --error-logfile - --log-level info --timeout 120 timesketch.wsgi:application"` + # Run the Timesketch server (without SSL) + cd /tmp + exec `bash -c "/usr/local/bin/celery -A timesketch.lib.tasks worker --uid nobody --loglevel info & \ + gunicorn --reload -b 0.0.0.0:80 --access-logfile - --error-logfile - --log-level info --timeout 120 timesketch.wsgi:application"` fi + +# Run a custom command on container start +exec "$@" diff --git a/docker/release/build/Dockerfile-latest b/docker/release/build/Dockerfile-latest new file mode 100644 index 0000000000..67b1f2e17f --- /dev/null +++ b/docker/release/build/Dockerfile-latest @@ -0,0 +1,37 @@ +# Use the official Docker Hub Ubuntu base image +FROM ubuntu:22.04 + +ARG PPA_TRACK=stable + +# Prevent needing to configure debian packages, stopping the setup of +# the docker container. +RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections + +RUN apt-get update && apt-get install -y --no-install-recommends \ + software-properties-common \ + python3-pip \ + python3-wheel \ + python3-setuptools \ + python3-psycopg2 \ + gpg-agent \ + wget \ + tzdata \ + && rm -rf /var/lib/apt/lists/* + +# Install Timesketch +RUN wget https://raw.githubusercontent.com/google/timesketch/master/requirements.txt +RUN pip3 install -r requirements.txt +RUN pip3 install https://github.com/google/timesketch/archive/master.zip + +# Install Plaso +RUN add-apt-repository -y ppa:gift/$PPA_TRACK +RUN apt-get update && apt-get install -y --no-install-recommends \ + plaso-tools \ + && rm -rf /var/lib/apt/lists/* + +# Copy the entrypoint script into the container +COPY docker-entrypoint.sh / +RUN chmod a+x /docker-entrypoint.sh + +# Load the entrypoint script to be run later +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/docker/release/build/cloudbuild.yaml b/docker/release/build/cloudbuild.yaml new file mode 100644 index 0000000000..62132e20e7 --- /dev/null +++ b/docker/release/build/cloudbuild.yaml @@ -0,0 +1,18 @@ +# Google Cloud Build configuration for Timesketch server release +steps: + - name: gcr.io/cloud-builders/docker + args: + [ + "build", + "-t", + "us-docker.pkg.dev/osdfir-registry/timesketch/timesketch:$TAG_NAME", + "--build-arg", + "RELEASE_TAG=${TAG_NAME}", + "-f", + "docker/release/build/Dockerfile-release", + ".", + ] + timeout: 2400s +timeout: 2400s +images: + - us-docker.pkg.dev/osdfir-registry/timesketch/timesketch:$TAG_NAME diff --git a/docker/release/config.env b/docker/release/config.env index d303d41fb5..2febd25732 100644 --- a/docker/release/config.env +++ b/docker/release/config.env @@ -1,7 +1,7 @@ -# Timesketch version to run. Latest is build from the main branch and a release +# Timesketch version to run. Latest is build from the master branch and a release # number is build from a release tag. Using latest means that you are running # the bleeding edge version and we cannot guarantee that it will not be broken. -TIMESKETCH_VERSION=20250112 +TIMESKETCH_VERSION=20250408 # Timesketch PATH local etc/timesketch TIMESKETCH_CONFIG_PATH=./etc/timesketch diff --git a/docker/release/docker-compose.yml b/docker/release/docker-compose.yml new file mode 100644 index 0000000000..0cad1346a1 --- /dev/null +++ b/docker/release/docker-compose.yml @@ -0,0 +1,86 @@ +version: "3.7" +services: + timesketch-web: + container_name: timesketch-web + image: us-docker.pkg.dev/osdfir-registry/timesketch/timesketch:${TIMESKETCH_VERSION} + environment: + - NUM_WSGI_WORKERS=${NUM_WSGI_WORKERS} + restart: always + command: timesketch-web + volumes: + - ${TIMESKETCH_CONFIG_PATH}:/etc/timesketch/ + - ${TIMESKETCH_UPLOAD_PATH}:/usr/share/timesketch/upload/ + - ${TIMESKETCH_LOGS_PATH}:/var/log/timesketch/ + + # Temporary service while the V2 UI is in the testing phase. + # TODO: Remove when V2 is the default. + timesketch-web-legacy: + container_name: timesketch-web-legacy + image: us-docker.pkg.dev/osdfir-registry/timesketch/timesketch:${TIMESKETCH_VERSION} + environment: + - NUM_WSGI_WORKERS=${NUM_WSGI_WORKERS} + restart: always + command: timesketch-web-legacy + volumes: + - ./etc/timesketch:/etc/timesketch/ + - ./upload:/usr/share/timesketch/upload/ + - ./logs:/var/log/timesketch/ + + timesketch-worker: + container_name: timesketch-worker + image: us-docker.pkg.dev/osdfir-registry/timesketch/timesketch:${TIMESKETCH_VERSION} + environment: + - WORKER_LOG_LEVEL=${WORKER_LOG_LEVEL} + restart: always + command: timesketch-worker + volumes: + - ${TIMESKETCH_CONFIG_PATH}:/etc/timesketch/ + - ${TIMESKETCH_UPLOAD_PATH}:/usr/share/timesketch/upload/ + - ${TIMESKETCH_LOGS_PATH}:/var/log/timesketch/ + + opensearch: + container_name: opensearch + image: opensearchproject/opensearch:${OPENSEARCH_VERSION} + restart: always + environment: + - TAKE_FILE_OWNERSHIP=1 + - discovery.type=single-node + - "DISABLE_INSTALL_DEMO_CONFIG=true" + - "DISABLE_SECURITY_PLUGIN=true" # TODO: Enable when we have migrated the python client to Opensearch as well. + - "OPENSEARCH_JAVA_OPTS=-Xms${OPENSEARCH_MEM_USE_GB}g -Xmx${OPENSEARCH_MEM_USE_GB}g" + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + volumes: + - ${OPENSEARCH_DATA_PATH}:/usr/share/opensearch/data/ + + postgres: + container_name: postgres + image: postgres:${POSTGRES_VERSION} + environment: + - POSTGRES_USER=timesketch + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + restart: always + volumes: + - ${POSTGRES_DATA_PATH}:/var/lib/postgresql/data + + redis: + container_name: redis + image: redis:${REDIS_VERSION} + command: "redis-server" + restart: always + + nginx: + container_name: nginx + image: nginx:${NGINX_VERSION} + restart: always + ports: + - ${NGINX_HTTP_PORT}:80 + - ${NGINX_HTTPS_PORT}:443 + volumes: + - ${NGINX_CONFIG_PATH}:/etc/nginx/nginx.conf + diff --git a/docs/changelog/index.md b/docs/changelog/index.md index 9aaa8b06cd..1986ab8087 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -38,7 +38,7 @@ Released: 2024-02-07 ### What's Changed #### ✨ Features -* Collapsable left panel by @berggren in [#3008](https://github.com/google/timesketch/pull/3008) +* Collapsible left panel by @berggren in [#3008](https://github.com/google/timesketch/pull/3008) * Support for Large Language Model (LLM) services by @berggren in [#3019](https://github.com/google/timesketch/pull/3019) * Implement user management (create, list, get) via API by @lo-chr in [#3024](https://github.com/google/timesketch/pull/3024) * Setup frontend unit tests with vitest by @Annoraaq in [#3013](https://github.com/google/timesketch/pull/3013) @@ -166,7 +166,7 @@ Released: 2023-09-13 * Adding tag filter chips to sigma rules by @jkppr in https://github.com/google/timesketch/pull/2890 #### 🐞 Fixes -* correct paramters in cli attributes method by @jaegeral in https://github.com/google/timesketch/pull/2863 +* correct parameters in cli attributes method by @jaegeral in https://github.com/google/timesketch/pull/2863 * Update troubleshooting.md by @jaegeral in https://github.com/google/timesketch/pull/2866 * Update Date chip to support milliseconds by @sydp in https://github.com/google/timesketch/pull/2867 * Allow API port to listen on localhost by @tomchop in https://github.com/google/timesketch/pull/2875 @@ -198,7 +198,7 @@ Released: 2023-07-21 * Support event list sorting (asc/desc) by @berggren in https://github.com/google/timesketch/pull/2843 #### 🐞 Fixes -* Consitent forms and cleaned up XML viewer by @berggren in https://github.com/google/timesketch/pull/2812 +* Consistent forms and cleaned up XML viewer by @berggren in https://github.com/google/timesketch/pull/2812 * Remove ports from e2e-tests by @berggren in https://github.com/google/timesketch/pull/2816 * Update Account Finder Analyzer by @jkppr in https://github.com/google/timesketch/pull/2803 * Adding hashR user documentation by @jkppr in https://github.com/google/timesketch/pull/2824 diff --git a/docs/developers/api-client.md b/docs/developers/api-client.md index 5cba58d90e..2645647c9b 100644 --- a/docs/developers/api-client.md +++ b/docs/developers/api-client.md @@ -543,7 +543,7 @@ To add tags to multiple events: ```python # first search for the events that you want to search for -events = sketch.explore('foobarsearchterm', as_dict=True) +events = sketch.explore('foobarsearchterm') events['objects'] for event in events['objects']: print(event.get('_id')) diff --git a/docs/developers/api-upload-data.md b/docs/developers/api-upload-data.md index e15ee87d34..1f662b2cdf 100644 --- a/docs/developers/api-upload-data.md +++ b/docs/developers/api-upload-data.md @@ -245,9 +245,12 @@ work with Timesketch. This function does limited checking before making it available. The timeline may or may not work in Timesketch, depending on multiple factors._ -- datetime +The data that is ingested needs to have few fields already set before it can be +ingested into Timesketch: + +- message - timestamp_desc -- data_type +- datetime The datetime field also needs to be mapped as a date, not a text string. @@ -259,13 +262,10 @@ from timesketch_api_client import config ts_client = config.get_client() sketch = ts_client.get_sketch(SKETCH_ID) -timeline = sketch.generate_timeline_from_es_index( - es_index_name=OPENSEARCH_INDEX_NAME, +sketch.generate_timeline_from_es_index( + index_name=OPENSEARCH_INDEX_NAME, name=TIMELINE_NAME, provider='My Custom Ingestion Script', context='python my_custom_script.py --ingest', ) - -# Use `timeline.id` as the value of the integer field `__ts_timeline_id`, -# e.g. Logstash filter: `{mutate {add_field => { "__ts_timeline_id" => "${TIMELINE_ID}"}}} `` ``` diff --git a/docs/developers/frontend-development.md b/docs/developers/frontend-development.md index 4be1d4a687..fc41ded787 100644 --- a/docs/developers/frontend-development.md +++ b/docs/developers/frontend-development.md @@ -2,18 +2,24 @@ hide: - footer --- +### Frontend (old) development dependencies -# Frontend-ng developement - -When developing the `frontend-ng` you use the VueJS frontend server. Changes will be picked up automatically +When developing the frontend you use the Vue.js frontend server. Changes will be picked up automatically as soon as a `.vue` file is saved without having to rebuild the frontend or even refresh your browser. -## Install dependencies +If you develop a new feature, consider changing to `frontent-ng`, the old frontend is likely to be deprecated in 2023. -Inside the container shell go to the Timesketch frontend-ng directory. +First we need to get an interactive shell to the container to install the frontend modules: + +```bash +$ docker compose exec timesketch yarn install --cwd=/usr/local/src/timesketch/timesketch/frontend +$ docker compose exec timesketch yarn run --cwd=/usr/local/src/timesketch/timesketch/frontend build --mode development --watch +``` + +Then inside the container shell go to the Timesketch frontend directory. ```bash -cd /usr/local/src/timesketch/timesketch/frontend-ng +! cd /usr/local/src/timesketch/timesketch/frontend ``` Note that this directory in the container is mounted as volume from your local repo and mirrors changes to your local repo. @@ -21,45 +27,94 @@ Note that this directory in the container is mounted as volume from your local r Install node dependencies ```bash -apt update && apt install -y make build-essential g++ -npm install --force +! npm install ``` This will create `node_modules/` folder from `package.json` in the frontend directory. ```bash -yarn install +! yarn install ``` -## Tweak config file +### Tweak config file * In your `timesketch` docker container, edit `/etc/timesketch/timesketch.conf` and set `WTF_CSRF_ENABLED = False`. -## Start the VueJS development server +### Start the VueJS development server + +Follow the steps in the previous section to get dependencies installed and the config file tweaked. You need two shells: -1. Start the main webserver (for serving the API etc) in the first shell: +1. Start the main webserver (for serving the API etc.) in the first shell: -```bash -docker exec -it timesketch gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 600 -c /usr/local/src/timesketch/data/gunicorn_config.py timesketch.wsgi:application -``` + ```bash + $ CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" + $ docker exec -it $CONTAINER_ID gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 600 -c /usr/local/src/timesketch/data/gunicorn_config.py timesketch.wsgi:application + ``` 2. Start the development webserver in the second shell: -```bash -docker exec timesketch yarn run --cwd=/usr/local/src/timesketch/timesketch/frontend-ng serve -``` + ```bash + $ CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" + $ docker compose exec timesketch yarn run --cwd=/usr/local/src/timesketch/timesketch/frontend serve + ``` This will spawn a listener on port `5001`. Point your browser to `http://localhost:5001/login`, login with your dev credentials, and you should be redirected to the main Timesketch page. All code changes in `.vue` files will be instantly picked up. +## Frontend-ng development + +When developing the `frontend-ng` you use the Vue.js frontend server. Changes will be picked up automatically +as soon as a `.vue` file is saved without having to rebuild the frontend or even refresh your browser. + +### Install dependencies + +Inside the container shell go to the Timesketch frontend-ng directory. + +```bash +! cd /usr/local/src/timesketch/timesketch/frontend-ng +``` + +Note that this directory in the container is mounted as volume from your local repo and mirrors changes to your local repo. + +Install node dependencies -## Build UI for production +```bash +! npm install +``` -Generate UI builds: +This will create `node_modules/` folder from `package.json` in the frontend directory. ```bash -docker exec timesketch yarn build --cwd=/usr/local/src/timesketch/timesketch/frontend-ng +! yarn install ``` + +### Tweak config file + +* In your `timesketch` docker container, edit `/etc/timesketch/timesketch.conf` and set `WTF_CSRF_ENABLED = False`. + +### Start the VueJS development server + +You need two shells: + +1. Start the main webserver (for serving the API etc.) in the first shell: + + ```bash + $ CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" + $ docker exec -it $CONTAINER_ID gunicorn --reload -b 0.0.0.0:5000 --log-file - --timeout 600 -c /usr/local/src/timesketch/data/gunicorn_config.py timesketch.wsgi:application + ``` + +2. Start the development webserver in the second shell: + + ```bash + $ CONTAINER_ID="$(docker container list -f name=timesketch-dev -q)" + $ docker compose exec timesketch yarn run --cwd=/usr/local/src/timesketch/timesketch/frontend-ng serve + ``` + +This will spawn a listener on port `5001`. Point your browser to `http://localhost:5001/login`, login with your +dev credentials, and you should be redirected to the main Timesketch page. All code changes in `.vue` files will +be instantly picked up. + +If you already have a yarn process running with the "old" frontend, it might not work. diff --git a/docs/developers/testing.md b/docs/developers/testing.md index 6cf028a42a..53a9c9a84a 100644 --- a/docs/developers/testing.md +++ b/docs/developers/testing.md @@ -29,7 +29,7 @@ To run TSLint in watch mode, use To run a single test (there are multiple ways to do it), open a shell in the docker container: ```shell -docker exec -it timesketch /bin/bash +$ docker exec -it $CONTAINER_ID /bin/bash ``` Switch to: @@ -47,7 +47,7 @@ And execute the single test Or all in one: ```bash -sudo docker exec -it timesketch python3 -m pytest /usr/local/src/timesketch/timesketch/lib/emojis_test.py -v +$ sudo docker exec -it $CONTAINER_ID python3 -m pytest /usr/local/src/timesketch/timesketch/lib/emojis_test.py -v ``` ## Writing unittests @@ -80,7 +80,7 @@ End2end (e2e) tests are run on Github with every commit. Those tests will setup To run the e2e-tests locally execute to setup the e2e docker images and run them: ```bash -sh end_to_end_tests/tools/run_end_to_end_tests.sh +$ sh end_to_end_tests/tools/run_end_to_end_tests.sh ``` The tests are stored in: @@ -103,7 +103,7 @@ The following example is for changing / adding tests to `client_test.py` ```shell $ export CONTAINER_ID="$(sudo -E docker container list -f name=e2e_timesketch -q)" -$ docker exec -it timesketch /bin/bash +$ docker exec -it $CONTAINER_ID /bin/bash ! rm /usr/local/lib/python3.10/dist-packages/end_to_end_tests/client_test.py ! ln -s /usr/local/src/timesketch/end_to_end_tests/client_test.py /usr/local/lib/python3.10/dist-packages/end_to_end_tests/client_test.py ``` @@ -117,7 +117,7 @@ From now on you can edit the `client_test.py` file outside of the docker instanc or run the following outside of the container: ```bash -sudo docker exec -it timesketch python3 /usr/local/src/timesketch/end_to_end_tests/tools/run_in_container.py +$ sudo docker exec -it $CONTAINER_ID python3 /usr/local/src/timesketch/end_to_end_tests/tools/run_in_container.py ``` ## Linting / Code format @@ -131,3 +131,29 @@ To check linting on a single file, run the following in your docker container: ! apt-get install pylint==2.6.0 ! pylint /usr/local/src/timesketch/timesketch/ --rcfile .pylintrc -v ``` + +## Generate test events + +The `/utils/generate_sample_data.py` tool provides utilities for generating sample or test data. +Currently, it includes a command to generate dummy CSV files, which can be useful for testing import functionality or for creating sample timelines. + +**Usage:** + +```bash +python3 utils/generate_sample_data.py [OPTIONS] +``` + +**Options:** + +* `--output FILE`: The path to the output CSV file. (Required) +* `--count INTEGER`: The number of dummy events to generate. (Default: 100) +* `--start-date TEXT`: The start date for the events in ISO 8601 format (e.g., `YYYY-MM-DDTHH:MM:SS`). (Required) +* `--end-date TEXT`: The end date for the events in ISO 8601 format (e.g., `YYYY-MM-DDTHH:MM:SS`). (Required) + +**Example:** + +To generate a CSV file named `dummy_events.csv` with 50 events between January 1st, 2023, 09:00:00 and January 1st, 2023, 17:00:00: + +```bash +python3 utils/generate_sample_data.py --output dummy_events.csv --count 50 --start-date 2023-01-01T09:00:00 --end-date 2023-01-01T17:00:00 +``` diff --git a/docs/guides/admin/admin-cli.md b/docs/guides/admin/admin-cli.md index ac799a59e1..52005c49d6 100644 --- a/docs/guides/admin/admin-cli.md +++ b/docs/guides/admin/admin-cli.md @@ -462,7 +462,19 @@ tsctl similarity_score #### sketch-info Get information about a sketch -Displays various information about a given sketch. +Displays detailed information about a specific sketch. + +This command retrieves and displays comprehensive information about a +Timesketch sketch, including: + +- **Sketch Details:** The sketch's ID and name. +- **Active Timelines:** A table listing the active timelines within the + sketch, including their search index ID, index name, creation date, + user ID, description, status, timeline name, and timeline ID. +- **Sharing Information:** Details about users and groups with whom the + sketch is shared. +- **Sketch Status:** The current status of the sketch (e.g., "ready", + "archived"). ```shell tsctl sketch-info @@ -472,13 +484,12 @@ Example: ```shell Sketch 1 Name: (aaa) -searchindex_id index_name created_at user_id description -1 a17732074d8b492e934ef79910bfefa1 2022-10-21 15:06:52.849124 1 20200918_0417_DESKTOP-SDN1RPT -3 88002da782f64061bf3703bc782b6006 2022-10-21 15:19:26.072964 1 all_packets -1 a17732074d8b492e934ef79910bfefa1 2022-10-21 15:28:55.474166 1 E01-DC01_20200918_0347_CDrive -4 11d761cd266640d798e30bb897c8dd4e 2022-10-21 15:32:15.060184 1 autoruns-desktop-sdn1rpt_fresh_import -3 88002da782f64061bf3703bc782b6006 2022-10-31 10:15:12.316273 1 sigma_events -3 88002da782f64061bf3703bc782b6006 2022-10-31 10:15:48.592320 1 sigma_events2 +searchindex_id index_name created_at user_id description status timeline_name timeline_id +1 3e062029b52f4e1a8a103488b99bc2b3 2025-03-18 14:49:52.402364 1 my_file_with_a_timeline ready my_file_with_a_timeline 2 +1 3e062029b52f4e1a8a103488b99bc2b3 2025-03-18 16:21:07.707528 1 evtx_part ready evtx_part 3 +1 3e062029b52f4e1a8a103488b99bc2b3 2025-03-21 15:24:55.935364 1 sigma_events ready sigma_events 10 +10 9a0f22670bf74ba6884f3ba9b261bf13 2025-03-21 15:31:45.279662 1 evtx ready evtx 11 +1 3e062029b52f4e1a8a103488b99bc2b3 2025-03-21 15:41:10.860161 1 sigma_eventsa ready sigma_eventsa 12 Shared with: Users: (user_id, username) 3: bar @@ -497,17 +508,118 @@ id status created_at user_id In some cases, logs present a OpenSearch Index id and it is not easy to find out which Sketch that index is related to. -Therefore the following command can be used: +Therefore the following command can be used `tsctl searchindex-info`: + +Displays detailed information about a specific search index. You can specify the index using either its database ID or its OpenSearch index name. +The command shows the search index ID and name, and lists all timelines associated with the index, including their IDs, names, and associated sketch IDs and names. ```bash -# tsctl searchindex-info --searchindex_id asd +# tsctl searchindex-info --searchindex_id 99 Searchindex: asd not found in database. -# tsctl searchindex-info --searchindex_id 4c5afdf60c6e49499801368b7f238353 +# tsctl searchindex-info --searchindex_id 1 +Searchindex: 1 Name: sigma_events found in database. +Corresponding Timeline id: 3 in Sketch Id: 2 +Corresponding Sketch id: 2 Sketch name: asdasd +# tsctl searchindex-info --index_name 4c5afdf60c6e49499801368b7f238353 Searchindex: 4c5afdf60c6e49499801368b7f238353 Name: sigma_events found in database. Corresponding Timeline id: 3 in Sketch Id: 2 Corresponding Sketch id: 2 Sketch name: asdasd ``` +If neither `searchindex_id` nor `index_name` is provided, an error message is printed. If no matching search index is found, an appropriate message is printed + +### Timeline status + +The `tsctl timeline-status` command allows to get or set a timeline status. +This can be useful in the following scenarios: + +* Monitoring processing In large-scale investigations, timelines can take a considerable amount of time to process. +This feature allows administrators or automated scripts to monitor the processing status of timelines, ensuring that they are progressing as expected. + +* Automated Status updates: Scripts can be used to automatically update the status of timelines based on the results of automated analysis or processing steps. For example, if an automated script detects a critical error during analysis, it can set the timeline status to "fail." + +* Toubeshooting and Error handling: +** Quickly identifying timelines with a "fail" status allows investigators to troubleshoot issues and re-process data if necessary. +** By monitoring the status of timelines, administrators can identify potential bottlenecks or errors in the processing pipeline. +** Set the status to `fail` is a task is stuck. + +Usage: + +```bash +tsctl timeline-status [OPTIONS] TIMELINE_ID +--action [get|set] + Specify whether to get or set the timeline status. + - "get": Retrieves the current status of the timeline. + - "set": Sets the status of the timeline to the value specified by "--status". + (Required) + + --status [ready|processing|fail] + The desired status to set for the timeline. + This option is only valid when "--action" is set to "set". + Valid options are: + - "ready": Indicates that the timeline is ready for analysis. + - "processing": Indicates that the timeline is currently being processed. + - "fail": Indicates that the timeline processing failed. + (Required when --action is set to set) +``` + +Examples: +```bash +# Get the status of timeline with ID 123: + tsctl timeline-status --action get 123 + + # Set the status of timeline with ID 456 to "ready": + tsctl timeline-status --action set --status ready 456 + + # Set the status of timeline with ID 789 to "fail": + tsctl timeline-status --action set --status fail 789 + + # Try to set a status without the action set to set. + tsctl timeline-status --status fail 789 + # This will fail and display an error message. +``` + +### Searchindex-status + +The `tsctl searchindex-status` command allows to get or set a searchindex status. + +Usage: +``` +tsctl searchindex-status --help +Usage: tsctl searchindex-status [OPTIONS] SEARCHINDEX_ID + + Get or set a searchindex status + + If "action" is "set", the given value of status will be written in the + status. + + Args: action: get or set searchindex status. status: searchindex + status. Only valid choices are ready, processing, fail. + +Options: + --action [get|set] get or set timeline status. + --status [ready|processing|fail] + get or set timeline status. + --searchindex_id TEXT Searchindex ID to search for e.g. + 4c5afdf60c6e49499801368b7f238353. + [required] + --help Show this message and exit. +``` + + +Examples: +```bash +tsctl searchindex-status --action set 1 --status fail +Searchindex 1 status set to fail +To verify run: tsctl searchindex-status 1 --action get +tsctl searchindex-status --action set --status fail 1 +Searchindex 1 status set to fail +To verify run: tsctl searchindex-status 1 --action get +tsctl searchindex-status 1 --action get +searchindex_id index_name created_at user_id description status +1 f609b138aa1e4c448ece6c012dcb2bab 2025-03-07 09:23:37.172143 1 # fail +``` + ### Sigma #### List Sigma rules @@ -661,3 +773,186 @@ tsctl analyzer-stats sigma --scope many_hits --result_text_search 71a52 46 2.833333 0 * Scheduler 71a5257c-222f-4898-a117-694d6c63457c 59 2023-01-04 17:09:04.014973 48 2.750000 0 * Scheduler 71a5257c-222f-4898-a117-694d6c63457c 63 2023-01-04 17:09:04.148185 ``` + +### Celery Task Management + +These commands allow you to inspect and manage Celery tasks within the Timesketch application. + +#### `tsctl celery-tasks-redis` + +**Description:** + +Checks and displays the status of all Celery tasks stored in Redis. This command connects to the Redis instance used by Celery to store task metadata and retrieves information about all tasks. It then presents this information in a formatted table, including the task ID, name, status, and result. + +Notes: + +* Celery tasks have a result_expire date, which by default is one day. After that, the results will no longer be available. + +**Usage:** + +```bash +tsctl celery-tasks-redis +``` + +**Output:** + +A table with the following columns: + +* Task ID: The unique identifier for the Celery task. +* Name: The name of the task. +* Status: The current status of the task (e.g., SUCCESS, FAILURE, PENDING). +* Result: The result of the task if it has completed successfully. + +``` +Task ID Name Status Result +13a995db28d2479b854db177d1301ecb None SUCCESS 3e062029b52f4e1a8a103488b99bc2b3 +1829df81cb534ab29fe44d1e8c605c95 None SUCCESS 3e062029b52f4e1a8a103488b99bc2b3 +ffd3d6157e0f458bbe5f4c97e6d70d03 None SUCCESS 9a0f22670bf74ba6884f3ba9b261bf13 +``` + +#### tsctl celery-tasks + +Shows running or past Celery tasks. This command provides various ways to inspect and view the status of Celery tasks within the Timesketch application. It can display information about a specific task, list active tasks, or show all tasks (including pending, active, and failed). + +**Usage** + +```bash +tsctl celery-tasks [OPTIONS] +``` + +Options: + +* `--task_id TEXT`: Show information about a specific task ID. +* `--active`: Show only active tasks. +* `--show_all`: Show all tasks, including pending, active, and failed. + +**Notes** + +* Celery tasks have a `result_expire date`, which defaults to one day. After this period, task results may no longer be available. +* When displaying all tasks, the status of each task is retrieved, which may take some time. +* If no arguments are provided, it will print a message to use `--active` or `--show_all`. + +**Examples** + +```bash +tsctl celery-tasks --task_id +tsctl celery-tasks --active +tsctl celery-tasks --show_all +``` + +#### celery-revoke-task + +Revokes (cancels) a Celery task. This command attempts to revoke a running Celery task, effectively canceling its execution. It uses the task ID to identify the specific task to revoke. + +Note: For short tasks, they have to be cancelled quick. + +**Usage** + +```bash +tsctl celery-revoke-task TASK_ID +``` + +Example: +``` +tsctl celery-revoke-task 8115648e-944c-4452-962e-644041603419 +``` + +#### list-config + +**Description:** + +Lists all configuration variables currently loaded by the Timesketch Flask application (`current_app.config`). + +This command iterates through the application's configuration settings. + +It automatically identifies keys commonly associated with sensitive information (like `SECRET_KEY`, `PASSWORD`, `API_KEY`, `TOKEN`, etc.) based on a predefined list of keywords. +To prevent accidental exposure, the values corresponding to these sensitive keys are redacted and replaced with `******** (redacted)` in the output. All other configuration key-value pairs are displayed as they are loaded. + +The output is sorted alphabetically by key for consistent and predictable results. A note is included at the end to remind the user that some values may have been redacted for security reasons. + +**Usage:** + +```bash +tsctl list-config +Timesketch Configuration Variables: +----------------------------------- +ANALYZERS_DEFAULT_KWARGS: {} +APPLICATION_ROOT: / +AUTO_SKETCH_ANALYZERS: [] +AUTO_SKETCH_ANALYZERS_KWARGS: {} +CELERY_BROKER_URL: redis://redis:6379 +CELERY_RESULT_BACKEND: redis://redis:6379 +CONTEXT_LINKS_CONFIG_PATH: /etc/timesketch/context_links.yaml +DATA_FINDER_PATH: /etc/timesketch/data_finder.yaml +DEBUG: False +OPENSEARCH_HOST: 127.0.0.1 +OPENSEARCH_PORT: 9200 +SECRET_KEY: ******** (redacted) +SQLALCHEMY_DATABASE_URI: ******** (redacted) +UPLOAD_ENABLED: True +... +----------------------------------- +Note: Some values might be sensitive (e.g., SECRET_KEY, passwords). +``` + +### export-sketch + +Exports a Timesketch sketch to a zip archive. The archive contains: + +1. **`metadata.json`**: A comprehensive JSON file detailing the sketch, including: + * Basic sketch information (ID, name, description, status, timestamps, owner). + * Permissions and sharing details. + * Associated timelines with their configurations and data sources. + * Saved views (queries, filters, DSL). + * Stories, including their content. + * Aggregations and aggregation groups. + * Saved graphs. + * Analysis sessions and their results. + * DFIQ scenarios, including nested facets and investigative questions. + * Sketch attributes. + * Comments linked to specific events within the sketch. + * Export timestamp and Timesketch version. +2. **Event Data File**: (e.g., `events.csv` or `events.jsonl`) + * All events from the sketch's active (not failed or processing) timelines, processed in batches to conserve memory. + * The format can be specified as CSV (default) or JSONL using the `--output-format` option. + * By default all fields are exported. Using `--default-fields` a predefined set (DEFAULT_SOURCE_FIELDS in `timesketch/lib/definitions.py`) of common event fields are exported. + +**WARNING:** Re-importing this archive into Timesketch is not natively supported. This export is primarily for data archival, external analysis, or manual migration. + +Progress messages are printed to the console during the export process. + +**Usage:** + +Parameters: + +* **:** (Required) The ID of the sketch to export. +* **--filename / -f:** (Optional) The name for the output zip file. Default: sketch_{sketch_id}_{output_format}_export.zip +* **--output-format:** (Optional) The format for the event data ('csv' or 'jsonl'). Default: 'csv'. +* **--all-fields:** (Optional default: True) Export all event fields instead of the default set. + +*Note on Container Usage:* When running this command within a container (e.g., Docker), the output zip file is written inside the container's filesystem. Ensure you write to a mounted volume or copy the file out of the container afterwards. + +Example: + +```bash +tsctl export-sketch 1 + +Exporting sketch [1] "aaaa" to sketch_1_csv_export.zip... + +WARNING: There is currently no native method to re-import this exported archive back into Timesketch. + +Gathering metadata... + Processing comments for 4 event(s)... + 2025-05-14 10:02:00 INFO GET http://opensearch:9200/ [status:200 request:0.008s] + Exporting all event fields. + Requesting event data (preferring JSONL)... +2025-05-14 10:02:00 INFO POST http://opensearch:9200/484a472fd004a72f2ee857c39a4fb17c,9c49430d1e5f42849bdb253647e1f836,5caa30a18efa4333971b42957d86d09e/_search?scroll=1m&search_type=query_then_fetch [status:200 request:0.214s] + +[...] + + Detected non-JSONL format in response (assuming CSV). + 303490 events processed for export. + Input is not JSONL, using as CSV... +Creating zip archive... +Sketch exported successfully to sketch_1_csv_export.zip +``` \ No newline at end of file diff --git a/docs/guides/admin/load-dfiq.md b/docs/guides/admin/load-dfiq.md new file mode 100644 index 0000000000..7e80b9b9ed --- /dev/null +++ b/docs/guides/admin/load-dfiq.md @@ -0,0 +1,36 @@ +--- +hide: + - footer +--- +# Loading DFIQ Template Data + +This guide explains how to load DFIQ (Digital Forensics Investigative Questions) +template data into Timesketch. DFIQ data provides a structured way to ask +questions and provides approaches for digital forensic investigations. + +## Steps + +Follow these steps to load the DFIQ template data: + +1. **Enable DFIQ:** + * Open your `timesketch.conf` file. + * Locate the `DFIQ_ENABLED` setting. + * Set the value to `True`. +2. **Replace DFIQ folders:** + * Navigate to the default Timesketch + [data/dfiq](https://github.com/google/timesketch/tree/master/data/dfiq) + directory. + * Delete the existing content of the directory. + * Replace the content with the folders from the official + [DFIQ repository](https://github.com/google/dfiq/tree/main/dfiq/data). +3. **Restart Timesketch:** + * Restart your timesketch docker container. + * This ensures that the new DFIQ data is loaded and recognized by the system. + +## Verification + +After completing these steps, you should see the DFIQ element loaded on your +sketches in the top. + +If the data is loaded correctly, you will find new questions and approaches +available to be used. diff --git a/docs/guides/admin/scaling-and-limits.md b/docs/guides/admin/scaling-and-limits.md index 7f2367eed1..05ace81058 100644 --- a/docs/guides/admin/scaling-and-limits.md +++ b/docs/guides/admin/scaling-and-limits.md @@ -8,7 +8,7 @@ Timesketch is designed to scale. The minimum system requirements are: -- Machine with Ubuntu 20.04 installed. +- Machine with Ubuntu 22.04 installed. - At least 8GB RAM, but more the better. - Optional: Domain name registered and configure for the machine if you want to setup SSL for the webserver. @@ -19,7 +19,7 @@ These are the limitations: ## OpenSearch indices limitation In the past, every timeline in a sketch was a dedicated OpenSearch Index. In larger installations, Timesketch hit the number of maximum open shards OpenSearch could handle. -Therefore a design [https://github.com/google/timesketch/issues/1567](change) was made to tackle those limitations +Therefore a design [https://github.com/google/timesketch/issues/1567](change) was made to tackle those limitations: - There are maximum number (1500) of shards that can be opened. - There are limitations with Lucene (which OpenSearch uses) and then OpenSearch itself, see https://www.elastic.co/guide/en/app-search/current/limits.html and maximum sizes of HTTP requests, hence when Timesketch uploads files they are split up, to avoid HTTP limitations. @@ -59,7 +59,7 @@ With a decent OpenSearch deployment you can have hundreds of millions events acr [This article](https://edward-cernera.medium.com/deploy-a-multi-node-elasticsearch-instance-with-docker-compose-ef63625f246e) will give you a good start to scale the OpenSearch cluster. Be careful to not expose your Cluster to systems other then the Timesketch node(s). -The config and credentials to the OpenSearch cluster are stored in https://github.com/google/timesketch/blob/master/data/timesketch.conf. If those calues are changed, the Timesketch Instance needs to be restarted. +The config and credentials to the OpenSearch cluster are stored in https://github.com/google/timesketch/blob/master/data/timesketch.conf. If those values are changed, the Timesketch Instance needs to be restarted. ### Celery workers diff --git a/docs/guides/admin/troubleshooting.md b/docs/guides/admin/troubleshooting.md index 8af963109a..f58d72e4e1 100644 --- a/docs/guides/admin/troubleshooting.md +++ b/docs/guides/admin/troubleshooting.md @@ -14,16 +14,16 @@ If you report a bug or ask for help in Slack, please provide as much information ## Troubleshooting playbook -* Is it only affecting one user? -* Is it only affecting one sketch / timeline? -* Can the issue be reproduced on demo.timesketch.org? -* Can the issue be reproduced on a different device / clear caches from browser? -* Any errors in Chrome console for any javascript errors or failed HTTP requests -* Any errors in nginx / webserver logs? -* Any errors in Timesketch / celery worker logs -* Any errors in ES logs? -* Any errors in postgres logs? -* What versions is running (Timesketch, Plaso, ...) `cat /usr/local/src/timesketch/timesketch/version.py` in the Docker container to get the Timesketch version +- Is it only affecting one user? +- Is it only affecting one sketch / timeline? +- Can the issue be reproduced on demo.timesketch.org? +- Can the issue be reproduced on a different device / clear caches from browser? +- Any errors in Chrome console for any javascript errors or failed HTTP requests +- Any errors in nginx / webserver logs? +- Any errors in Timesketch / celery worker logs +- Any errors in ES logs? +- Any errors in postgres logs? +- What versions is running (Timesketch, Plaso, ...) `cat /usr/local/src/timesketch/timesketch/version.py` in the Docker container to get the Timesketch version ## Frontend issues @@ -31,14 +31,14 @@ To troubleshoot web frontend issues, the first look should go to the Chrome deve To raise issues related to the web frontend, please provide the following: -* Copy out the full error message(s) from Chrome Console -* The URL (without your local IP or Domain) -* What was clicked before it happened -* Any entries in the server side logs (see below)? -* Share a screenshot if possible -* If possible details about the event / sketch - * Was it an imported Plaso file or CSV or JSONL? - * Was the data imported via Web or API client? +- Copy out the full error message(s) from Chrome Console +- The URL (without your local IP or Domain) +- What was clicked before it happened +- Any entries in the server side logs (see below)? +- Share a screenshot if possible +- If possible details about the event / sketch + - Was it an imported Plaso file or CSV or JSONL? + - Was the data imported via Web or API client? ## Docker @@ -56,30 +56,30 @@ See [docs/learn/server-admin](docs/learn/server-admin#troubleshooting-database-s ## Import issues -* Is the celery worker running? -* Have a look at the celery logs. -* Is it a specific file that causes problems? -* What is the WebUI status of the import? -* Try switching from WebUI to the `import_client.py` to upload the same file -* Try to upload one of the [sample files](https://github.com/google/timesketch/blob/master/test_tools/test_events/sigma_events.csv) -* If you open a Github issue for an import issue, please indicate, what type of file you try to upload and what error message / stacktrace you have +- Is the celery worker running? +- Have a look at the celery logs. +- Is it a specific file that causes problems? +- What is the WebUI status of the import? +- Try switching from WebUI to the `import_client.py` to upload the same file +- Try to upload one of the [sample files](https://github.com/google/timesketch/blob/master/tests/test_events/sigma_events.csv) +- If you open a Github issue for an import issue, please indicate, what type of file you try to upload and what error message / stacktrace you have ### Issues importing a CSV file -* What are the headers of the CSV files -* Have the headers of the CSV file the minimum headers -* Is there an encoding issue in the CSV file -* If you tried to upload via web, try the import client and the other way around -* Check the celery logs -* Try to upload [This sample](https://github.com/google/timesketch/blob/master/test_tools/test_events/sigma_events.csv) -* If you open a Github issue, provide at least the header of your CSV and a few lines of content (please scramble PII) so it can be reproduced. +- What are the headers of the CSV files +- Have the headers of the CSV file the minimum headers +- Is there an encoding issue in the CSV file +- If you tried to upload via web, try the import client and the other way around +- Check the celery logs +- Try to upload [This sample](https://github.com/google/timesketch/blob/master/tests/test_events/sigma_events.csv) +- If you open a Github issue, provide at least the header of your CSV and a few lines of content (please scramble PII) so it can be reproduced. ### Issues importing Plaso file -* Which Plaso version is installed on the Timesketch server? (Run `psort.py --version` in the Timesketch docker instance -* Which Plaso version was used to create the Plaso file? -* Is the issue for both web upload and `import_client`? -* If you open a Github Issue, please indicate the Plaso version used to generate the file. +- Which Plaso version is installed on the Timesketch server? (Run `psort.py --version` in the Timesketch docker instance +- Which Plaso version was used to create the Plaso file? +- Is the issue for both web upload and `import_client`? +- If you open a Github Issue, please indicate the Plaso version used to generate the file. Try to run the following in the Docker container after the file was uploaded (but not successfully imported): @@ -112,13 +112,13 @@ grep "http_code:500" /var/log/nginx/access.log # to get all Error 500 If you started the webserver with docker, look in the console where you started: ```shell -docker exec -it timesketch gunicorn --reload -b 0.0.0.0:5000 --log-file --timeout 600 timesketch.wsgi:application +docker exec -it $CONTAINER_ID gunicorn --reload -b 0.0.0.0:5000 --log-file --timeout 600 timesketch.wsgi:application ``` -Or run the following where `timesketch` is the ID from your `timesketch` Docker container. +Or run the following where `$CONTAINER_ID` is the ID from your `timesketch-dev` or `timesketch` Docker container. ```shell -docker logs timesketch +docker logs $CONTAINER_ID ``` ### Timesketch / Celery worker @@ -126,19 +126,19 @@ docker logs timesketch See your console output if you started the workers with: ```shell -docker exec -it timesketch celery -A timesketch.lib.tasks worker --loglevel=debug +docker exec -it $CONTAINER_ID celery -A timesketch.lib.tasks worker --loglevel=debug ``` It is possible to see current running jobs with: ```shell -docker exec -it timesketch celery -A timesketch.lib.tasks inspect active +docker exec -it $CONTAINER_ID celery -A timesketch.lib.tasks inspect active ``` Which will give a list of tasks, individual tasks that are running can be then checked with ```shell -docker exec -it timesketch celery -A timesketch.lib.tasks inspect query_task $TASKID +docker exec -it $CONTAINER_ID celery -A timesketch.lib.tasks inspect query_task $TASKID ``` Where $TASKID is the id that was shown in the previous step. @@ -149,10 +149,10 @@ Where $TASKID is the id that was shown in the previous step. /var/log/opensearch ``` -Or run the following where `timesketch` is the ID from your `opensearch` Docker container. +Or run the following where `$CONTAINER_ID` is the ID from your `opensearch` Docker container. ```shell -docker logs timesketch +docker logs $CONTAINER_ID ``` ### PostgreSQL @@ -161,10 +161,10 @@ docker logs timesketch /var/log/postgresql/ ``` -Or run the following where `timesketch` is the ID from your `postgres` Docker container. +Or run the following where `$CONTAINER_ID` is the ID from your `postgres` Docker container. ```shell -docker logs timesketch +docker logs $CONTAINER_ID ``` ## CSRF token expire diff --git a/docs/guides/admin/upgrade.md b/docs/guides/admin/upgrade.md index 5d236c326b..603463349b 100644 --- a/docs/guides/admin/upgrade.md +++ b/docs/guides/admin/upgrade.md @@ -7,45 +7,42 @@ hide: When upgrading Timesketch you might need to migrate the database to use the latest database schema. This is how you do that. ## Backup you database (!) - -First you should backup your current database in case something goes wrong in the upgrade process. For PostgreSQL you do the following (Ref: ): +First you should backup your current database in case something goes wrong in the upgrade process. For PostgreSQL you do the following (Ref: https://www.postgresql.org/docs/9.1/static/backup.html): ### general postgres ```shell -sudo -u postgres pg_dump timesketch > ~/timesketch-db.sql -sudo -u postgres pg_dumpall > ~/timesketch-db-all.sql +$ sudo -u postgres pg_dump timesketch > ~/timesketch-db.sql +$ sudo -u postgres pg_dumpall > ~/timesketch-db-all.sql ``` ### docker postgres ```shell -sudo docker exec -t postgres pg_dump -U timesketch timesketch > ~/timesketch-db.sql -sudo docker exec -t postgres pg_dumpall -U timesketch > ~/timesketch-db-all.sql +$ sudo docker exec -t postgres pg_dump -U timesketch timesketch > ~/timesketch-db.sql +$ sudo docker exec -t postgres pg_dumpall -U timesketch > ~/timesketch-db-all.sql ``` ## Change to your Timesketch installation directory - (e.g. /opt/timesketch) ```shell -cd / +$ cd / ``` ## Upgrade the database schema - Have you backed up your database..? good. Let's upgrade the schema. First connect to the timesketch-web container: ```shell -docker compose exec timesketch-web /bin/bash +$ docker compose exec timesketch-web /bin/bash ``` While connected to the container: ```shell -git clone https://github.com/google/timesketch.git -cd timesketch/timesketch -tsctl db current +root@$ git clone https://github.com/google/timesketch.git +root@$ cd timesketch/timesketch +root@$ tsctl db current ``` If this command returns a value, then you can go ahead and upgrade the database. @@ -53,27 +50,26 @@ If this command returns a value, then you can go ahead and upgrade the database. In case you don't get any response back from the `db current` command you'll need to first find out revisions and fix a spot to upgrade from. ```shell -tsctl db history +root@$ tsctl db history ``` Find the last revision number you have upgraded the database too, and then issue ```shell -tsctl db stamp +root@$ tsctl db stamp ``` And now you are ready to upgrade. ```shell -tsctl db upgrade +root@$ tsctl db upgrade ``` ## Upgrade timesketch - Exit from the container (CTRL-D), then pull new versions of the docker images and upgrade Timesketch: ```shell -docker compose pull -docker compose down -docker compose up -d +$ docker compose pull +$ docker compose down +$ docker compose up -d ``` diff --git a/docs/guides/user/cli-client.md b/docs/guides/user/cli-client.md index b005edfc44..1f5e19c20e 100644 --- a/docs/guides/user/cli-client.md +++ b/docs/guides/user/cli-client.md @@ -51,13 +51,14 @@ Options: Commands: analyze Analyze timelines. config Configuration for this CLI tool. - events Manage events + events Manage event. import Import timeline. + intelligence Manage intelligence within a sketch. saved-searches Managed saved searches. - search Search and explore. + search Searches and explores events within a Timesketch sketch. + sigma Manage sigma rules. sketch Manage sketch. timelines Manage timelines. - ``` ## Configure @@ -645,4 +646,3 @@ Datasources: File on disk: /tmp/4c3c1c5c351b4db285453bff0ecad51e Error: ``` - diff --git a/docs/guides/user/notebook.md b/docs/guides/user/notebook.md new file mode 100644 index 0000000000..ed9ac4e16f --- /dev/null +++ b/docs/guides/user/notebook.md @@ -0,0 +1,131 @@ +--- +hide: + - footer +--- +# Timesketch Notebook + +The Timesketch notebook is a docker container that runs a customized version +of [picatrix](https://github.com/google/picatrix), designed to assist analysts +using Timesketch. + +## Installation + +The notebook is a docker container, so the first step is to make sure that +[docker is installed](https://docs.docker.com/engine/install/). + +If you did not install the docker desktop app you may also need to install +`docker-compose-plugin`, please follow the instructions +[here](https://docs.docker.com/compose/install/) (the version that is often +included in your source repo might be too old to properly setup the container). + +After installing docker the next step is to create a docker compose file, which +is used to bootstrap the docker commands. + +Save the following content to a file called `docker-compose.yml`: + +``` +version: '3' +services: + notebook: + container_name: notebook + image: us-docker.pkg.dev/osdfir-registry/timesketch/notebook:latest + ports: + - 127.0.0.1:8844:8844 + restart: on-failure + volumes: + - FOLDER_PATH:/usr/local/src/picadata/ +``` + +Replace the text `FOLDER_PATH` with a folder that can survive reboots. This is +the path to the folder where all notebooks will be saved to. The folder needs +to be readable and writeable by a user with uid/gid 1000:1000 (if this is run +on a Windows system the `FOLDER_PATH` can be set to something like +`C:\My Folder\`) + +Once the file has been saved, docker compose can be used to pull and start +the container: + +```shell +$ sudo docker compose pull +$ sudo docker compose up -d +``` + +The docker compose command will download the latest build and deploy the +TS docker container. + + +## Access the Container + +To be able to connect to the notebook connect to +[http://localhost:8844](http://localhost:8844), the password to access +the notebook is `timesketch`. + +### Troubleshooting Container + +In case there are any issues with the container it can be useful to take +a look at the container logs, which may give you hints into what may +be the issue. + +```shell +$ sudo docker container logs notebook +``` + +**TODO**: Complete this section. + +## Upgrade Container + +To update the container, use: + +```shell +$ sudo docker compose pull +$ sudo docker compose stop +$ sudo docker compose up -d +``` + +## Docker Desktop + +If you are using Docker desktop you can find the docker image, click +on the three dots and select pull. + +After manually updating the image the container needs to be recreated (using +the docker compose up command used earlier). + +## Credentials + +The docker container will have default credentials and configuration to connect +to the development server running in a container on the localhost, using the +user/pass combination of dev/dev. + +To connect to a different server, few options are available: + +1. Copy ~/.timesketchrc and ~/.timesketch.token to the docker using `docker cp`. +2. Run `ts_client = config.get_client(confirm_choices=True) and change all +values as questions come up. +3. Create a separate session using +```python +ts_client = config.get_client(config_section='myserver') +``` +4. The other option is to connect to the docker container: +```shell +$ sudo docker exec -it notebook /bin/bash +``` + +And manually craft the ~/.timesketchrc file. + +## Connect To Colab + +In order to connect to the docker container from colab, select the arrow +next to the `Connect` button, select `Connect to local runtime` and type +in the URL `http://localhost:8844/?token=timesketch` into the `Backend URL` +field and hit `CONNECT`. + +## Usage + +**TODO**: This section needs to be filled in. + +However in the meantime these sites can be of an assistance: + ++ [Discussion thread about the container](https://github.com/google/timesketch/discussions/1515) ++ [Beginners guide of Jupyter](https://www.dataquest.io/blog/jupyter-notebook-tutorial/) ++ [Test notebook](https://colab.research.google.com/github/google/timesketch/blob/master/notebooks/colab-timesketch-demo.ipynb) ++ [Jupyter tutorial](https://www.datacamp.com/community/tutorials/tutorial-jupyter-notebook) diff --git a/docs/guides/user/search-query-guide.md b/docs/guides/user/search-query-guide.md index af0327406d..fc1f080d8c 100644 --- a/docs/guides/user/search-query-guide.md +++ b/docs/guides/user/search-query-guide.md @@ -17,6 +17,7 @@ Data fields will vary depending on the source being uploaded, but here are some | Field | Description | Example query | | ---------------- | ---------------------------------------------- | -------------------------------------------- | | `message` | String with information about event | `message:”This is a message”` | +| `timestamp` | Timestamp as microseconds since Unix epoch | `timestamp:”363420000”` | | `datetime` | Date and time in ISO8601 format | `datetime:”2016-03-31T22:56:32+00:00”` | | `timestamp_desc` | String explaining what type of timestamp it is | `timestamp_desc:”Content Modification Time”` | diff --git a/end_to_end_tests/__init__.py b/end_to_end_tests/__init__.py index a1e547a805..fc1168e047 100644 --- a/end_to_end_tests/__init__.py +++ b/end_to_end_tests/__init__.py @@ -16,8 +16,10 @@ # Register all tests by importing them. # TODO: Re-enable this test. Temporarily disabled while debugging issues. # from . import agg_test +from . import cli_client_e2e_test from . import client_test from . import data_finder_test from . import graph_test from . import query_test from . import upload_test +from . import tsctl_test diff --git a/end_to_end_tests/cli_client_e2e_test.py b/end_to_end_tests/cli_client_e2e_test.py new file mode 100644 index 0000000000..b0994f0c17 --- /dev/null +++ b/end_to_end_tests/cli_client_e2e_test.py @@ -0,0 +1,102 @@ +# /usr/local/google/home/jaegeral/dev/timesketch/end_to_end_tests/cli_client_e2e_test.py +"""End to end tests for Timesketch CLI client commands.""" + +from click.testing import CliRunner + +from timesketch_cli_client.commands.sketch import sketch_group + +from . import interface +from . import manager + + +class E2ECliContextObject: + """A context object for running CLI client commands in E2E tests.""" + + def __init__(self, api_client, sketch_instance, output_format="text"): + self.api = api_client + self.sketch = sketch_instance # The active sketch for the commands + self.output_format = output_format + + +class CliClientE2ETest(interface.BaseEndToEndTest): + """End to end tests for the Timesketch CLI client.""" + + NAME = ( + "cli_client_e2e_test" # Sketch created by BaseEndToEndTest will have this name + ) + + def __init__(self): + """Initialize the test case.""" + super().__init__() # This initializes self.api and self.sketch + self.runner = CliRunner() + + def test_cli_sketch_list(self): + """Tests 'timesketch sketch list' using the CLI client's command group.""" + sketch_to_find = self.sketch + + # Prepare the context object for the CLI command. + # 'sketch list' uses ctx.obj.api and ctx.obj.output_format. + cli_ctx_obj = E2ECliContextObject( + api_client=self.api, + sketch_instance=sketch_to_find, + output_format="text", + ) + + result = self.runner.invoke(sketch_group, ["list"], obj=cli_ctx_obj) + + # Assertions + self.assertions.assertEqual( + result.exit_code, + 0, + f"CLI command 'sketch list' failed.\nOutput:\n{result.output}\n" + f"Exception:\n{result.exception}", + ) + self.assertions.assertIn( + sketch_to_find.name, + result.output, + f"Sketch name '{sketch_to_find.name}' not found in 'sketch list' output.", + ) + self.assertions.assertIn( + str(sketch_to_find.id), + result.output, + f"Sketch ID '{sketch_to_find.id}' not found in 'sketch list' output.", + ) + + def test_cli_sketch_describe(self): + """Tests 'timesketch sketch describe' using the CLI client's command group.""" + # self.sketch is the active sketch for this test. + active_sketch = self.sketch + + # Prepare the context object. + # 'sketch describe' uses ctx.obj.sketch and ctx.obj.output_format. + cli_ctx_obj = E2ECliContextObject( + api_client=self.api, + sketch_instance=active_sketch, + output_format="text", + ) + + # Invoke the 'describe' command. + result = self.runner.invoke(sketch_group, ["describe"], obj=cli_ctx_obj) + + # Assertions + self.assertions.assertEqual( + result.exit_code, + 0, + f"CLI command 'sketch describe' failed.\n" + f"Output:\n{result.output}\nException:\n{result.exception}", + ) + self.assertions.assertIn( + f"Name: {active_sketch.name}", + result.output, + "Sketch name not found or incorrect in 'sketch describe' output.", + ) + + self.assertions.assertIn( + f"Description: {active_sketch.description}", + result.output, + "Sketch description not found or incorrect in 'sketch describe' output.", + ) + + +# Register the new test class with the test manager +manager.EndToEndTestManager.register_test(CliClientE2ETest) diff --git a/end_to_end_tests/client_test.py b/end_to_end_tests/client_test.py index 9df0919d2c..1fcf285146 100755 --- a/end_to_end_tests/client_test.py +++ b/end_to_end_tests/client_test.py @@ -13,22 +13,24 @@ # limitations under the License. """End to end tests of Timesketch client functionality.""" +import uuid import json +import random +import os import time -import opensearchpy from timesketch_api_client import search -from . import interface, manager - -OPENSEARCH_HOST = "opensearch" -OPENSEARCH_PORT = 9200 +from . import interface +from . import manager class ClientTest(interface.BaseEndToEndTest): """End to end tests for client functionality.""" NAME = "client_test" + RULEID1 = str(uuid.uuid4()) + RULEID2 = str(uuid.uuid4()) def test_client(self): """Client tests.""" @@ -58,99 +60,42 @@ def test_client(self): continue self.assertions.assertTrue(bool(index.index_name)) - def test_direct_opensearch_single_index(self): - """Generate timeline from a single index""" + def test_direct_opensearch(self): + """Test injecting data into OpenSearch directly.""" index_name = "direct_testing" self.import_directly_to_opensearch( filename="evtx_direct.csv", index_name=index_name ) - sketch = self.api.create_sketch( + new_sketch = self.api.create_sketch( name="Testing Direct", description="Adding data directly from ES" ) context = "e2e - > test_direct_opensearch" - timeline = sketch.generate_timeline_from_es_index( + timeline_name = "Ingested Via Mechanism" + timeline = new_sketch.generate_timeline_from_es_index( es_index_name=index_name, - name="Ingested Via Mechanism", + name=timeline_name, provider="end_to_end_testing_platform", context=context, ) - _ = sketch.lazyload_data(refresh_cache=True) - self.assertions.assertEqual(len(sketch.list_timelines()), 1) - self.assertions.assertEqual(timeline.name, "Ingested Via Mechanism") + + _ = new_sketch.lazyload_data(refresh_cache=True) + self.assertions.assertEqual(len(new_sketch.list_timelines()), 1) + self.assertions.assertEqual(timeline.name, timeline_name) data_sources = timeline.data_sources self.assertions.assertEqual(len(data_sources), 1) data_source = data_sources[0] self.assertions.assertEqual(data_source.get("context", ""), context) - def test_direct_opensearch_with_alias(self): - """Test injecting data into OpenSearch directly.""" - alias_name = "index" - index_name = "index-00001" - - es = opensearchpy.OpenSearch( - [{"host": OPENSEARCH_HOST, "port": OPENSEARCH_PORT}], http_compress=True - ) - body = { - "mappings": { - "properties": { - "datetime": {"type": "date"}, - "timestamp_desc": { - "type": "text", - "fields": {"keyword": {"type": "keyword"}}, - }, - "message": {"type": "text"}, - "data_type": { - "type": "text", - "fields": {"keyword": {"type": "keyword"}}, - }, - "__ts_timeline_id": {"type": "long"}, - } - } - } - es.indices.create(index_name, body=body) - es.indices.put_alias(index=index_name, name=alias_name) - - self.import_directly_to_opensearch( - filename="sigma_events_timeline_id.csv", index_name=index_name - ) - - sketch = self.api.create_sketch( - name="Testing Direct", description="Adding data directly from ES" - ) - - context = "e2e - > test_direct_opensearch" - timelines = [] - for i in range(1, 4): - timelines.append( - sketch.generate_timeline_from_es_index( - es_index_name=index_name, - name=f"Timeline - {i}", - provider="end_to_end_testing_platform", - context=context, - ) - ) - - _ = sketch.lazyload_data(refresh_cache=True) - self.assertions.assertEqual(len(sketch.list_timelines()), 3) - - for i in range(1, 4): - self.assertions.assertEqual(timelines[i - 1].name, f"Timeline - {i}") - self.assertions.assertEqual( - sketch.get_timeline(timelines[i - 1].id).id, timelines[i - 1].id - ) - search_obj = search.Search(sketch) - search_obj.query_string = f"__ts_timeline_id:{i}" - self.assertions.assertEqual(len(search_obj.table), 1) - def test_sigmarule_create(self): """Create a Sigma rule in database""" - MOCK_SIGMA_RULE = """ + + MOCK_SIGMA_RULE = f""" title: Suspicious Installation of bbbbbb -id: 5266a592-b793-11ea-b3de-bbbbbb +id: {self.RULEID1} description: Detects suspicious installation of bbbbbb references: - https://rmusser.net/docs/ATT&CK-Stuff/ATT&CK/Discovery.html @@ -185,9 +130,9 @@ def test_sigmarule_create_get(self): """Client Sigma object tests.""" rule = self.api.create_sigmarule( - rule_yaml=""" + rule_yaml=f""" title: Suspicious Installation of eeeee -id: 5266a592-b793-11ea-b3de-eeeee +id: {self.RULEID2} description: Detects suspicious installation of eeeee references: - https://rmusser.net/docs/ATT&CK-Stuff/ATT&CK/Discovery.html @@ -209,17 +154,17 @@ def test_sigmarule_create_get(self): ) self.assertions.assertIsNotNone(rule) - rule = self.api.get_sigmarule(rule_uuid="5266a592-b793-11ea-b3de-eeeee") - rule.from_rule_uuid("5266a592-b793-11ea-b3de-eeeee") + rule = self.api.get_sigmarule(rule_uuid=self.RULEID2) + rule.from_rule_uuid(self.RULEID2) self.assertions.assertGreater(len(rule.attributes), 5) self.assertions.assertIsNotNone(rule) self.assertions.assertIn("Alexander", rule.author) self.assertions.assertIn("Alexander", rule.get_attribute("author")) - self.assertions.assertIn("b793-11ea-b3de-eeeee", rule.id) + self.assertions.assertIn(self.RULEID2, rule.id) self.assertions.assertIn("Installation of eeeee", rule.title) self.assertions.assertIn("zmap", rule.search_query) self.assertions.assertIn("shell:zsh:history", rule.search_query) - self.assertions.assertIn("sigmarules/5266a592", rule.resource_uri) + self.assertions.assertIn(self.RULEID2, rule.resource_uri) self.assertions.assertIn("installation of eeeee", rule.description) self.assertions.assertIn("high", rule.level) self.assertions.assertEqual(len(rule.falsepositives), 1) @@ -243,14 +188,14 @@ def test_sigmarule_remove(self): """Client Sigma delete tests. The test is called remove to avoid running it before the create test. """ - rule = self.api.get_sigmarule(rule_uuid="5266a592-b793-11ea-b3de-eeeee") + rule = self.api.get_sigmarule(rule_uuid=self.RULEID1) self.assertions.assertGreater(len(rule.attributes), 5) rule.delete() rules = self.api.list_sigmarules() self.assertions.assertGreaterEqual(len(rules), 1) - rule = self.api.get_sigmarule(rule_uuid="5266a592-b793-11ea-b3de-bbbbbb") + rule = self.api.get_sigmarule(rule_uuid=self.RULEID2) self.assertions.assertGreater(len(rule.attributes), 5) rule.delete() rules = self.api.list_sigmarules() @@ -356,5 +301,238 @@ def test_add_event_attributes_invalid(self): new_event["objects"]["existing_attr"], "original_value" ) + def test_create_sketch_empty_name(self): + """Test creating a sketch with an empty name.""" + with self.assertions.assertRaises(ValueError) as context: + self.api.create_sketch(name="", description="test_create_sketch") + self.assertions.assertIn("Sketch name cannot be empty", str(context.exception)) + + def test_archive_sketch(self): + """Test archiving and unarchiving a sketch.""" + sketch = self.api.create_sketch( + name="test_archive_sketch", description="test_archive_sketch" + ) + # check status before archiving + self.assertions.assertEqual(sketch.status, "new") + sketch.archive() + self.assertions.assertEqual(sketch.status, "archived") + sketch.unarchive() + self.assertions.assertEqual(sketch.status, "ready") + + def test_delete_sketch(self): + """Test deleting a sketch.""" + sketches = list(self.api.list_sketches()) + number_of_sketches = len(sketches) + + sketch = self.api.create_sketch( + name="test_delete_sketch", description="test_delete_sketch" + ) + + sketches = list(self.api.list_sketches()) + self.assertions.assertEqual(len(sketches), number_of_sketches + 1) + + # store sketch_id of the newly created sketch + sketch_id = sketch.id + + # check that sketch is in the sketch list + sketches = self.api.list_sketches() + found = False + for s in sketches: + if s.name == "test_delete_sketch": + found = True + + self.assertions.assertEqual(found, True) + + # delete sketch + sketch.delete() + + sketches = list(self.api.list_sketches()) + self.assertions.assertEqual(len(sketches), number_of_sketches) + # attempt to pull sketch + # breakpoint() + with self.assertions.assertRaises(RuntimeError): + self.api.get_sketch(sketch_id).name # pylint: disable=W0106 + + # test to delete a sketch that is archived + def test_delete_archived_sketch(self): + """Test deleting an archived sketch.""" + sketch = self.api.create_sketch( + name="test_delete_archived_sketch", + description="test_delete_archived_sketch", + ) + sketch.archive() + with self.assertions.assertRaises(RuntimeError) as context: + sketch.delete() + self.assertions.assertIn( + "Unable to delete an archived sketch, first unarchive then delete.", + str(context.exception), + ) + + def test_modify_sketch_name_description(self): + """Test modifying a sketch's name and description.""" + sketch = self.api.create_sketch( + name="test_modify_sletch_name_description", + description="test_modify_sletch_name_description", + ) + sketch.name = "new_name" + sketch.description = "new_description" + self.assertions.assertEqual(sketch.name, "new_name") + self.assertions.assertEqual(sketch.description, "new_description") + # check in the sketch list + sketches = self.api.list_sketches() + # find the right one in the sketch list + for s in sketches: + if s.name == "new_name": + sketch2 = s + break + else: + raise RuntimeError("Sketch not found") + + self.assertions.assertEqual(sketch2.name, "new_name") + self.assertions.assertEqual(sketch2.description, "new_description") + + def test_modify_sketch_with_empty_name(self): + """Test modifying a sketch with an empty name. + They should not be used, thus keeping the old names. + """ + sketch = self.api.create_sketch( + name="test_modify_sketch_with_empty_name", + description="test_modify_sketch_with_empty_name", + ) + sketch.name = "" + sketch.description = "" + + # values should not be changed + self.assertions.assertEqual(sketch.name, "test_modify_sketch_with_empty_name") + self.assertions.assertEqual( + sketch.description, "test_modify_sketch_with_empty_name" + ) + + def test_list_timelines(self): + """Test listing timelines in a sketch.""" + # Create a new sketch + sketch = self.api.create_sketch( + name="test_list_timelines", description="test_list_timelines" + ) + + # Import a timeline into the sketch + self.import_timeline("evtx.plaso", sketch=sketch) + + # List the timelines in the sketch + timelines = sketch.list_timelines() + + # Check that there is at least one timeline + self.assertions.assertGreaterEqual(len(timelines), 1) + + # Check that the timeline has a name + for timeline in timelines: + self.assertions.assertTrue(timeline.name) + + # Check that the timeline has an index name + for timeline in timelines: + self.assertions.assertTrue(timeline.index_name) + + # Check that the timeline has an ID + for timeline in timelines: + self.assertions.assertTrue(timeline.id) + + # Import a second timeline into the sketch + self.import_timeline("evtx_part.csv", sketch=sketch) + + _ = sketch.lazyload_data(refresh_cache=True) + + # List the timelines in the sketch + timelines = sketch.list_timelines() + + # Check that there are two timelines + self.assertions.assertEqual(len(timelines), 2) + + def test_delete_timeline(self): + """Test deleting a timeline. + This test verifies the following: + - A new sketch can be created. + - A timeline can be imported into the sketch. + - The timeline's name, index name, and index status are correct. + - The number of events in the sketch is correct + after importing the timeline. + - A second timeline can be imported into the sketch. + - The total number of events in the sketch is correct after + importing the second timeline. + - A timeline can be deleted. + - The number of events in the sketch is correct after deleting + a timeline. + - The number of timelines in the sketch is correct after + deleting a timeline. + Raises: + AssertionError: If any of the assertions fail. + RuntimeError: If the event creation fails. + RuntimeError: If the sketch is not found. + """ + + # create a new sketch + rand = random.randint(0, 10000) + sketch = self.api.create_sketch( + name=f"test_delete_timeline {rand}", description="test_delete_timeline" + ) + self.sketch = sketch + + file_path = ( + "/usr/local/src/timesketch/end_to_end_tests/test_data/sigma_events.jsonl" + ) + + self.import_timeline(file_path, index_name=rand, sketch=sketch) + timeline = sketch.list_timelines()[0] + # check that timeline was uploaded correctly + self.assertions.assertEqual(timeline.name, file_path) + self.assertions.assertEqual(timeline.index.name, str(rand)) + self.assertions.assertEqual(timeline.index.status, "ready") + self.assertions.assertEqual(len(sketch.list_timelines()), 1) + + events = sketch.explore("*", as_pandas=True) + self.assertions.assertEqual(len(events), 4) + + # second import + + file_path = "/tmp/second.csv" + + with open(file_path, "w", encoding="utf-8") as file_object: + file_object.write( + '"message","timestamp","datetime","timestamp_desc","data_type"\n' + ) + + for i in range(5): + # write a line with random values for message + string = ( + f'"CSV Count: {i} {rand}","123456789",' + '"2015-07-24T19:01:01+00:00","Write time","foobarcsv"\n' + ) + file_object.write(string) + + self.import_timeline("/tmp/second.csv", index_name="second", sketch=sketch) + os.remove(file_path) + # refresh data after import + _ = sketch.lazyload_data(refresh_cache=True) + + timeline = sketch.list_timelines()[0] + self.assertions.assertEqual(len(sketch.list_timelines()), 2) + + # Check that there are 9 (5+4) events in total + search_client = search.Search(sketch) + search_response = json.loads(search_client.json) + self.assertions.assertEqual(len(search_response["objects"]), 9) + + events = sketch.explore("*", as_pandas=True) + self.assertions.assertEqual(len(events), 9) + + # delete timeline 1 + # now it should be 5 events in one timeline + timeline.delete() + events = sketch.explore("*", as_pandas=True) + self.assertions.assertEqual(len(events), 5) + + # check number of timelines + _ = sketch.lazyload_data(refresh_cache=True) + self.assertions.assertEqual(len(sketch.list_timelines()), 1) + manager.EndToEndTestManager.register_test(ClientTest) diff --git a/end_to_end_tests/interface.py b/end_to_end_tests/interface.py index dbe82855e0..f9bbc3082a 100644 --- a/end_to_end_tests/interface.py +++ b/end_to_end_tests/interface.py @@ -15,8 +15,8 @@ import collections import inspect -import json import os +import json import time import traceback import unittest @@ -25,6 +25,7 @@ import opensearchpy import opensearchpy.helpers import pandas as pd + from timesketch_api_client import client as api_client from timesketch_import_client import importer @@ -253,7 +254,7 @@ def run_tests(self): print("Running test: {0:s} ...".format(test_name), end="", flush=True) try: test_func() - except Exception: + except Exception: # pylint: disable=broad-except # TODO: Change to logging module instead of prints print(traceback.format_exc()) self._counter["errors"] += 1 diff --git a/end_to_end_tests/manager.py b/end_to_end_tests/manager.py index beb4f6df9b..4d9a543278 100644 --- a/end_to_end_tests/manager.py +++ b/end_to_end_tests/manager.py @@ -47,7 +47,7 @@ def get_test(cls, test_name): Raises: KeyError: if the test is not registered. """ - + # pylint: disable=raise-missing-from try: test_class = cls._class_registry[test_name.lower()] except KeyError: diff --git a/end_to_end_tests/tsctl_test.py b/end_to_end_tests/tsctl_test.py new file mode 100644 index 0000000000..c3949a2016 --- /dev/null +++ b/end_to_end_tests/tsctl_test.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google Inc. All rights reserved. +# +# 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. +"""Tests for tsctl command-line tool.""" + +import os +import zipfile +import json +import csv +from click.testing import CliRunner +from timesketch.tsctl import cli +from . import interface +from . import manager + + +class TestTsctl(interface.BaseEndToEndTest): # Or inherit from BaseTest if applicable + """Tests for tsctl commands.""" + + NAME = "tsctl_test" + + def __init__(self): + """Initialize the test class and the runner.""" + super().__init__() + self.runner = CliRunner() + + def test_version_command(self): + """Tests the 'tsctl version' command.""" + # Invoke 'tsctl version' + result = self.runner.invoke(cli, ["version"]) + + # Assertions + self.assertions.assertEqual(result.exit_code, 0, f"CLI Error: {result.output}") + self.assertions.assertIn("Timesketch version:", result.output) + + def test_list_users_command(self): + """Tests the 'tsctl list-users' command.""" + # Invoke 'tsctl list-users' + result = self.runner.invoke(cli, ["list-users"]) + + self.assertions.assertEqual(result.exit_code, 0, f"CLI Error: {result.output}") + self.assertions.assertIn(interface.USERNAME, result.output) + + def test_list_users_status_command(self): + """Tests the 'tsctl list-users --status' command.""" + # Invoke 'tsctl list-users --status' + result = self.runner.invoke(cli, ["list-users", "--status"]) + + # Assertions + self.assertions.assertEqual(result.exit_code, 0, f"CLI Error: {result.output}") + self.assertions.assertIn(interface.USERNAME, result.output) + # Check for the status indicator (active: True/False) + self.assertions.assertIn("active: True)", result.output) + + def test_export_sketch_command(self): + """Tests the 'tsctl export-sketch' command.""" + # Ensure the default sketch for the test has some data + # Using 'sigma_events.csv' which is known to have 4 events + header + self.import_timeline("sigma_events.csv") + + sketch_id = self.sketch.id + sketch_name = self.sketch.name + output_filename = f"test_sketch_{sketch_id}_export.zip" + + # Invoke 'tsctl export-sketch --filename ' + result = self.runner.invoke( + cli, ["export-sketch", str(sketch_id), "--filename", output_filename] + ) + + # Assertions for command execution + self.assertions.assertEqual(result.exit_code, 0, f"CLI Error: {result.output}") + self.assertions.assertTrue( + os.path.exists(output_filename), f"Export file {output_filename} not found" + ) + + # Assertions for zip file content + with zipfile.ZipFile(output_filename, "r") as zipf: + self.assertions.assertIn("metadata.json", zipf.namelist()) + self.assertions.assertIn("events.csv", zipf.namelist()) + + with zipf.open("metadata.json") as meta_file: + metadata = json.load(meta_file) + self.assertions.assertEqual(metadata.get("sketch_id"), sketch_id) + self.assertions.assertEqual(metadata.get("name"), sketch_name) + + with zipf.open("events.csv") as events_file: + # Read CSV content (decode bytes to string for csv.reader) + csv_content = events_file.read().decode("utf-8") + reader = csv.reader(csv_content.splitlines()) + rows = list(reader) + self.assertions.assertEqual(len(rows), 5) # 1 header + 4 events + + # Clean up + if os.path.exists(output_filename): + os.remove(output_filename) + + +manager.EndToEndTestManager.register_test(TestTsctl) diff --git a/end_to_end_tests/upload_test.py b/end_to_end_tests/upload_test.py index b444bd71f7..5658b6e4fa 100755 --- a/end_to_end_tests/upload_test.py +++ b/end_to_end_tests/upload_test.py @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. """End to end tests of Timesketch upload functionality.""" -import json import os import random +import json from timesketch_api_client import search - -from . import interface, manager +from . import interface +from . import manager class UploadTest(interface.BaseEndToEndTest): @@ -48,7 +48,7 @@ def test_normal_upload_json(self): self.assertions.assertEqual(timeline.index.name, str(rand)) self.assertions.assertEqual(timeline.index.status, "ready") - events = sketch.explore("*") + events = sketch.explore("*", as_pandas=True) self.assertions.assertEqual(len(events), 4) def test_large_upload_jsonl(self): @@ -66,7 +66,7 @@ def test_large_upload_jsonl(self): with open(file_path, "w", encoding="utf-8") as file_object: for i in range(4123): - string = f'{{"message":"Count {i} {rand}","timestamp":"123456789","datetime":"2015-07-24T19:01:01+00:00","timestamp_desc":"Write time","data_type":"foobarjson"}}\n' + string = f'{{"message":"Count {i} {rand}","timestamp":"123456789","datetime":"2015-07-24T19:01:01+00:00","timestamp_desc":"Write time","data_type":"foobarjson"}}\n' # pylint: disable=line-too-long file_object.write(string) self.import_timeline("/tmp/large.jsonl", index_name=rand, sketch=sketch) @@ -84,7 +84,7 @@ def test_large_upload_jsonl(self): self.assertions.assertEqual(len(search_obj.table), 4123) # check that the number of events is correct with a different method - events = sketch.explore("data_type:foobarjson") + events = sketch.explore("data_type:foobarjson", as_pandas=True) self.assertions.assertEqual(len(events), 4123) def test_upload_jsonl_mapping_exceeds_limit(self): @@ -137,7 +137,9 @@ def test_upload_jsonl_mapping_exceeds_limit(self): # check that timeline threw the correct error self.assertions.assertEqual(timeline.name, file_path) self.assertions.assertEqual(timeline.index.name, str(rand)) - self.assertions.assertEqual(timeline.index.status, "fail") + self.assertions.assertEqual( + timeline.data_sources[0]["status"][0]["status"], "fail" + ) self.assertions.assertIn( "OPENSEARCH_MAPPING_UPPER_LIMIT", timeline.data_sources[0]["error_message"] ) @@ -157,7 +159,7 @@ def test_very_large_upload_jsonl(self): with open(file_path, "w", encoding="utf-8") as file_object: for i in range(74251): - string = f'{{"message":"Count {i} {rand}","timestamp":"123456789","datetime":"2015-07-24T19:01:01+00:00","timestamp_desc":"Write time","data_type":"foobarjsonverlarge"}}\n' + string = f'{{"message":"Count {i} {rand}","timestamp":"123456789","datetime":"2015-07-24T19:01:01+00:00","timestamp_desc":"Write time","data_type":"foobarjsonverlarge"}}\n' # pylint: disable=line-too-long file_object.write(string) self.import_timeline(file_path, index_name=rand, sketch=sketch) @@ -183,7 +185,9 @@ def test_very_large_upload_jsonl(self): self.assertions.assertEqual(len(search_obj.table), 74251) # check that the number of events is correct with a different method - events = sketch.explore("data_type:foobarjsonverlarge", max_entries=100000) + events = sketch.explore( + "data_type:foobarjsonverlarge", as_pandas=True, max_entries=100000 + ) self.assertions.assertEqual(len(events), 74251) def test_large_upload_csv(self): @@ -228,7 +232,7 @@ def test_large_upload_csv(self): self.assertions.assertEqual(len(search_obj.table), 3251) # check that the number of events is correct with a different method - events = sketch.explore("data_type:foobarcsv") + events = sketch.explore("data_type:foobarcsv", as_pandas=True) self.assertions.assertEqual(len(events), 3251) def test_large_upload_csv_over_flush_limit(self): @@ -281,9 +285,45 @@ def test_large_upload_csv_over_flush_limit(self): self.assertions.assertEqual(len(search_obj.table), 73251) # check that the number of events is correct with a different method - events = sketch.explore("data_type:73kcsv", max_entries=100000) + events = sketch.explore("data_type:73kcsv", as_pandas=True, max_entries=100000) self.assertions.assertEqual(len(events), 73251) + def test_datetime_out_of_normal_range_in_csv(self): + """Test uploading a file with events from way back and some + in a distant future. This test can reveal edge cases that might occur + when tools produce a "fake" datetime value""" + + rand = str(random.randint(0, 10000)) + sketch = self.api.create_sketch( + name=f"datetime_out_of_normal_range_in_csv_{rand}" + ) + self.sketch = sketch + file_path = "/usr/local/src/timesketch/tests/test_events/validate_time_out_of_range.csv" # pylint: disable=line-too-long + self.import_timeline(file_path, index_name=rand, sketch=sketch) + timeline = sketch.list_timelines()[0] + # check that timeline was uploaded correctly + self.assertions.assertEqual(timeline.name, file_path) + self.assertions.assertEqual(timeline.index.name, str(rand)) + self.assertions.assertEqual(timeline.index.status, "ready") + + # Search for the very old event + search_obj = search.Search(sketch) + search_obj.query_string = "data_type:csv_very_old_event" + search_obj.commit() + self.assertions.assertEqual(len(search_obj.table), 1) + self.assertions.assertEqual( + "1601-01-01" in str(search_obj.table["datetime"]), True + ) + + # Search for future event check if datetime value is in the result + search_obj2 = search.Search(sketch) + search_obj2.query_string = "data_type:csv_very_future_event" + search_obj2.commit() + self.assertions.assertEqual(len(search_obj2.table), 1) + self.assertions.assertEqual( + "2227-12-31" in str(search_obj2.table["datetime"]), True + ) + def test_csv_different_timestamps(self): """Test uploading a timeline with different precision of timestamps.""" @@ -341,15 +381,15 @@ def test_csv_different_timestamps(self): self.assertions.assertEqual(len(search_obj.table), 3) # check that the number of events is correct with a different method - events = sketch.explore("data_type:timestamptest") + events = sketch.explore("data_type:timestamptest", as_pandas=True) self.assertions.assertEqual(len(events), 3) # check that events with no timestamp - events = sketch.explore("data_type:no_timestamp") + events = sketch.explore("data_type:no_timestamp", as_pandas=True) self.assertions.assertEqual(len(events), 1) # check number of events with no datetime - events = sketch.explore("data_type:no_datetime") + events = sketch.explore("data_type:no_datetime", as_pandas=True) self.assertions.assertEqual(len(events), 1) diff --git a/importer_client/python/timesketch_import_client/helper.py b/importer_client/python/timesketch_import_client/helper.py index cff1db6d37..83f142f40b 100644 --- a/importer_client/python/timesketch_import_client/helper.py +++ b/importer_client/python/timesketch_import_client/helper.py @@ -92,7 +92,7 @@ def add_config(self, file_path): "Unable to read config file since it does not produce a dict" ) - if not all([isinstance(x, dict) for x in config.values()]): + if not all(isinstance(x, dict) for x in config.values()): raise ValueError( "The config needs to a dict that contains other dict attributes." ) diff --git a/importer_client/python/timesketch_import_client/importer.py b/importer_client/python/timesketch_import_client/importer.py index b771ffba65..0318890983 100644 --- a/importer_client/python/timesketch_import_client/importer.py +++ b/importer_client/python/timesketch_import_client/importer.py @@ -25,7 +25,9 @@ import numpy import pandas -from timesketch_api_client import definitions, timeline + +from timesketch_api_client import timeline +from timesketch_api_client import definitions from timesketch_api_client.error import UnableToRunAnalyzer from timesketch_import_client import utils @@ -120,7 +122,7 @@ def _fix_dict(self, my_dict): * All keys that start with an underscore ("_") are removed. Args: - my_dict: a dictionary that may be missing few fields needed + my_dict (dict): a dictionary that may be missing few fields needed for Timesketch. """ if "message" not in my_dict: @@ -168,7 +170,7 @@ def _fix_data_frame(self, data_frame): """Returns a data frame with added columns for Timesketch upload. Args: - data_frame: a pandas data frame. + data_frame (DataFrame): a pandas data frame. Returns: A pandas data frame with added columns needed for Timesketch. @@ -211,7 +213,7 @@ def _fix_data_frame(self, data_frame): break except ValueError as e: logger.info( - "Unable to convert timestamp in column: " "%s, error %s", + "Unable to convert timestamp in column: %s, error %s", column, e, ) @@ -225,9 +227,12 @@ def _fix_data_frame(self, data_frame): ) else: try: - date = pandas.to_datetime(data_frame["datetime"], utc=True) + # Use format='mixed' for robust parsing of varied datetime strings + date = pandas.to_datetime( + data_frame["datetime"], utc=True, format="mixed" + ) data_frame["datetime"] = date.dt.strftime("%Y-%m-%dT%H:%M:%S%z") - except Exception: + except Exception: # pylint: disable=broad-except logger.error( "Unable to change datetime, is it correctly formatted?", exc_info=True, @@ -263,9 +268,9 @@ def _upload_data_buffer(self, end_stream, retry_count=0): """Upload data to Timesketch. Args: - end_stream: boolean indicating whether this is the last chunk of + end_stream (bool): boolean indicating whether this is the last chunk of the stream. - retry_count: optional int that is only set if this is a retry + retry_count (int): optional int that is only set if this is a retry of the upload. Raises: @@ -299,7 +304,7 @@ def _upload_data_buffer(self, end_stream, retry_count=0): if retry_count >= self.DEFAULT_RETRY_LIMIT: raise RuntimeError( "Error uploading data: [{0:d}] {1!s} {2!s}, " - "index {3:s}".format( + "index {3!s}".format( response.status_code, response.reason, response.text, @@ -334,10 +339,10 @@ def _upload_data_frame(self, data_frame, end_stream, retry_count=0): """Upload data to Timesketch. Args: - data_frame: a pandas DataFrame with the content to upload. - end_stream: boolean indicating whether this is the last chunk of + data_frame (DataFrame): a pandas DataFrame with the content to upload. + end_stream (bool): boolean indicating whether this is the last chunk of the stream. - retry_count: optional int that is only set if this is a retry + retry_count (int): optional int that is only set if this is a retry of the upload. Raises: @@ -396,7 +401,7 @@ def _upload_binary_file(self, file_path): """Upload binary data to Timesketch, potentially chunking it up. Args: - file_path: a full path to the file that is about to be uploaded. + file_path (str): a full path to the file that is about to be uploaded. """ file_size = os.path.getsize(file_path) @@ -421,10 +426,11 @@ def _upload_binary_file(self, file_path): data["context"] = self._upload_context if file_size <= self._threshold_filesize: - file_dict = {"file": open(file_path, "rb")} - response = self._sketch.api.session.post( - self._resource_url, files=file_dict, data=data - ) + with open(file_path, "rb") as fh: + file_dict = {"file": fh} + response = self._sketch.api.session.post( + self._resource_url, files=file_dict, data=data + ) else: chunks = int(math.ceil(float(file_size) / self._threshold_filesize)) data["chunk_total_chunks"] = chunks @@ -434,12 +440,12 @@ def _upload_binary_file(self, file_path): data["chunk_index"] = index start = self._threshold_filesize * index data["chunk_byte_offset"] = start - fh = open(file_path, "rb") - fh.seek(start) - binary_data = fh.read(self._threshold_filesize) - file_stream = io.BytesIO(binary_data) - file_stream.name = file_path - file_dict = {"file": file_stream} + with open(file_path, "rb") as fh: + fh.seek(start) + binary_data = fh.read(self._threshold_filesize) + file_stream = io.BytesIO(binary_data) + file_stream.name = file_path + file_dict = {"file": file_stream} retry_count = 0 while True: @@ -498,14 +504,15 @@ def add_data_frame(self, data_frame, part_of_iter=False): """Add a data frame into the buffer. Args: - data_frame: a pandas data frame object to add to the buffer. - part_of_iter: if it is expected that this function is called + data_frame (DataFrame): a pandas data frame object to add to the buffer. + part_of_iter (bool): if it is expected that this function is called as part of an iterator, or that many data frames may be added to the importer set to True, defaults to False. Raises: ValueError: if the data frame does not contain the correct columns for Timesketch upload. + TypeError: if the entry is not a DataFrame. """ self._ready() @@ -564,7 +571,7 @@ def add_dict(self, entry): """Add an entry into the buffer. Args: - entry: a dict object to add to the buffer. + entry (dict): a dict object to add to the buffer. Raises: TypeError: if the entry is not a dict. @@ -595,7 +602,7 @@ def add_excel_file(self, filepath, **kwargs): """Add a Microsoft Excel sheet to importer. Args: - filepath: full file path to a XLS or XLSX file to add to the + filepath (str): full file path to a XLS or XLSX file to add to the importer. kwargs: Other parameters can be passed in that match the @@ -641,8 +648,8 @@ def add_file(self, filepath, delimiter=","): """Add a CSV, JSONL or a PLASO file to the buffer. Args: - filepath: the path to the file to add. - delimiter: if this is a CSV file then a delimiter can be defined. + filepath (str): the path to the file to add. + delimiter (str): if this is a CSV file then a delimiter can be defined. Raises: TypeError: if the entry does not fulfill requirements. @@ -688,15 +695,15 @@ def add_file(self, filepath, delimiter=","): else: raise TypeError( - "File needs to have a file extension of: .csv, .jsonl or " ".plaso" + "File needs to have a file extension of: .csv, .jsonl or .plaso" ) def add_json(self, json_entry, column_names=None): """Add an entry that is in a JSON format. Args: - json_entry: a single entry encoded in JSON. - column_names: a list of column names if the JSON object + json_entry (str): a single entry encoded in JSON. + column_names (list): a list of column names if the JSON object is a list as an opposed to a dict. Raises: @@ -886,6 +893,7 @@ def __enter__(self): self._reset() return self + # pylint: disable=unused-argument def __exit__(self, exception_type, exception_value, traceback): """Make it possible to use "with" statement.""" self.close() diff --git a/importer_client/python/timesketch_import_client/importer_test.py b/importer_client/python/timesketch_import_client/importer_test.py index 2be88da126..15da7a7f5c 100644 --- a/importer_client/python/timesketch_import_client/importer_test.py +++ b/importer_client/python/timesketch_import_client/importer_test.py @@ -16,9 +16,9 @@ import json import unittest - import mock import pandas + from timesketch_api_client.error import UnableToRunAnalyzer from . import importer @@ -178,6 +178,7 @@ def test_adding_json(self): streamer.flush() self._run_all_tests(streamer.columns, streamer.lines) + # pylint: disable=protected-access def test_fix_data_frame(self): """Test fixing a data frame. create a pandas dataframe with timestamp, datetime, message and data_type @@ -237,6 +238,7 @@ def test_fix_data_frame_precision_timestamp(self): ) self.assertIs("1331698658276340" in fixed_frame["timestamp"].values, True) + # pylint: enable=protected-access def _run_all_tests(self, columns, lines): """Run all tests on the result set of a streamer.""" # The first line is the column line. diff --git a/importer_client/python/timesketch_import_client/utils.py b/importer_client/python/timesketch_import_client/utils.py index 0b1bcb6939..2bd1007ac6 100644 --- a/importer_client/python/timesketch_import_client/utils.py +++ b/importer_client/python/timesketch_import_client/utils.py @@ -28,6 +28,7 @@ [ "timestamp_desc", "time", + "timestamp", "data_type", "datetime", "source_short", diff --git a/importer_client/python/tools/timesketch_importer.py b/importer_client/python/tools/timesketch_importer.py index eb6645b008..4b26705d11 100644 --- a/importer_client/python/tools/timesketch_importer.py +++ b/importer_client/python/tools/timesketch_importer.py @@ -664,8 +664,8 @@ def main(args=None): if status in ("archived", "failed", "fail"): print("[FAIL]") print( - "Unable to index timeline {0:s}, reason: {1:s}".format( - timeline.description, timeline.status + "Unable to index timeline (ID: {0:d}), reason: {1:s}".format( + timeline.id, timeline.status ) ) return diff --git a/mkdocs.yml b/mkdocs.yml index 71a6b7d24b..3733fc78b9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,6 +37,7 @@ nav: - Admin CLI: guides/admin/admin-cli.md - Context Links: guides/admin/context-links.md - LLM Features: guides/admin/llm-features.md + - DFIQ Templates: guides/admin/load-dfiq.md - Developers: - Getting started: developers/getting-started.md - Frontend development: developers/frontend-development.md diff --git a/notebooks/MUS2019_CTF.ipynb b/notebooks/MUS2019_CTF.ipynb new file mode 100644 index 0000000000..19dabf673c --- /dev/null +++ b/notebooks/MUS2019_CTF.ipynb @@ -0,0 +1,1182 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "MUS2019-CTF.ipynb", + "provenance": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2y1Dij2Z7C4n" + }, + "source": [ + "# Magnet User Summit CTF 2019\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V3DWqc_275Jm" + }, + "source": [ + "The folks at [Magnet Forensics](https://www.magnetforensics.com/) had a [conference](https://magnetusersummit.com/) recently, and as part of it they put together a digital forensics-themed Capture the Flag competition. I wasn't able to attend, but thankfully they [released the CTF online](https://www.hecfblog.com/2019/04/daily-blog-657-mus2019-dfir-ctf-open-to.html) a few days after the live competition ended. \n", + "\n", + "It looked like a lot of fun and I wanted to take a crack at it using the open source tools we use/build here at Google. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1_pWpmTdnYJM" + }, + "source": [ + "## Forensics Preprocessing" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2Hph_KETIvOT" + }, + "source": [ + "I'm going to focus on how to find the answers to the CTF questions after all the processing has been done. I'll quickly summarize the processing steps I did to get to the state when I pick up my walkthrough.\n", + "\n", + "I started off by processing the provided E01 image with a basic log2timeline command; nothing special added:\n", + "\n", + "\n", + "```\n", + "log2timeline.py MUS2019-CTF.plaso MUS-CTF-19-DESKTOP-001.E01\n", + "```\n", + "\n", + "Once that finished, I went to [Timesketch](https://github.com/google/timesketch), made a new sketch, and uploaded the MUS2019-CTF.plaso file I just made. The *.plaso* file is a database containing the results of my log2timeline run; Timesketch can read it and provide a nice, collaborative interface for reviewing and exploring that data.\n", + "\n", + "Most of what I'm going to show you is done in Colab by accessing the Timesketch API in Python. You can do most of the steps in the Timesketch web interface directly, but I wanted to demonstrate how you can use Python, Colab, Timesketch, and Plaso together to work a case. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w-UPKnDLnbBF" + }, + "source": [ + "## Timesketch & Colab Setup\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0dmFr3P_9Ao7" + }, + "source": [ + "First, if you want to run this notebook and play along, click the 'Connect' button at the top right of the page. The [Timesketch GitHub](https://github.com/google/timesketch) has Colab ([Timesketch and Colab](https://colab.research.google.com/github/google/timesketch/blob/master/notebooks/colab-timesketch-demo.ipynb)) that walks through how to install, connect, and explore a Sketch using Colab. Please check it out if you want a more thorough explanation of the setup; I'm just going to show the commands you need to run to get it working: " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h35lMbAxIeYE" + }, + "source": [ + "# Install the TimeSketch API client if you don't have it\n", + "!pip install timesketch-api-client\n", + "\n", + "# Import some things we'll need\n", + "from timesketch_api_client import config\n", + "from timesketch_api_client import search\n", + "import pandas as pd\n", + "pd.options.display.max_colwidth = 60" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ph1jGHR5JjZo" + }, + "source": [ + "### Connect to Timesketch" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i5JCNPkL87Cq" + }, + "source": [ + "By default, this will connect to the public demo Timesketch server, which [David Cowen](https://twitter.com/HECFBlog) has graciously allowed to host a copy of the Plaso timeline of the MUS2019-CTF. Thanks Dave!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dqwwIBOpJfZi", + "cellView": "form" + }, + "source": [ + "#@title Client Information \n", + "# @markdown In order to connect to Timesketch you need to first get a Timesketch object, which will require you to answer\n", + "# @markdown some questions the first time you execute this code. The answers are:\n", + "# @markdown + **auth_mode**: timesketch (username/pwd combination)\n", + "# @markdown + **host_uri**: https://demo.timesketch.org\n", + "# @markdown + **username**: demo\n", + "# @markdown + **password**: demo\n", + "\n", + "ts_client = config.get_client(confirm_choices=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OZ4CahZZPjht" + }, + "source": [ + "Now that we've connected to the Timesketch server, we need to select the Sketch that has the CTF timeline. \n", + "\n", + "First we'll list the available sketches, then print their names:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vsEZI45porba" + }, + "source": [ + "sketches = ts_client.list_sketches()\n", + "ctf = None\n", + "for sketch in sketches:\n", + " print('[{0:d}] {1:s}'.format(sketch.id, sketch.name))\n", + " if sketch.name == 'MUS2019 CTF':\n", + " ctf = sketch" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E6RX0jqzQrRq" + }, + "source": [ + "Then we'll select the MUS2019-CTF sketch (shown as sketch 3 above; you can change the number below to select a different sketch):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hvCl6L7ZQrsZ" + }, + "source": [ + "print(ctf.name)\n", + "print(ctf.description)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4P9vvN2KWRjX" + }, + "source": [ + "Lastly, I'll briefly explain a few paramters of the **explore** function, which we'll use heavily when answering questions.\n", + "\n", + ".explore() is how we send queries to Timesketch and get results back. **query_string**, **return_fields**, and **as_pandas** are the main parameters I'll be using:\n", + " - query_string: This is the same as the query you'd enter if you were using the Timesketch web interface.\n", + " - return_fields: Here we specify what fields we want back from Timesketch. This is where we can get really specific using Colab and only get the things we're interested in (which varies depending on what data types we're expecting back).\n", + " - as_pandas: This just a boolen value which tells Timesketch to return a [Pandas DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html), rather than a dictionary. We'll have this set to True in all our queries, since DataFrames are awesome!\n", + "\n", + "Okay, enough setup. Let's get to answering questions!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tzvfE55GLKhB" + }, + "source": [ + "# Questions\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Pfy7e0iO9MJK" + }, + "source": [ + "![Basic - Desktop Questions](https://dfir.blog/content/images/2019/04/MUS2019-CTF-Basic-Desktop.png)\n", + "\n", + "I grouped the questions from the 'Basic - Desktop' section into three categories: NTFS, TeamViewer, and Registry." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SBtoNqZcp_Oi" + }, + "source": [ + "## NTFS Questions\n", + "This first set of questions relate to aspects of NTFS: MFT entries, sequence numbers, USN entries, and VSNs." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t4G6-lVUqN_V" + }, + "source": [ + "As a little refresher, the 64-bit **file reference address** (or number) is made up of the **MFT entry** (48 bits) and **sequence** (16 bits) numbers. We often see this represented as something like 1234-2, with 1234 being the MFT entry number and 2 being the sequence number. Plaso calls the MFT entry number the **inode**, since that's the more generic term that applies across file systems." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aVcSxh925V2T" + }, + "source": [ + "### Q: What is the name of the file associated with MFT entry number 102698?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m6apzEsfAGeo" + }, + "source": [ + "Since Plaso parses out the MFT entry (or as it calls it, inode) into its own field, let's do a query for all records with that value:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0n6k7v-ioy4_" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'inode:102698'\n", + "search_obj.return_fields='datetime,timestamp_desc,data_type,inode,filename'\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','inode','filename']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zuBoWImjAjs-" + }, + "source": [ + "Multiple results, as is expected since Plaso creates multiple records for different types of timestamps, but they all point to the same filename: **/Users/Administrator/Downloads/TeamViewer_Setup.exe**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JY3n9O60hdf8" + }, + "source": [ + "ts_results.filename.unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RPH7R0tKtLXn" + }, + "source": [ + "### Q: What is the file name that represented MFT entry 60725 with a sequence number of 10?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lHvfLumPlC5J" + }, + "source": [ + "The quick way to answer this is to just search for the MFT entry number (60725) and look for references to sequence number 10 in the message field:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "idzQZADYj8LF" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = '60725'\n", + "search_obj.return_fields='datetime,timestamp_desc,data_type,filename,message'\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','filename','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lEAo1lLcUeBb" + }, + "source": [ + "That's a bunch of rows, so let's filter it down by searching for messages that contain '60725-10':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iPCYySiEVB6P" + }, + "source": [ + "ts_results[ts_results.message.str.contains('60725-10')]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShIpZoBRV-xi" + }, + "source": [ + "That filename is really long and cut off; let's just select that field, then deduplicate using set():" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7xRO5-FFV_KN" + }, + "source": [ + "set(ts_results[ts_results.message.str.contains('60725-10')].filename)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VX8kLLl4ltAI" + }, + "source": [ + "Another way to solve this is to query for the file reference number directly. That's not as easy as it sounds, since Plaso stores it in the hex form ([I'm working on fixing that](https://github.com/log2timeline/plaso/issues/2453)). We can work with that though! \n", + "\n", + "Let's do the same query as above, but add the file_reference field:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qzemkUIAl-dX" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = '60725'\n", + "search_obj.return_fields='datetime,timestamp_desc,data_type,file_reference,filename,message'\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','file_reference','filename','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ujdlJk_a9Hxo" + }, + "source": [ + "The *file_reference* value is not the format we want, since it's hard to tell what the sequence number is. We can convert it to a more useful form though: " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qM4QlMgqmQRk" + }, + "source": [ + "# Drop any rows with NaN, since they aren't what we're looking for and will \n", + "# break the below function.\n", + "ts_results = ts_results.dropna()\n", + "pd.options.display.max_colwidth = 110\n", + "\n", + "# Replace the file_reference hex value with the human-readable MFT-Seq version. \n", + "# This is basically what Plaso does to display the result in the 'message' \n", + "# string we searched for. \n", + "ts_results['file_reference'] = ts_results['file_reference'].map(\n", + " lambda x: '{0:d}-{1:d}'.format(int(x) & 0xffffffffffff, int(x) >> 48))\n", + "ts_results[['datetime','timestamp_desc','data_type','file_reference','filename']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5zq9iqSJ9bA6" + }, + "source": [ + "There. Now we have the file_reference number in an easier-to-read format, and the history of all filenames that MFT entry 60725 has had! It's easy to look for the entry with a sequence number of 10 and get our answer." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hoj0JdKQrDru" + }, + "source": [ + "### Q: Which file name represents the USN record where the USN number is 546416480?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tDnlbF-8rfIF" + }, + "source": [ + "Like other questions, the quick, generic way to answer is to just search for the unique detail; in this case, search in Timesketch for '546416480'. I'll show the more targeted way below, but it's pretty simple:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lPObip1NrOtn" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'update_sequence_number:546416480'\n", + "search_obj.return_fields='datetime,timestamp_desc,data_type,update_sequence_number,filename'\n", + "ts_results = search_obj.table\n", + "ts_results.shape\n", + "#ts_results[['datetime','timestamp_desc','data_type','update_sequence_number','filename']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TfRrngTvysQi" + }, + "source": [ + "### Q: What is the MFT sequence number associated with the file \"\\Users\\Administrator\\Desktop\\FTK_Imager_Lite_3.1.1\\FTK Imager.exe\"?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xq0HG3CV2s1s" + }, + "source": [ + "We'll handle this question like other ones involving the file reference address, except in this case we first need to find the MFT entry number (or inode) from the file name. Searching for the whole file path in Timesketch is problematic (slashes among other things), so let's search for the file name and then verify the path is right:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lvxp9ltq0plT" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'FTK Imager.exe'\n", + "search_obj.return_fields='datetime,timestamp_desc,data_type,inode,message,filename'\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','inode','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MZ14rd0f3rCC" + }, + "source": [ + "In the second row of the results, we can find the correct path we're looking for in the message and see that the corresponding inode is 99916. We could do another search, similar to how we answered other questions... or we could just look down a few rows for a USN entry that shows: \"FTK Imager.exe File reference: 99916-**4**\". There's the answer!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s3GAl6TTjTS9" + }, + "source": [ + "ts_results[\n", + " ~ts_results.filename.isna() & (\n", + " ts_results.filename.str.contains(r'Users\\\\Administrator\\\\Desktop\\\\FTK_Imager_Lite_3.1.1\\\\FTK Imager.exe'))][['filename', 'inode']].drop_duplicates()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VjF1NkzwsROK" + }, + "source": [ + "### Q: What is the Volume Serial Number of the Desktop's OS volume?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3d-el0ezsoQi" + }, + "source": [ + "I know the VSN can be found in multiple places, but the first one I thought of was as part of a Prefetch file, so let's do it that way. \n", + "\n", + "I'll search for all 'volume creation' Prefetch records, since I don't really care about which particular one, beyond that it's from the OS drive. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1gt8_VMxsQ77" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'data_type:\"windows:volume:creation\"'\n", + "search_obj.return_fields='datetime,timestamp_desc,data_type,device_path,hostname,serial_number,message'\n", + "ts_results = search_obj.table\n", + "\n", + "pd.options.display.max_colwidth = 70\n", + "ts_results[['datetime','timestamp_desc','data_type','device_path','hostname','serial_number','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KUtZWLKmuWet" + }, + "source": [ + "You can see the VSN in a readable format at the end of the device_path or in the message string. I'm only seeing one value here, so we don't need to determine which drive was the OS one. If we did, I'd look for some system processes that need to run from the OS drive to get the right VSN. \n", + "\n", + "That's good enough for the question, but let's also convert the serial_number field from an integar to the hex format the answer wants, just to be sure:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NmTdhbK7kLjB" + }, + "source": [ + "for serial_nr in ts_results.serial_number.unique():\n", + " print('{0:08X}'.format(serial_nr))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Ig0sZEC8fYa" + }, + "source": [ + "## TeamViewer Questions\n", + "The next group of questions involved [TeamViewer](https://www.teamviewer.com/en-us/), a common remote desktop program." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qsH4fUlqIUho" + }, + "source": [ + "### Q: Which user installed Team Viewer?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Hl_qGSxrLzN6" + }, + "source": [ + "We can start searching very broadly, then focus in on anything that stands out. Let's just search everything we have for \"TeamViewer\":" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hs2NyOf0IUS2" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'TeamViewer'\n", + "search_obj.return_fields='datetime,timestamp_desc,timestamp,data_type,message'\n", + "ts_results = search_obj.table\n", + "\n", + "ts_results[['datetime','timestamp_desc','data_type','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ACBv7solSKa9" + }, + "source": [ + "That returned a lot of results (600+). We could page through them all, but why not see if there are any interesting clusters first? That sounds like a job for a visualization!\n", + "\n", + "You can do this multiple ways; I'll do it in Python in a second, but the explanation is a bit complicated. The easier way is to do the search in TImesketch, then go to Charts > Histogram:\n", + "\n", + "**Histograms were part of the old UI and have not yet been ported back into the new UI. This picture is therefore from the old UI and needs to be updated.**\n", + "\n", + "![alt text](https://dfir.blog/content/images/2019/04/timesketch-histogram.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7zRjoel2wRdA" + }, + "source": [ + "And here's how you'd do something similar in Python:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fxJN_YxSScJu" + }, + "source": [ + "ts_results = ts_results.set_index('datetime')\n", + "ts_results['2018':].message.resample('D').count().plot()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "okGUVLBvk4LN" + }, + "source": [ + "Or to use grouping/aggregation in pandas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "agA685Kpk624" + }, + "source": [ + "ts_results.reset_index(inplace=True)\n", + "ts_results['day'] = ts_results.datetime.dt.strftime('%Y%m%d')\n", + "group = ts_results[['day', 'timestamp']].groupby('day', as_index=False)\n", + "\n", + "group_df = group.count().rename(columns={'timestamp': 'count'})\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iiM8mz0rleHD" + }, + "source": [ + "group_df.sort_values('count', ascending=False)[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Khe0KmZbyWl0" + }, + "source": [ + "Okay, so from the graphs it looks like we have a good cluster at the end of February; let's look closer. I'll slice the results to only show after 2019-02-20:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y-hGtMtYyrt6" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "\n", + "date_chip = search.DateRangeChip()\n", + "date_chip.start_time = '2019-02-25T00:00:00'\n", + "date_chip.end_time = '2019-03-04T23:59:59'\n", + "\n", + "search_obj.query_string = 'TeamViewer'\n", + "search_obj.add_chip(date_chip)\n", + "search_obj.return_fields = '*'\n", + "\n", + "ts_results = search_obj.table\n", + "#ts_results = ts_results.set_index('datetime')\n", + "#ts_results['2019-02-20':][['timestamp_desc','data_type','filename','message']]\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rIQfr9vvmWqc" + }, + "source": [ + "ts_results.data_type.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2meDiywWmZxD" + }, + "source": [ + "ts_results.search_string.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QBDi0z_gmcmK" + }, + "source": [ + "ts_results[ts_results.data_type.str.contains('chrome')][['datetime', 'url', 'domain', 'search_string', 'message', 'title']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XVDEnDw2mvGh" + }, + "source": [ + "ts_results[ts_results.data_type == 'fs:stat'][['datetime', 'display_name', 'timestamp_desc']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-3krCPn50csr" + }, + "source": [ + "So from this, in a short interval starting 2019-02-25T20:39, we can see:\n", + "* a Google search for \"teamviewer\"\n", + "* a visit in Chrome to teamviewer.com,\n", + "* then teamviewer.com/en-us/teamviewer-automatic-download/,\n", + "* and lastly a bunch of TeamViewer related files being created.\n", + "\n", + "The web browser and files created were done under the Administrator account (per the path filename), so that's our answer." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5EzZwgne_V44" + }, + "source": [ + "### Q: How Many Times\n", + "At least how many times did the teamviewer_desktop.exe run?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "--29x7kjADg3" + }, + "source": [ + "Prefetch is a great artifact for \"how many times did something run\"-type questions, so let's look for Prefetch execution entries for the program in question:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v2ZjHcsv_Voj" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "\n", + "search_obj.query_string = 'data_type:\"windows:prefetch:execution\" AND teamviewer_desktop.exe'\n", + "search_obj.return_fields = 'datetime,timestamp_desc,data_type,executable,run_count,message'\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','executable','run_count','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QwCaUO1TBLis" + }, + "source": [ + "### Q: Execute Where\n", + "After looking at the TEAMVIEWER_DESKTOP.EXE prefetch file, which path was the executable in at the time of execution?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8gu7QiD-Bkou" + }, + "source": [ + "We did all the work for this question with the previous query (the answer is in the message string), but we can explicitly query for the path:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y1jC_-hMBLUG" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "\n", + "search_obj.query_string = 'data_type:\"windows:prefetch:execution\" AND teamviewer_desktop.exe'\n", + "search_obj.return_fields = '*'\n", + "\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','executable','run_count', 'path_hints']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Z5KJzwABK7V" + }, + "source": [ + "## Registry Questions\n", + "This last set of questions can be answered using the Windows Registry (and one from event logs)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oYn41EUYFf5O" + }, + "source": [ + "Lots of registry questions depend on the Current Control Set, so let's verify what it is:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qbT0cf4dB_aJ" + }, + "source": [ + "# Escaping fun: We need to esacpe the slashes in the key_path once for Timesketch and once for Python, so we'll have triple slashes (\\\\\\)\n", + "\n", + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'data_type:\"windows:registry:key_value\" AND key_path:\"HKEY_LOCAL_MACHINE\\\\\\System\\\\\\Select\"'\n", + "search_obj.return_fields='datetime,timestamp_desc,data_type,message'\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FoqCvGtlFnZ1" + }, + "source": [ + "From the message, the Current control set is 1." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3QuYQux5FtlO" + }, + "source": [ + "### Q: What was the timezone offset at the time of imaging? and What is the timezone of the Desktop" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sX5xYElTHxOh" + }, + "source": [ + "I'm combining these, since the answer is in the same query:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f8CE4NYEFzWu" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "\n", + "search_obj.query_string = 'data_type:\"windows:registry:timezone\"'\n", + "search_obj.return_fields = 'datetime,timestamp_desc,data_type,message'\n", + "ts_results = search_obj.table\n", + "\n", + "ts_results[['datetime','timestamp_desc','data_type','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HJDjeFc0bzu4" + }, + "source": [ + "The message is really long; let's pull it out:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s8UMrq0tb3u6" + }, + "source": [ + "message = list(ts_results.message.unique())[0]\n", + "buffer = []\n", + "first = True\n", + "key = ''\n", + "for word in message.split():\n", + " if first:\n", + " print(word)\n", + " first = False\n", + " continue\n", + "\n", + " if not word.endswith(':'):\n", + " buffer.append(word)\n", + " continue\n", + " \n", + " if key:\n", + " words = ' '.join(buffer)\n", + " buffer = []\n", + " print(f'{\" \"*4}{key} = {words}')\n", + "\n", + " key = word[:-1]\n", + "\n", + "words = ' '.join(buffer)\n", + "buffer = []\n", + "print(f'{\" \"*4}{key} = {words}')\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NAloEuihHke2" + }, + "source": [ + "The name of the Timezone is in the message string, as is the ActiveTimeBias, which we can use to get the UTC offset:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5R57xnzQGzEB" + }, + "source": [ + "# The ActiveTimeBias is in minutes, so divide by -60 (I don't know why it's stored negative): \n", + "420 / -60" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yU8rM-2fQC-g" + }, + "source": [ + "### Q: When was the Windows OS installed?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yGnx4554QICl" + }, + "source": [ + "Plaso actually parses this out as it's own data_type, so querying for it is easy:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_DTNDAiAMSgz" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "\n", + "search_obj.query_string = 'data_type:\"windows:registry:installation\"'\n", + "search_obj.return_fields = 'datetime,timestamp_desc,data_type,message'\n", + "ts_results = search_obj.table\n", + "\n", + "ts_results[['datetime','timestamp_desc','data_type','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h6OG8tRbRf6b" + }, + "source": [ + "### Q: What is the IP address of the Desktop?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kNmlBEFAR1lI" + }, + "source": [ + "We already confirmed the Control Set is 001, so let's query for the registry key under that control set that holds the Interface information:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "angYvM_3RfA1" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'key_path:\"System\\\\\\ControlSet001\\\\\\Services\\\\\\Tcpip\\\\\\Parameters\\\\\\Interfaces\"'\n", + "search_obj.return_fields = 'datetime,timestamp_desc,data_type,message'\n", + "\n", + "ts_results = search_obj.table\n", + "ts_results[['datetime','timestamp_desc','data_type','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LckTVA9eSDCR" + }, + "source": [ + "There are a few entries, but only the last one has what we want. Reading through it (or using Ctrl+F) we can find the 'IPAddress' is 64.44.141.76." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "55kVv0nOcVKf" + }, + "source": [ + "set(ts_results.message)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TstAJwDdpW8E" + }, + "source": [ + "Or we can use str.extract:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0sS_9nFEpYTf" + }, + "source": [ + "ts_results.message.str.extract(r'DhcpIPAddress: \\[REG_SZ\\] ([^ ]+)').drop_duplicates()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VXtkOaKTU5YP" + }, + "source": [ + "### Q: Which User Shutdown Windows on February 25th 2019?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UbuECyqADgrp" + }, + "source": [ + "Event logs seem like a good place to look for this answer, since a shutdown generates a 1074 event in the System event log. From the question, we have a fairly-narrow timeframe, so let's slice the results down to that after we do our query: " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6dq7IoM_U7Qo" + }, + "source": [ + "search_obj = search.Search(ctf)\n", + "search_obj.query_string = 'data_type:\"windows:evtx:record\" AND display_name:\"System.evtx\" AND event_identifier:\"1074\"'\n", + "search_obj.return_fields='*'\n", + "\n", + "ts_results = search_obj.table\n", + "ts_results = ts_results.set_index('datetime')\n", + "ts_results['2019-02-25':'2019-02-26'][['timestamp_desc','data_type','username','message']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AlWim_NuGMeV" + }, + "source": [ + "# Wrap Up" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BbHOAd3X9Sq-" + }, + "source": [ + "That's it! Thanks for reading and I hope you found this useful. This walkthrough covered most of the questions from the 'Basic - Desktop' category; I may do other sections as well if there is time/interest. If you found this useful, check out Kristinn's demonstration of [Timesketch and Colab](https://colab.research.google.com/github/google/timesketch/blob/master/notebooks/colab-timesketch-demo.ipynb).\n", + "\n", + "You can get the free, open source tools I used to solve the CTF:\n", + "* Plaso / Log2Timeline: https://github.com/log2timeline/plaso\n", + "* Timesketch: https://github.com/google/timesketch\n", + "* Colab(oratory): https://colab.sandbox.google.com/notebooks/welcome.ipynb " + ] + } + ] +} diff --git a/notebooks/OSDFCon Demo.ipynb b/notebooks/OSDFCon Demo.ipynb new file mode 100644 index 0000000000..0750eaeb85 --- /dev/null +++ b/notebooks/OSDFCon Demo.ipynb @@ -0,0 +1,1113 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Live Demo\n", + "\n", + "Before we do any sort of research into a data set we'll need to know what the goal is.\n", + "\n", + "In this case I'm demoing how you can use Minhash calculation and text based similarities to discover potential phishing domains. This code is borrowed mostly from the phishy domain analyzer. This is to demonstrate how one can start doing some data analysis/research and end up with an analyzer.\n", + "\n", + "The question we are trying to answer is: **Are there domains in the data set that are \"similar\" to the most frequently visited domains, and thus have a chance to be phishing domains?** The theory here being that the most commonly visited domains by the user are most likely \"legit\", and if there are anomalies in the data set, that is domains that are less frequently visited yet very similar to those that are frequently visited they could be malicious or phishing domains.\n", + "\n", + "## Imports\n", + "\n", + "Simple imports of libraries that are going to be used throughout." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import re\n", + "import datetime\n", + "import getpass\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import altair as alt\n", + "\n", + "import difflib \n", + "\n", + "from timesketch_api_client import client as timesketch_client" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Caveat**\n", + "\n", + "If you are running this from jupyterlab, then you will not be able to run the first half, only the Timesketch portion.\n", + "\n", + "Also you will not be able to import everything, so the first import statement will work fine, the second import statement is only for those running this locally.\n", + "\n", + "Also if you are running from jupyterlab, then you'll need to run the pip command below (commented out for local run)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#!pip install vega" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Second import statement (only run if you are not using jupyterlab)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from datasketch.minhash import MinHash\n", + "from six.moves import urllib_parse as urlparse\n", + "\n", + "from timesketch.lib import similarity\n", + "from timesketch.lib.analyzers import utils\n", + "\n", + "_ = alt.renderers.enable('notebook')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Read the Data\n", + "\n", + "The way this would be done normally would be to store the data in timesketch and then query it.\n", + "\n", + "In this case we really only care about entries that have a URL or a domain attribute set. The TS query would be: \n", + "\n", + "```\n", + " query = (\n", + " '{\"query\": { \"bool\": { \"should\": [ '\n", + " '{ \"exists\" : { \"field\" : \"url\" }}, '\n", + " '{ \"exists\" : { \"field\" : \"domain\" }} ] } } }')\n", + "```\n", + " \n", + "However, this notebook was used at a conference for a live demo, and as such we don't want to depend on internet connectivity, thus we read a JSON file on disk.\n", + "\n", + "To get a copy of the JSON file, please reach out to kiddi at log2timeline dot net." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "user_running_notebook = getpass.getuser()\n", + "\n", + "DATA_LOCATION = '/Users/{0:s}/Documents/Presentation/data/studentpc1.jsonl'.format(user_running_notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The file itself is really large:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!du -hs $DATA_LOCATION" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since all we care about are entries with URls or domains in them, we'll open up the file and read it line by line, just picking those and then entering them into a data frame." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "data_entries = []\n", + "\n", + "with open(DATA_LOCATION, 'r') as fh:\n", + " for line in fh:\n", + " parsed = json.loads(line)\n", + " if 'url' in parsed or 'domain' in parsed:\n", + " data_entries.append(parsed)\n", + "\n", + "network_data = pd.DataFrame(data_entries)\n", + "del data_entries" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Initial Exploration\n", + "\n", + "No we've got a data frame with just our browsing data, let's look at it first to inspect before we make any other changes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "network_data.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When doing research, or data exploration it really helps knowing what the data looks like, so we take a small sample of it to look at it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "network_data.head(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's check whether we've got a domain column...." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if 'domain' in network_data.columns:\n", + " print('we do have a domain column')\n", + "else:\n", + " print('no such column exists....')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Manipulate The Data\n", + "\n", + "Now we need to start manipulating or extracting the features we need.\n", + "\n", + "We could also have just used regular expressions... eg `r'https?://([^$/]+)'` and the built-in `network_data.url.str.extract()` to extract the data. However here I'm using a library to extract the URL part, since it contains features for more types of URLs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_domain(url):\n", + " domain_parsed = urlparse.urlparse(url)\n", + " domain_full = domain_parsed.netloc\n", + " domain, _, _ = domain_full.partition(':')\n", + " return domain\n", + "\n", + "def get_tld(domain):\n", + " return '.'.join(domain.split('.')[-2:])\n", + "\n", + "network_data['domain'] = network_data.url.apply(get_domain)\n", + "network_data['tld'] = network_data.domain.apply(get_tld)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The Meat\n", + "\n", + "Now that we've got the domain we can start looking at whether there are similar domains, but first we need to figure out what are the most common domains, to see what the most likely \"corporate\" domains are." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "network_data.tld.value_counts()[:10].keys()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's create a list of domains to \"watch\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# We \"bootstrap\" the watch list with the known \"corp\" domains that we've got and we know about.\n", + "watch_list = ['greendale.xyz']\n", + "\n", + "# Let's add the top domains to the list.\n", + "watch_list.extend(network_data.tld.value_counts()[:10].keys())\n", + "watch_list.extend(network_data.domain.value_counts()[:10].keys())\n", + "\n", + "# Remove empty records...\n", + "watch_list = [x for x in watch_list if x]\n", + "watch_list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's now calculate the MinHash value for all of the domains on the watch list.\n", + "\n", + "Start by defining few functions.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + " # This is just some code from the phishy analyzer, not really something we go through here.\n", + " # Added here to have the code to play with.\n", + " domain_scoring_threshold = 0.75\n", + "\n", + " def _get_minhash_from_domain(domain):\n", + " \"\"\"Get the Minhash value from a domain name.\n", + " This function takes a domain, removes the TLD extension\n", + " from it and then creates a MinHash object from every\n", + " remaining character in the domain.\n", + " If a domain starts with www., it will be stripped of the\n", + " domain before the Minhash is calculated.\n", + " Args:\n", + " domain: string with a full domain, eg. www.google.com\n", + " Returns:\n", + " A minhash (instance of datasketch.minhash.MinHash)\n", + " \"\"\"\n", + " domain_items = domain.split('.')\n", + " domain_part = '.'.join(domain_items[:-1])\n", + "\n", + " minhash = MinHash(similarity.DEFAULT_PERMUTATIONS)\n", + " for char in domain_part:\n", + " minhash.update(char.encode('utf8'))\n", + "\n", + " return minhash\n", + "\n", + " def _get_similar_domains(domain, domain_dict):\n", + " \"\"\"Compare a domain to a list of domains and return similar domains.\n", + " This function takes a domain and a dict object that contains\n", + " as key domain names and value the calculated MinHash value for that\n", + " domain as well as the domains depth (mbl.is is 2, foobar.evil.com would\n", + " be 3). It will then strip www. if needed from the domain, and compare\n", + " the Jaccard distance between all domains in the dict and the supplied\n", + " domain (removing the TLD extension from all domains).\n", + " If the Jaccard distance between the supplied domain and one or more of\n", + " the domains in the domain dict is higher than the configured threshold\n", + " the domain is further tested to see if there are overlapping substrings\n", + " between the two domains. If there is a common substring that is longer\n", + " than half the domain name and the Jaccard distance is above the\n", + " threshold the domain is considered to be similar.\n", + " Args:\n", + " domain: string with a full domain, eg. www.google.com\n", + " domain_dict: dict with domain names (keys) and MinHash objects\n", + " (values) for all domains to compare against.\n", + " Returns:\n", + " a list of tuples (score, similar_domain_name) with the names of\n", + " the similar domains as well as the Jaccard distance between\n", + " the supplied domain and the matching one.\n", + " \"\"\"\n", + " domain = utils.strip_www_from_domain(domain)\n", + "\n", + " similar = []\n", + " if '.' not in domain:\n", + " return similar\n", + "\n", + " if domain in domain_dict:\n", + " return similar\n", + "\n", + " if any(domain.endswith('.{0:s}'.format(x)) for x in domain_dict):\n", + " return similar\n", + "\n", + " # We want to get rid of the TLD extension of the domain.\n", + " # This is only used in the substring match in case the Jaccard\n", + " # distance is above the threshold.\n", + " domain_items = domain.split('.')\n", + " domain_depth = len(domain_items)\n", + " domain_part = '.'.join(domain_items[:-1])\n", + "\n", + " minhashes = {}\n", + " for index in range(0, domain_depth - 1):\n", + " minhashes[domain_depth - index] = _get_minhash_from_domain(\n", + " '.'.join(domain_items[index:]))\n", + "\n", + " for watched_domain, watched_item in iter(domain_dict.items()):\n", + " watched_hash = watched_item.get('hash')\n", + " watched_depth = watched_item.get('depth')\n", + "\n", + " minhash = minhashes.get(watched_depth)\n", + " if not minhash:\n", + " # The supplied domains length does not match this watched\n", + " # domain.\n", + " continue\n", + " score = watched_hash.jaccard(minhash)\n", + " if score < domain_scoring_threshold:\n", + " continue\n", + "\n", + " watched_domain_items = watched_domain.split('.')\n", + " watched_domain_part = '.'.join(watched_domain_items[:-1])\n", + "\n", + " # Check if there are also any overlapping strings.\n", + " sequence = difflib.SequenceMatcher(\n", + " None, domain_part, watched_domain_part)\n", + " match = sequence.find_longest_match(\n", + " 0, len(domain_part), 0, len(watched_domain_part))\n", + "\n", + " # We want to have at least half of the domain matching.\n", + " # TODO: This can be improved, this is a value and part that\n", + " # needs or can be tweaked. Perhaps move this to a config option\n", + " # that is the min length of strings.\n", + " match_size = min(\n", + " int(len(domain_part)/2), int(len(watched_domain_part)/2))\n", + " if match.size < match_size:\n", + " continue\n", + " similar.append((watched_domain, score))\n", + "\n", + " return similar" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and to create the watched domain dict, which is an object that simply contains all the watched domains as keys and the value is the MinHash value and the depth. The depth is defined simply as the number of parts within the domain name, eg. www.mbl.is is 3 level deep, whereas cnn.com is 2, etc." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "watched_domains = {}\n", + "for domain in watch_list:\n", + " minhash = _get_minhash_from_domain(domain)\n", + " watched_domains[domain] = {\n", + " 'hash': minhash,\n", + " 'depth': len(domain.split('.'))\n", + " }" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we've got the common domains, let's calculate the jaccard distance (actually [minhash](https://en.wikipedia.org/wiki/MinHash) ) and similarities (overlapping strings) for all of the domains in the history.\n", + "\n", + "Since what we do is to take all the letters in the domain name and add it to a set, which we then create the MinHash value from and use for comparison the domains abc.com and bacccab.moc will be considered the same (same letters in it), that's why we add the overlapping string check to make sure the domains are similar." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can go through the domains we've got and find \"similar\" domains." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "entries = []\n", + "for domain in network_data.domain.unique():\n", + " similar_domains = _get_similar_domains(domain, watched_domains)\n", + " if not similar_domains:\n", + " continue\n", + "\n", + " print('Domain: {0:s} does have similar domains discovered:'.format(domain))\n", + " for similarities in similar_domains:\n", + " s_domain, s_score = similarities\n", + " print(' [{0:s}] - {1:0.2f}%'.format(s_domain, s_score * 100))\n", + " entry = {'domain': domain, 'watched_domain': s_domain, 'score': s_score}\n", + " entries.append(entry)\n", + " print('---')\n", + "similar_domains = pd.DataFrame(entries)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This can also be looked at visually.\n", + "\n", + "As a table:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "similar_domains.sort_values('score', ascending=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So we see that someone is visiting a URL that looks very similar to our corp URL...\n", + "\n", + "This could trigger a detection." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or a chart (might not be the best representation) ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "similar_domains['percentage'] = similar_domains.score * 100\n", + "alt.Chart(similar_domains).mark_point().encode(\n", + " y='domain', x='watched_domain', size='percentage',\n", + " color='watched_domain', fill='watched_domain',\n", + " tooltip=['watched_domain','domain', 'percentage'],\n", + ").properties(\n", + " width=600, height=400,\n", + " title='Similar Domains'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Timesketch Demo\n", + "\n", + "Small TS demo. Let's start by connecting to our demo server." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "client = timesketch_client.TimesketchApi('https://demo.timesketch.org', 'demo', 'demo')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we can take a look at what sketches are available, and let's pick one of them." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for index, sketch in enumerate(client.list_sketches()):\n", + " print('[{0:d}] ID: {1:d} - {2:s} <{3:s}>'.format(index, sketch.id, sketch.name, sketch.description))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case we want to get the data from the Greendale incident." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketch = client.get_sketch(238)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's start to check whether or not there are saved views." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "lines = []\n", + "for view in sketch.list_views():\n", + " view_dict = {\n", + " 'id': view.id,\n", + " 'name': view.name}\n", + " lines.append(view_dict)\n", + "\n", + "pd.DataFrame(lines)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's look at what browser searches were made." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "view = sketch.get_view(view_id=2010)\n", + "\n", + "results = sketch.explore(\n", + " view=view, as_pandas=True,\n", + " return_fields='datetime,message,timestamp_desc,source,source_short,label,tag,tags,url,domain,search_string')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's look at some of the browser searches." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "results.search_string.value_counts()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can take a look at the frequency of search queries." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "results['date'] = pd.to_datetime(results.datetime)\n", + "results['day'] = results.date.dt.strftime('%Y%m%d')\n", + "r_group = results[['day', 'datetime']].groupby(by='day', as_index=False)\n", + "r_count = r_group.count()\n", + "r_count['count'] = r_count['datetime']\n", + "del r_count['datetime']\n", + "\n", + "alt.Chart(r_count, width=500, height=300).mark_line(point=True).encode(\n", + " x='day',\n", + " y='count',\n", + " tooltip=['day', 'count'],\n", + ").properties(\n", + " title='Search Queries per day'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Problem with this is the fact that there are days with no search queries, that make the chart look a bit odd. Let's fill the values so that we have each day represented in the chart." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's skip the first day, since that was in the year 2000....\n", + "r = r_count[1:]\n", + "\n", + "# We need to find out the first and last day.\n", + "r_first = r.day.values[0]\n", + "r_end = r.day.values[-1]\n", + "\n", + "# Let's create a timestamp from the first day.\n", + "year = r_first[0:4]\n", + "month = r_first[4:6]\n", + "day = r_first[6:]\n", + "first_day = datetime.datetime(year=int(year), month=int(month), day=int(day))\n", + "\n", + "# Now we can create a list of all dates between first and last date.\n", + "all_days = []\n", + "cur_day = first_day\n", + "while True:\n", + " day_string = cur_day.strftime('%Y%m%d')\n", + " if day_string == r_end:\n", + " break\n", + " all_days.append(day_string)\n", + " cur_day = cur_day + datetime.timedelta(days=1)\n", + "\n", + "# Let's create sets, one for all days, the second for the current days.\n", + "cur_days = set([str(x) for x in r.day.values])\n", + "all_days = set(all_days)\n", + "# Now we can easily find a list of all missing dates.\n", + "missing_days = all_days.difference(cur_days)\n", + "\n", + "# Let's create a data frame that contains just the missing dates, with a count of zero.\n", + "lines = []\n", + "for day in missing_days:\n", + " line = {'day': str(day), 'count': 0}\n", + " lines.append(line)\n", + " \n", + "df = pd.DataFrame(lines)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can repeat what we did before, just this time with filled values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "r_filled = r.append(df, sort=True)\n", + "\n", + "alt.Chart(r_filled, width=900, height=300).mark_line(point=True).encode(\n", + " x=alt.X('day', axis=alt.Axis(title='Day of Query')),\n", + " y='count',\n", + " tooltip=['day', 'count'],\n", + ").properties(\n", + " title='Search Queries per day'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also just look at saved aggregations..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "aggregations = []\n", + "for index, agg in enumerate(sketch.list_aggregations()):\n", + " print('[{0:d}] - {1:s}, {2:s} <{3:s}> -> {4:s}'.format(index, agg.name, agg.aggregator_name, agg.type, agg.chart_type))\n", + " aggregations.append(agg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "They are more or less the same... we can take a look at one of them.\n", + "\n", + "As a table:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "aggregations[3].table" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or as a chart:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "aggregations[3].chart" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we shall do something different. Let's look at all executions that are recorded from our prefetch parser. Once we've get these records we can then search for whether they appear somewhere in our web history.. that is whether there is a link between prefetch and browser history (this will miss ZIP files or other compressed files that get downloaded)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data = sketch.explore(\n", + " query_string='parser:\"prefetch\"', as_pandas=True,\n", + " return_fields='datetime,timestamp_desc,source,source_short,message,executable')\n", + "\n", + "data.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we've got all the prefetch data, let's look at all executables and do a query for browser traffic that contains those names." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "browser_traffic = pd.DataFrame()\n", + "\n", + "for executable in data.executable.unique():\n", + " if not executable:\n", + " continue\n", + " if executable is np.nan:\n", + " continue\n", + " if not executable.lower().endswith('.exe'):\n", + " continue\n", + " exec_data = sketch.explore(\n", + " query_string='url:\"*{0:s}*\"'.format(executable.lower()),\n", + " return_fields='datetime,timestamp_desc,source,source_short,message,domain,url',\n", + " as_pandas=True)\n", + " browser_traffic = pd.concat([browser_traffic, exec_data])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's combine the two data frames, that is the browser traffic and the prefetch data. We'll then sort it by dates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "combined = pd.concat([browser_traffic, data], sort=False)\n", + "c_sorted = combined.sort_values(by='datetime')\n", + "c_sorted['date'] = pd.to_datetime(c_sorted.datetime)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First of all, let's just look at VPN.exe:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c_sorted[c_sorted.message.str.contains('vpn.exe', case=False)][['date', 'timestamp_desc', 'message', 'url', 'executable', 'domain']][2:]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And to examine all the hits:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c_sorted[['date', 'timestamp_desc', 'message', 'url', 'executable']]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also extract the executable from the web history." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import six\n", + "\n", + "def check_row(row):\n", + " executable = row.executable\n", + " if isinstance(executable, six.text_type):\n", + " if not executable:\n", + " return np.nan\n", + " return executable.lower()\n", + " url = row.url\n", + " if not isinstance(url, six.text_type):\n", + " return np.nan\n", + " _, _, last_part = url.rpartition('/')\n", + " if '&' in last_part:\n", + " last_part, _, _ = last_part.partition('&')\n", + " if '#' in last_part:\n", + " last_part, _, _ = last_part.partition('#')\n", + " \n", + " if not last_part:\n", + " return np.nan\n", + " return last_part\n", + "\n", + "c_sorted['new_exec'] = c_sorted.apply(check_row, axis=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can look at the most common applications" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c_sorted['day'] = c_sorted.date.dt.strftime('%Y%m%d')\n", + "c_sorted_data = c_sorted[~c_sorted.new_exec.isna()]\n", + "\n", + "c_sorted_data.new_exec.value_counts()[:10]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And then look at vpn.exe" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c_sorted_data[c_sorted_data.new_exec == 'vpn.exe']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or we can do this as a chart..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c_group = c_sorted[['day', 'date', 'new_exec']].groupby(by=['new_exec','day'], as_index=False)\n", + "c_count = c_group.count()\n", + "c_count['count'] = c_count.date\n", + "c_count['executable'] = c_count['new_exec']\n", + "del c_count['date']\n", + "\n", + "alt.Chart(c_count).mark_point(filled=True).encode(\n", + " x='day',\n", + " y='executable',\n", + " size='count',\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OK.. these are all... but what about those executables that appear BOTH in a URL and Prefetch.\n", + "\n", + "To be able to do that, we'll first add the executable field to the two data frames from before." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "browser_traffic.head(10)\n", + "\n", + "def get_exec(url):\n", + " items = [x.lower() for x in url.split('/')]\n", + " executable = ''\n", + " for item in items:\n", + " if not '.exe' in item:\n", + " continue\n", + " executable = item\n", + " if '#' in executable:\n", + " executable, _, _ = executable.partition('#')\n", + " if '&' in executable:\n", + " executable, _, _ = executable.partition('&')\n", + " if '\\\\' in executable:\n", + " _, _, executable = executable.rpartition('\\\\')\n", + " return executable\n", + "\n", + "browser_traffic['new_exec'] = browser_traffic.url.apply(get_exec)\n", + "\n", + "def get_exec(exec_string):\n", + " if not isinstance(exec_string, six.text_type):\n", + " return exec_string\n", + " return exec_string.lower()\n", + "\n", + "data['new_exec'] = data.executable.apply(get_exec)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can merge the two data frames." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "merged_df = data.merge(browser_traffic, on='new_exec')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And then we can do the same as we did above." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "merged_df['date'] = pd.to_datetime(merged_df['datetime_x'])\n", + "merged_df['day'] = merged_df.date.dt.strftime('%Y%m%d')\n", + "m_group = merged_df[['day', 'date', 'new_exec']].groupby(by=['new_exec','day'], as_index=False)\n", + "m_count = m_group.count()\n", + "m_count['count'] = m_count.date\n", + "m_count['executable'] = m_count['new_exec']\n", + "del m_count['date']\n", + "\n", + "alt.Chart(m_count, width=300, height=200).mark_point(filled=True).encode(\n", + " x='day',\n", + " y='executable',\n", + " size='count',\n", + " color='executable'\n", + ").properties(\n", + " title='Executables that appear both in Prefetch and Internet history'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Search by label.\n", + "Let's look at some other part of the API, let's look at starred events." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketch.search_by_label('__ts_star', as_pandas=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/SigmaPortFileToDatabase.ipynb b/notebooks/SigmaPortFileToDatabase.ipynb new file mode 100644 index 0000000000..71a55d1588 --- /dev/null +++ b/notebooks/SigmaPortFileToDatabase.ipynb @@ -0,0 +1,1419 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Timesketch Sigma rule from file to Database notebook\n", + "\n", + "This notebook will help adding one Sigma rule from disk to the Timesketch Sigma rule database." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -q timesketch_api_client" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mWARNING: Skipping timesketch_api_client as it is not installed.\u001b[0m\u001b[33m\n", + "\u001b[0m" + ] + } + ], + "source": [ + "!pip uninstall -y timesketch_api_client" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "MODULE_FULL_PATH = '/usr/local/google/home/jaegeral/dev/timesketch/api_client/python/'\n", + "\n", + "sys.path.insert(1, MODULE_FULL_PATH)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "running build\n", + "running install\n", + "/usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\n", + " warnings.warn(\n", + "/usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages/setuptools/command/easy_install.py:158: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.\n", + " warnings.warn(\n", + "Checking .pth file support in /usr/local/google/home/jaegeral/.local/lib/python3.10/site-packages/\n", + "/usr/local/google/home/jaegeral/dev/timesketch/.venv/bin/python3 -E -c pass\n", + "TEST FAILED: /usr/local/google/home/jaegeral/.local/lib/python3.10/site-packages/ does NOT support .pth files\n", + "bad install directory or PYTHONPATH\n", + "\n", + "You are attempting to install a package to a directory that is not\n", + "on PYTHONPATH and which Python does not read \".pth\" files from. The\n", + "installation directory you specified (via --install-dir, --prefix, or\n", + "the distutils default setting) was:\n", + "\n", + " /usr/local/google/home/jaegeral/.local/lib/python3.10/site-packages/\n", + "\n", + "and your PYTHONPATH environment variable currently contains:\n", + "\n", + " '/usr/local/buildtools/current/sitecustomize'\n", + "\n", + "Here are some of your options for correcting the problem:\n", + "\n", + "* You can choose a different installation directory, i.e., one that is\n", + " on PYTHONPATH or supports .pth files\n", + "\n", + "* You can add the installation directory to the PYTHONPATH environment\n", + " variable. (It must then also be on PYTHONPATH whenever you run\n", + " Python and want to use the package(s) you are installing.)\n", + "\n", + "* You can set up the installation directory to support \".pth\" files by\n", + " using one of the approaches described here:\n", + "\n", + " https://setuptools.pypa.io/en/latest/deprecated/easy_install.html#custom-installation-locations\n", + "\n", + "\n", + "Please make the appropriate changes for your system and try again.\n", + "running bdist_egg\n", + "running egg_info\n", + "writing timesketch_api_client.egg-info/PKG-INFO\n", + "writing dependency_links to timesketch_api_client.egg-info/dependency_links.txt\n", + "writing requirements to timesketch_api_client.egg-info/requires.txt\n", + "writing top-level names to timesketch_api_client.egg-info/top_level.txt\n", + "reading manifest file 'timesketch_api_client.egg-info/SOURCES.txt'\n", + "writing manifest file 'timesketch_api_client.egg-info/SOURCES.txt'\n", + "installing library code to build/bdist.linux-x86_64/egg\n", + "running install_lib\n", + "warning: install_lib: 'build/lib' does not exist -- no Python modules to install\n", + "\n", + "creating build/bdist.linux-x86_64/egg\n", + "creating build/bdist.linux-x86_64/egg/EGG-INFO\n", + "copying timesketch_api_client.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO\n", + "copying timesketch_api_client.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", + "copying timesketch_api_client.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", + "copying timesketch_api_client.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO\n", + "copying timesketch_api_client.egg-info/requires.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", + "copying timesketch_api_client.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", + "creating 'dist/timesketch_api_client-20221005-py3.10.egg' and adding 'build/bdist.linux-x86_64/egg' to it\n", + "removing 'build/bdist.linux-x86_64/egg' (and everything under it)\n", + "Processing timesketch_api_client-20221005-py3.10.egg\n", + "creating /usr/local/google/home/jaegeral/.local/lib/python3.10/site-packages/timesketch_api_client-20221005-py3.10.egg\n", + "Extracting timesketch_api_client-20221005-py3.10.egg to /usr/local/google/home/jaegeral/.local/lib/python3.10/site-packages\n", + "\n", + "Installed /usr/local/google/home/jaegeral/.local/lib/python3.10/site-packages/timesketch_api_client-20221005-py3.10.egg\n", + "Processing dependencies for timesketch-api-client==20221005\n", + "Searching for requests==2.28.1\n", + "Best match: requests 2.28.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for pandas==1.4.4\n", + "Best match: pandas 1.4.4\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for networkx==2.8.6\n", + "Best match: networkx 2.8.6\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for google-auth-oauthlib==0.5.3\n", + "Best match: google-auth-oauthlib 0.5.3\n", + "Installing google-oauthlib-tool script to /usr/local/google/home/jaegeral/.local/bin\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for google-auth==2.11.0\n", + "Best match: google-auth 2.11.0\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for cryptography==38.0.1\n", + "Best match: cryptography 38.0.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for beautifulsoup4==4.11.1\n", + "Best match: beautifulsoup4 4.11.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for altair==4.2.0\n", + "Best match: altair 4.2.0\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for certifi==2022.6.15.2\n", + "Best match: certifi 2022.6.15.2\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for charset-normalizer==2.1.1\n", + "Best match: charset-normalizer 2.1.1\n", + "Installing normalizer script to /usr/local/google/home/jaegeral/.local/bin\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for urllib3==1.26.12\n", + "Best match: urllib3 1.26.12\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for idna==3.4\n", + "Best match: idna 3.4\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for pytz==2022.2.1\n", + "Best match: pytz 2022.2.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for python-dateutil==2.8.2\n", + "Best match: python-dateutil 2.8.2\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for numpy==1.23.3\n", + "Best match: numpy 1.23.3\n", + "Installing f2py script to /usr/local/google/home/jaegeral/.local/bin\n", + "Installing f2py3 script to /usr/local/google/home/jaegeral/.local/bin\n", + "Installing f2py3.10 script to /usr/local/google/home/jaegeral/.local/bin\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for requests-oauthlib==1.3.1\n", + "Best match: requests-oauthlib 1.3.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for rsa==4.9\n", + "Best match: rsa 4.9\n", + "Installing pyrsa-decrypt script to /usr/local/google/home/jaegeral/.local/bin\n", + "Installing pyrsa-encrypt script to /usr/local/google/home/jaegeral/.local/bin\n", + "Installing pyrsa-keygen script to /usr/local/google/home/jaegeral/.local/bin\n", + "Installing pyrsa-priv2pub script to /usr/local/google/home/jaegeral/.local/bin\n", + "Installing pyrsa-sign script to /usr/local/google/home/jaegeral/.local/bin\n", + "Installing pyrsa-verify script to /usr/local/google/home/jaegeral/.local/bin\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for cachetools==5.2.0\n", + "Best match: cachetools 5.2.0\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for pyasn1-modules==0.2.8\n", + "Best match: pyasn1-modules 0.2.8\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for six==1.16.0\n", + "Best match: six 1.16.0\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for cffi==1.15.1\n", + "Best match: cffi 1.15.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for soupsieve==2.3.2.post1\n", + "Best match: soupsieve 2.3.2.post1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for toolz==0.12.0\n", + "Best match: toolz 0.12.0\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for jsonschema==4.16.0\n", + "Best match: jsonschema 4.16.0\n", + "Installing jsonschema script to /usr/local/google/home/jaegeral/.local/bin\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for entrypoints==0.4\n", + "Best match: entrypoints 0.4\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for Jinja2==3.1.2\n", + "Best match: Jinja2 3.1.2\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for oauthlib==3.1.0\n", + "Best match: oauthlib 3.1.0\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for pyasn1==0.4.8\n", + "Best match: pyasn1 0.4.8\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for pycparser==2.21\n", + "Best match: pycparser 2.21\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for attrs==22.1.0\n", + "Best match: attrs 22.1.0\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for pyrsistent==0.18.1\n", + "Best match: pyrsistent 0.18.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Searching for MarkupSafe==2.1.1\n", + "Best match: MarkupSafe 2.1.1\n", + "\n", + "Using /usr/local/google/home/jaegeral/dev/timesketch/.venv/lib/python3.10/site-packages\n", + "Finished processing dependencies for timesketch-api-client==20221005\n" + ] + } + ], + "source": [ + "!python3 /usr/local/google/home/jaegeral/dev/timesketch/api_client/python/setup.py build && python3 /usr/local/google/home/jaegeral/dev/timesketch/api_client/python/setup.py install --user" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "from timesketch_api_client import config\n", + "from timesketch_api_client import sketch\n", + "from timesketch_api_client import timeline\n", + "from timesketch_api_client import analyzer\n", + "from timesketch_api_client import search\n", + "\n", + "from timesketch_import_client import helper\n", + "from timesketch_import_client import importer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If an error occurs, you might need to remove `rm ~/.timesketch*` and re-run the following command" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "ts_client = config.get_client()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sketch name: aaa (1)\n" + ] + } + ], + "source": [ + "sketches = [(x.id, x.name) for x in ts_client.list_sketches()]\n", + "for sketch in sketches:\n", + " print(f\"Sketch name: {sketch[1]} ({sketch[0]})\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using sketch ID 1\n", + "{\n", + " \"meta\": {\n", + " \"aggregators\": {\n", + " \"field_bucket\": {\n", + " \"description\": \"Aggregating values of a particular field\",\n", + " \"display_name\": \"Terms Aggregation\",\n", + " \"form_fields\": [\n", + " {\n", + " \"display\": true,\n", + " \"label\": \"Chart type to render\",\n", + " \"name\": \"supported_charts\",\n", + " \"options\": [\n", + " \"table\",\n", + " \"hbarchart\",\n", + " \"barchart\",\n", + " \"linechart\",\n", + " \"circlechart\"\n", + " ],\n", + " \"type\": \"ts-dynamic-form-select-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"\",\n", + " \"display\": true,\n", + " \"label\": \"What field to aggregate on\",\n", + " \"name\": \"field\",\n", + " \"placeholder\": \"Enter a field to aggregate\",\n", + " \"type\": \"ts-dynamic-form-text-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"\",\n", + " \"display\": true,\n", + " \"label\": \"ISO formatted timestamp for the start time of the aggregated data\",\n", + " \"name\": \"start_time\",\n", + " \"placeholder\": \"Enter a start date for the aggregation\",\n", + " \"type\": \"ts-dynamic-form-datetime-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"\",\n", + " \"display\": true,\n", + " \"label\": \"ISO formatted end time for the aggregation\",\n", + " \"name\": \"end_time\",\n", + " \"placeholder\": \"Enter an end date for the aggregation\",\n", + " \"type\": \"ts-dynamic-form-datetime-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"10\",\n", + " \"display\": true,\n", + " \"label\": \"Number of results to return\",\n", + " \"name\": \"limit\",\n", + " \"placeholder\": \"Enter number of results to return\",\n", + " \"type\": \"ts-dynamic-form-text-input\"\n", + " }\n", + " ]\n", + " },\n", + " \"query_bucket\": {\n", + " \"description\": \"Aggregating values of a field after applying a filter\",\n", + " \"display_name\": \"Filtered Terms Aggregation\",\n", + " \"form_fields\": [\n", + " {\n", + " \"display\": true,\n", + " \"label\": \"Chart type to render\",\n", + " \"name\": \"supported_charts\",\n", + " \"options\": [\n", + " \"table\",\n", + " \"hbarchart\",\n", + " \"barchart\",\n", + " \"linechart\",\n", + " \"circlechart\"\n", + " ],\n", + " \"type\": \"ts-dynamic-form-select-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"\",\n", + " \"display\": true,\n", + " \"label\": \"The filter query to narrow down the result set\",\n", + " \"name\": \"query_string\",\n", + " \"placeholder\": \"Query\",\n", + " \"type\": \"ts-dynamic-form-text-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"\",\n", + " \"display\": false,\n", + " \"label\": \"The filter query DSL to narrow down the result\",\n", + " \"name\": \"query_dsl\",\n", + " \"placeholder\": \"Query DSL\",\n", + " \"type\": \"ts-dynamic-form-text-input\"\n", + " },\n", + " {\n", + " \"display\": true,\n", + " \"label\": \"What field to aggregate.\",\n", + " \"name\": \"field\",\n", + " \"type\": \"ts-dynamic-form-text-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"\",\n", + " \"display\": true,\n", + " \"label\": \"ISO formatted timestamp for the start time of the aggregated data\",\n", + " \"name\": \"start_time\",\n", + " \"placeholder\": \"Enter a start date for the aggregation\",\n", + " \"type\": \"ts-dynamic-form-datetime-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"\",\n", + " \"display\": true,\n", + " \"label\": \"ISO formatted end time for the aggregation\",\n", + " \"name\": \"end_time\",\n", + " \"placeholder\": \"Enter an end date for the aggregation\",\n", + " \"type\": \"ts-dynamic-form-datetime-input\"\n", + " },\n", + " {\n", + " \"default_value\": \"10\",\n", + " \"display\": true,\n", + " \"label\": \"Number of results to return\",\n", + " \"name\": \"limit\",\n", + " \"placeholder\": \"Enter number of results to return\",\n", + " \"type\": \"ts-dynamic-form-text-input\"\n", + " }\n", + " ]\n", + " }\n", + " },\n", + " \"attributes\": {},\n", + " \"collaborators\": {\n", + " \"groups\": [],\n", + " \"users\": []\n", + " },\n", + " \"emojis\": {\n", + " \"🆔\": \"Account ID\",\n", + " \"🇦🇨\": \"Ascension Island\",\n", + " \"🇦🇩\": \"Andorra\",\n", + " \"🇦🇪\": \"United Arab Emirates\",\n", + " \"🇦🇫\": \"Afghanistan\",\n", + " \"🇦🇬\": \"Antigua & Barbuda\",\n", + " \"🇦🇮\": \"Anguilla\",\n", + " \"🇦🇱\": \"Albania\",\n", + " \"🇦🇲\": \"Armenia\",\n", + " \"🇦🇴\": \"Angola\",\n", + " \"🇦🇶\": \"Antarctica\",\n", + " \"🇦🇷\": \"Argentina\",\n", + " \"🇦🇸\": \"American Samoa\",\n", + " \"🇦🇹\": \"Austria\",\n", + " \"🇦🇺\": \"Australia\",\n", + " \"🇦🇼\": \"Aruba\",\n", + " \"🇦🇽\": \"\\u00c5land Islands\",\n", + " \"🇦🇿\": \"Azerbaijan\",\n", + " \"🇧🇦\": \"Bosnia & Herzegovina\",\n", + " \"🇧🇧\": \"Barbados\",\n", + " \"🇧🇩\": \"Bangladesh\",\n", + " \"🇧🇪\": \"Belgium\",\n", + " \"🇧🇫\": \"Burkina Faso\",\n", + " \"🇧🇬\": \"Bulgaria\",\n", + " \"🇧🇭\": \"Bahrain\",\n", + " \"🇧🇮\": \"Burundi\",\n", + " \"🇧🇯\": \"Benin\",\n", + " \"🇧🇱\": \"St. Barth\\u00e9lemy\",\n", + " \"🇧🇲\": \"Bermuda\",\n", + " \"🇧🇳\": \"Brunei\",\n", + " \"🇧🇴\": \"Bolivia\",\n", + " \"🇧🇶\": \"Caribbean Netherlands\",\n", + " \"🇧🇷\": \"Brazil\",\n", + " \"🇧🇸\": \"Bahamas\",\n", + " \"🇧🇹\": \"Bhutan\",\n", + " \"🇧🇻\": \"Bouvet Island\",\n", + " \"🇧🇼\": \"Botswana\",\n", + " \"🇧🇾\": \"Belarus\",\n", + " \"🇧🇿\": \"Belize\",\n", + " \"🇨🇦\": \"Canada\",\n", + " \"🇨🇨\": \"Cocos (Keeling) Islands\",\n", + " \"🇨🇩\": \"Congo - Kinshasa\",\n", + " \"🇨🇫\": \"Central African Republic\",\n", + " \"🇨🇬\": \"Congo - Brazzaville\",\n", + " \"🇨🇭\": \"Switzerland\",\n", + " \"🇨🇮\": \"C\\u00f4te d\\u2019Ivoire\",\n", + " \"🇨🇰\": \"Cook Islands\",\n", + " \"🇨🇱\": \"Chile\",\n", + " \"🇨🇲\": \"Cameroon\",\n", + " \"🇨🇳\": \"China\",\n", + " \"🇨🇴\": \"Colombia\",\n", + " \"🇨🇵\": \"Clipperton Island\",\n", + " \"🇨🇷\": \"Costa Rica\",\n", + " \"🇨🇺\": \"Cuba\",\n", + " \"🇨🇻\": \"Cape Verde\",\n", + " \"🇨🇼\": \"Cura\\u00e7ao\",\n", + " \"🇨🇽\": \"Christmas Island\",\n", + " \"🇨🇾\": \"Cyprus\",\n", + " \"🇨🇿\": \"Czechia\",\n", + " \"🇩🇪\": \"Germany\",\n", + " \"🇩🇬\": \"Diego Garcia\",\n", + " \"🇩🇯\": \"Djibouti\",\n", + " \"🇩🇰\": \"Denmark\",\n", + " \"🇩🇲\": \"Dominica\",\n", + " \"🇩🇴\": \"Dominican Republic\",\n", + " \"🇩🇿\": \"Algeria\",\n", + " \"🇪🇦\": \"Ceuta & Melilla\",\n", + " \"🇪🇨\": \"Ecuador\",\n", + " \"🇪🇪\": \"Estonia\",\n", + " \"🇪🇬\": \"Egypt\",\n", + " \"🇪🇭\": \"Western Sahara\",\n", + " \"🇪🇷\": \"Eritrea\",\n", + " \"🇪🇸\": \"Spain\",\n", + " \"🇪🇹\": \"Ethiopia\",\n", + " \"🇪🇺\": \"European Union\",\n", + " \"🇫🇮\": \"Finland\",\n", + " \"🇫🇯\": \"Fiji\",\n", + " \"🇫🇰\": \"Falkland Islands\",\n", + " \"🇫🇲\": \"Micronesia\",\n", + " \"🇫🇴\": \"Faroe Islands\",\n", + " \"🇫🇷\": \"France\",\n", + " \"🇬🇦\": \"Gabon\",\n", + " \"🇬🇧\": \"United Kingdom\",\n", + " \"🇬🇩\": \"Grenada\",\n", + " \"🇬🇪\": \"Georgia\",\n", + " \"🇬🇫\": \"French Guiana\",\n", + " \"🇬🇬\": \"Guernsey\",\n", + " \"🇬🇭\": \"Ghana\",\n", + " \"🇬🇮\": \"Gibraltar\",\n", + " \"🇬🇱\": \"Greenland\",\n", + " \"🇬🇲\": \"Gambia\",\n", + " \"🇬🇳\": \"Guinea\",\n", + " \"🇬🇵\": \"Guadeloupe\",\n", + " \"🇬🇶\": \"Equatorial Guinea\",\n", + " \"🇬🇷\": \"Greece\",\n", + " \"🇬🇸\": \"South Georgia & South Sandwich Islands\",\n", + " \"🇬🇹\": \"Guatemala\",\n", + " \"🇬🇺\": \"Guam\",\n", + " \"🇬🇼\": \"Guinea-Bissau\",\n", + " \"🇬🇾\": \"Guyana\",\n", + " \"🇭🇰\": \"Hong Kong SAR China\",\n", + " \"🇭🇲\": \"Heard & McDonald Islands\",\n", + " \"🇭🇳\": \"Honduras\",\n", + " \"🇭🇷\": \"Croatia\",\n", + " \"🇭🇹\": \"Haiti\",\n", + " \"🇭🇺\": \"Hungary\",\n", + " \"🇮🇨\": \"Canary Islands\",\n", + " \"🇮🇩\": \"Indonesia\",\n", + " \"🇮🇪\": \"Ireland\",\n", + " \"🇮🇱\": \"Israel\",\n", + " \"🇮🇲\": \"Isle of Man\",\n", + " \"🇮🇳\": \"India\",\n", + " \"🇮🇴\": \"British Indian Ocean Territory\",\n", + " \"🇮🇶\": \"Iraq\",\n", + " \"🇮🇷\": \"Iran\",\n", + " \"🇮🇸\": \"Iceland\",\n", + " \"🇮🇹\": \"Italy\",\n", + " \"🇯🇪\": \"Jersey\",\n", + " \"🇯🇲\": \"Jamaica\",\n", + " \"🇯🇴\": \"Jordan\",\n", + " \"🇯🇵\": \"Japan\",\n", + " \"🇰🇪\": \"Kenya\",\n", + " \"🇰🇬\": \"Kyrgyzstan\",\n", + " \"🇰🇭\": \"Cambodia\",\n", + " \"🇰🇮\": \"Kiribati\",\n", + " \"🇰🇲\": \"Comoros\",\n", + " \"🇰🇳\": \"St. Kitts & Nevis\",\n", + " \"🇰🇵\": \"North Korea\",\n", + " \"🇰🇷\": \"South Korea\",\n", + " \"🇰🇼\": \"Kuwait\",\n", + " \"🇰🇾\": \"Cayman Islands\",\n", + " \"🇰🇿\": \"Kazakhstan\",\n", + " \"🇱🇦\": \"Laos\",\n", + " \"🇱🇧\": \"Lebanon\",\n", + " \"🇱🇨\": \"St. Lucia\",\n", + " \"🇱🇮\": \"Liechtenstein\",\n", + " \"🇱🇰\": \"Sri Lanka\",\n", + " \"🇱🇷\": \"Liberia\",\n", + " \"🇱🇸\": \"Lesotho\",\n", + " \"🇱🇹\": \"Lithuania\",\n", + " \"🇱🇺\": \"Luxembourg\",\n", + " \"🇱🇻\": \"Latvia\",\n", + " \"🇱🇾\": \"Libya\",\n", + " \"🇲🇦\": \"Morocco\",\n", + " \"🇲🇨\": \"Monaco\",\n", + " \"🇲🇩\": \"Moldova\",\n", + " \"🇲🇪\": \"Montenegro\",\n", + " \"🇲🇫\": \"St. Martin\",\n", + " \"🇲🇬\": \"Madagascar\",\n", + " \"🇲🇭\": \"Marshall Islands\",\n", + " \"🇲🇰\": \"Macedonia\",\n", + " \"🇲🇱\": \"Mali\",\n", + " \"🇲🇲\": \"Myanmar (Burma)\",\n", + " \"🇲🇳\": \"Mongolia\",\n", + " \"🇲🇴\": \"Macao SAR China\",\n", + " \"🇲🇵\": \"Northern Mariana Islands\",\n", + " \"🇲🇶\": \"Martinique\",\n", + " \"🇲🇷\": \"Mauritania\",\n", + " \"🇲🇸\": \"Montserrat\",\n", + " \"🇲🇹\": \"Malta\",\n", + " \"🇲🇺\": \"Mauritius\",\n", + " \"🇲🇻\": \"Maldives\",\n", + " \"🇲🇼\": \"Malawi\",\n", + " \"🇲🇽\": \"Mexico\",\n", + " \"🇲🇾\": \"Malaysia\",\n", + " \"🇲🇿\": \"Mozambique\",\n", + " \"🇳🇦\": \"Namibia\",\n", + " \"🇳🇨\": \"New Caledonia\",\n", + " \"🇳🇪\": \"Niger\",\n", + " \"🇳🇫\": \"Norfolk Island\",\n", + " \"🇳🇬\": \"Nigeria\",\n", + " \"🇳🇮\": \"Nicaragua\",\n", + " \"🇳🇱\": \"Netherlands\",\n", + " \"🇳🇴\": \"Norway\",\n", + " \"🇳🇵\": \"Nepal\",\n", + " \"🇳🇷\": \"Nauru\",\n", + " \"🇳🇺\": \"Niue\",\n", + " \"🇳🇿\": \"New Zealand\",\n", + " \"🇴🇲\": \"Oman \",\n", + " \"🇵🇦\": \"Panama\",\n", + " \"🇵🇪\": \"Peru\",\n", + " \"🇵🇫\": \"French Polynesia\",\n", + " \"🇵🇬\": \"Papua New Guinea\",\n", + " \"🇵🇭\": \"Philippines\",\n", + " \"🇵🇰\": \"Pakistan\",\n", + " \"🇵🇱\": \"Poland\",\n", + " \"🇵🇲\": \"St. Pierre & Miquelon\",\n", + " \"🇵🇳\": \"Pitcairn Islands\",\n", + " \"🇵🇷\": \"Puerto Rico\",\n", + " \"🇵🇸\": \"Palestinian Territories\",\n", + " \"🇵🇹\": \"Portugal\",\n", + " \"🇵🇼\": \"Palau\",\n", + " \"🇵🇾\": \"Paraguay\",\n", + " \"🇶🇦\": \"Qatar\",\n", + " \"🇷🇪\": \"R\\u00e9union\",\n", + " \"🇷🇴\": \"Romania\",\n", + " \"🇷🇸\": \"Serbia\",\n", + " \"🇷🇺\": \"Russia\",\n", + " \"🇷🇼\": \"Rwanda\",\n", + " \"🇸🇦\": \"Saudi Arabia\",\n", + " \"🇸🇧\": \"Solomon Islands\",\n", + " \"🇸🇨\": \"Seychelles\",\n", + " \"🇸🇩\": \"Sudan\",\n", + " \"🇸🇪\": \"Sweden\",\n", + " \"🇸🇬\": \"Singapore\",\n", + " \"🇸🇭\": \"St. Helena\",\n", + " \"🇸🇮\": \"Slovenia\",\n", + " \"🇸🇯\": \"Svalbard & Jan Mayen\",\n", + " \"🇸🇰\": \"Slovakia\",\n", + " \"🇸🇱\": \"Sierra Leone\",\n", + " \"🇸🇲\": \"San Marino\",\n", + " \"🇸🇳\": \"Senegal\",\n", + " \"🇸🇴\": \"Somalia\",\n", + " \"🇸🇷\": \"Suriname\",\n", + " \"🇸🇸\": \"South Sudan\",\n", + " \"🇸🇹\": \"S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe\",\n", + " \"🇸🇻\": \"El Salvador\",\n", + " \"🇸🇽\": \"Sint Maarten\",\n", + " \"🇸🇾\": \"Syria\",\n", + " \"🇸🇿\": \"Eswatini\",\n", + " \"🇹🇦\": \"Tristan da Cunha\",\n", + " \"🇹🇨\": \"Turks & Caicos Islands\",\n", + " \"🇹🇩\": \"Chad\",\n", + " \"🇹🇫\": \"French Southern Territories\",\n", + " \"🇹🇬\": \"Togo\",\n", + " \"🇹🇭\": \"Thailand\",\n", + " \"🇹🇯\": \"Tajikistan\",\n", + " \"🇹🇰\": \"Tokelau\",\n", + " \"🇹🇱\": \"Timor-Leste\",\n", + " \"🇹🇲\": \"Turkmenistan\",\n", + " \"🇹🇳\": \"Tunisia\",\n", + " \"🇹🇴\": \"Tonga\",\n", + " \"🇹🇷\": \"Turkey\",\n", + " \"🇹🇹\": \"Trinidad & Tobago\",\n", + " \"🇹🇻\": \"Tuvalu\",\n", + " \"🇹🇼\": \"Taiwan\",\n", + " \"🇹🇿\": \"Tanzania\",\n", + " \"🇺🇦\": \"Ukraine\",\n", + " \"🇺🇬\": \"Uganda\",\n", + " \"🇺🇲\": \"U.S. Outlying Islands\",\n", + " \"🇺🇳\": \"United Nations\",\n", + " \"🇺🇸\": \"United States\",\n", + " \"🇺🇾\": \"Uruguay\",\n", + " \"🇺🇿\": \"Uzbekistan\",\n", + " \"🇻🇦\": \"Vatican City\",\n", + " \"🇻🇨\": \"St. Vincent & Grenadines\",\n", + " \"🇻🇪\": \"Venezuela\",\n", + " \"🇻🇬\": \"British Virgin Islands\",\n", + " \"🇻🇮\": \"U.S. Virgin Islands\",\n", + " \"🇻🇳\": \"Vietnam\",\n", + " \"🇻🇺\": \"Vanuatu\",\n", + " \"🇼🇫\": \"Wallis & Futuna\",\n", + " \"🇼🇸\": \"Samoa\",\n", + " \"🇽🇰\": \"Kosovo\",\n", + " \"🇾🇪\": \"Yemen\",\n", + " \"🇾🇹\": \"Mayotte\",\n", + " \"🇿🇦\": \"South Africa\",\n", + " \"🇿🇲\": \"Zambia\",\n", + " \"🇿🇼\": \"Zimbabwe\",\n", + " \"🌏\": \"The world\",\n", + " \"🎣\": \"Phishing\",\n", + " \"💀\": \"Threat intel match\",\n", + " \"📡\": \"Domain activity\",\n", + " \"📷\": \"Screenshot activity\",\n", + " \"🔎\": \"Search related activity\",\n", + " \"🔒\": \"Logon activity\",\n", + " \"🔓\": \"Logoff activity\",\n", + " \"🔗\": \"Events Linked\",\n", + " \"🖵\": \"Screensaver activity\",\n", + " \"🗑\": \"Deletion activity\",\n", + " \"😴\": \"Activity outside of regular hours\",\n", + " \"🚂\": \"Execution activity\",\n", + " \"🧍\": \"Person\",\n", + " \"🪣\": \"Storage bucket\",\n", + " \"☠\": \"Suspicious entry\",\n", + " \"✨\": \"New entity created\"\n", + " },\n", + " \"filter_labels\": [],\n", + " \"indices_metadata\": {\n", + " \"af23d06fb58b409a849571a18115e4ba\": {\n", + " \"is_legacy\": false\n", + " }\n", + " },\n", + " \"last_activity\": \"2022-10-05T09:48:20.427484\",\n", + " \"mappings\": [\n", + " {\n", + " \"field\": \"command\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"data_type\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"datetime\",\n", + " \"type\": \"date\"\n", + " },\n", + " {\n", + " \"field\": \"display_name\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"extra_field_1\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"filename\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"message\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"packages\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"parser\",\n", + " \"type\": \"text\"\n", + " },\n", + " {\n", + " \"field\": \"timestamp\",\n", + " \"type\": \"long\"\n", + " },\n", + " {\n", + " \"field\": \"timestamp_desc\",\n", + " \"type\": \"text\"\n", + " }\n", + " ],\n", + " \"permissions\": {\n", + " \"delete\": true,\n", + " \"public\": false,\n", + " \"read\": true,\n", + " \"write\": true\n", + " },\n", + " \"searchtemplates\": [],\n", + " \"sketch_labels\": [],\n", + " \"stats_per_timeline\": {\n", + " \"1\": {\n", + " \"count\": 4\n", + " }\n", + " },\n", + " \"stories\": [],\n", + " \"views\": []\n", + " },\n", + " \"objects\": [\n", + " {\n", + " \"active_timelines\": [\n", + " {\n", + " \"color\": \"F37979\",\n", + " \"created_at\": \"2022-10-03T16:05:59.389141\",\n", + " \"datasources\": [\n", + " {\n", + " \"context\": \"sigma_events.csv\",\n", + " \"created_at\": \"2022-10-03T16:05:59.408345\",\n", + " \"data_label\": \"\",\n", + " \"error_message\": \"\",\n", + " \"file_on_disk\": \"/tmp/0c12b9e8d7e04ac5aa6f6c7f4166759d\",\n", + " \"file_size\": 702,\n", + " \"id\": 1,\n", + " \"original_filename\": \"sigma_events.csv\",\n", + " \"provider\": \"WebUpload\",\n", + " \"status\": [\n", + " {\n", + " \"created_at\": \"2022-10-03T16:06:11.196512\",\n", + " \"id\": 3,\n", + " \"status\": \"ready\",\n", + " \"updated_at\": \"2022-10-03T16:06:11.196512\"\n", + " }\n", + " ],\n", + " \"total_file_events\": 5,\n", + " \"updated_at\": \"2022-10-03T16:06:10.177291\",\n", + " \"user\": {\n", + " \"active\": true,\n", + " \"admin\": false,\n", + " \"groups\": [],\n", + " \"username\": \"dev\"\n", + " }\n", + " }\n", + " ],\n", + " \"deleted\": null,\n", + " \"description\": \"sigma_events\",\n", + " \"id\": 1,\n", + " \"label_string\": \"\",\n", + " \"name\": \"sigma_events\",\n", + " \"searchindex\": {\n", + " \"created_at\": \"2022-10-03T16:05:59.322881\",\n", + " \"deleted\": null,\n", + " \"description\": \"sigma_events\",\n", + " \"id\": 1,\n", + " \"index_name\": \"af23d06fb58b409a849571a18115e4ba\",\n", + " \"label_string\": \"[\\\"csv_jsonl\\\"]\",\n", + " \"name\": \"sigma_events\",\n", + " \"status\": [\n", + " {\n", + " \"created_at\": \"2022-10-03T16:06:11.211541\",\n", + " \"id\": 4,\n", + " \"status\": \"ready\",\n", + " \"updated_at\": \"2022-10-03T16:06:11.211541\"\n", + " }\n", + " ],\n", + " \"updated_at\": \"2022-10-03T16:05:59.322881\",\n", + " \"user\": {\n", + " \"active\": true,\n", + " \"admin\": false,\n", + " \"groups\": [],\n", + " \"username\": \"dev\"\n", + " }\n", + " },\n", + " \"status\": [\n", + " {\n", + " \"created_at\": \"2022-10-03T16:06:11.204530\",\n", + " \"id\": 3,\n", + " \"status\": \"ready\",\n", + " \"updated_at\": \"2022-10-03T16:06:11.204530\"\n", + " }\n", + " ],\n", + " \"updated_at\": \"2022-10-03T16:05:59.389141\",\n", + " \"user\": {\n", + " \"active\": true,\n", + " \"admin\": false,\n", + " \"groups\": [],\n", + " \"username\": \"dev\"\n", + " }\n", + " }\n", + " ],\n", + " \"all_permissions\": \"{\\\"user/dev\\\": [\\\"read\\\", \\\"write\\\", \\\"delete\\\"], \\\"is_public\\\": false}\",\n", + " \"created_at\": \"2022-10-03T16:05:52.851371\",\n", + " \"description\": \"aaa\",\n", + " \"graphs\": [],\n", + " \"id\": 1,\n", + " \"label_string\": \"\",\n", + " \"my_permissions\": \"[\\\"read\\\", \\\"write\\\", \\\"delete\\\"]\",\n", + " \"name\": \"aaa\",\n", + " \"status\": [\n", + " {\n", + " \"created_at\": \"2022-10-03T16:05:52.851371\",\n", + " \"id\": 1,\n", + " \"status\": \"new\",\n", + " \"updated_at\": \"2022-10-03T16:05:52.851371\"\n", + " }\n", + " ],\n", + " \"timelines\": [\n", + " {\n", + " \"color\": \"F37979\",\n", + " \"created_at\": \"2022-10-03T16:05:59.389141\",\n", + " \"datasources\": [\n", + " {\n", + " \"context\": \"sigma_events.csv\",\n", + " \"created_at\": \"2022-10-03T16:05:59.408345\",\n", + " \"data_label\": \"\",\n", + " \"error_message\": \"\",\n", + " \"file_on_disk\": \"/tmp/0c12b9e8d7e04ac5aa6f6c7f4166759d\",\n", + " \"file_size\": 702,\n", + " \"id\": 1,\n", + " \"original_filename\": \"sigma_events.csv\",\n", + " \"provider\": \"WebUpload\",\n", + " \"status\": [\n", + " {\n", + " \"created_at\": \"2022-10-03T16:06:11.196512\",\n", + " \"id\": 3,\n", + " \"status\": \"ready\",\n", + " \"updated_at\": \"2022-10-03T16:06:11.196512\"\n", + " }\n", + " ],\n", + " \"total_file_events\": 5,\n", + " \"updated_at\": \"2022-10-03T16:06:10.177291\",\n", + " \"user\": {\n", + " \"active\": true,\n", + " \"admin\": false,\n", + " \"groups\": [],\n", + " \"username\": \"dev\"\n", + " }\n", + " }\n", + " ],\n", + " \"deleted\": null,\n", + " \"description\": \"sigma_events\",\n", + " \"id\": 1,\n", + " \"label_string\": \"\",\n", + " \"name\": \"sigma_events\",\n", + " \"searchindex\": {\n", + " \"created_at\": \"2022-10-03T16:05:59.322881\",\n", + " \"deleted\": null,\n", + " \"description\": \"sigma_events\",\n", + " \"id\": 1,\n", + " \"index_name\": \"af23d06fb58b409a849571a18115e4ba\",\n", + " \"label_string\": \"[\\\"csv_jsonl\\\"]\",\n", + " \"name\": \"sigma_events\",\n", + " \"status\": [\n", + " {\n", + " \"created_at\": \"2022-10-03T16:06:11.211541\",\n", + " \"id\": 4,\n", + " \"status\": \"ready\",\n", + " \"updated_at\": \"2022-10-03T16:06:11.211541\"\n", + " }\n", + " ],\n", + " \"updated_at\": \"2022-10-03T16:05:59.322881\",\n", + " \"user\": {\n", + " \"active\": true,\n", + " \"admin\": false,\n", + " \"groups\": [],\n", + " \"username\": \"dev\"\n", + " }\n", + " },\n", + " \"status\": [\n", + " {\n", + " \"created_at\": \"2022-10-03T16:06:11.204530\",\n", + " \"id\": 3,\n", + " \"status\": \"ready\",\n", + " \"updated_at\": \"2022-10-03T16:06:11.204530\"\n", + " }\n", + " ],\n", + " \"updated_at\": \"2022-10-03T16:05:59.389141\",\n", + " \"user\": {\n", + " \"active\": true,\n", + " \"admin\": false,\n", + " \"groups\": [],\n", + " \"username\": \"dev\"\n", + " }\n", + " }\n", + " ],\n", + " \"updated_at\": \"2022-10-03T16:05:52.851371\",\n", + " \"user\": {\n", + " \"active\": true,\n", + " \"admin\": false,\n", + " \"groups\": [],\n", + " \"username\": \"dev\"\n", + " }\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get Sigma rules" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'API Client: 20221005\\nTS Backend: 20210602'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ts_client.version" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Deprecated, please use list_sigmarules() instead\n" + ] + } + ], + "source": [ + "sigme_rule = ts_client.list_sigmarules(as_pandas=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
authorcreated_atdatedescriptiondetectionfalsepositivesfile_nameidlevellogsourcemodifiedreferencesrule_uuidrule_yamlsearch_querystatustagstitleupdated_at
0None2022-10-04 15:10:27.6971842022/10/04Detects suspicious FOOBAR{'condition': 'keywords', 'keywords': ['*fooba...[Unknown]N/A7f4d2d41-19f9-4427-9227-1ef288247f52medium{'product': 'google_workspace', 'service': 'go...2022/10/04[https://]7f4d2d41-19f9-4427-9227-1ef288247f52title: Foobar\\nid: 7f4d2d41-19f9-4427-9227-1ef...*foobar2*experimental[None]Foobar2022-10-04 16:40:49.916821
1None2022-10-04 16:48:25.6205482022/10/04Detects suspicious FOOBAR{'condition': 'keywords', 'keywords': ['*fooba...[Unknown]N/Af71185d4-f2a2-4054-85b3-94c3ac9ce438medium{'category': 'process_creation', 'product': 'l...2022/10/04[https://]f71185d4-f2a2-4054-85b3-94c3ac9ce438title: Foobar\\nid: f71185d4-f2a2-4054-85b3-94c...(data_type:(\"shell:zsh:history\" OR \"bash:histo...experimental[None]Foobar2022-10-04 16:48:25.620548
2None2022-10-04 16:49:04.4032462022/10/04Detects suspicious FOOBAR{'condition': 'keywords', 'keywords': ['*zmap*']}[Unknown]N/A1289ad6d-1801-44aa-94f6-e16e596028b5medium{'category': 'clamav', 'product': 'linux'}2022/10/04[https://]1289ad6d-1801-44aa-94f6-e16e596028b5title: Foobar\\nid: 1289ad6d-1801-44aa-94f6-e16...*zmap*experimental[None]Foobar2022-10-04 16:49:04.403246
\n", + "
" + ], + "text/plain": [ + " author created_at date description \\\n", + "0 None 2022-10-04 15:10:27.697184 2022/10/04 Detects suspicious FOOBAR \n", + "1 None 2022-10-04 16:48:25.620548 2022/10/04 Detects suspicious FOOBAR \n", + "2 None 2022-10-04 16:49:04.403246 2022/10/04 Detects suspicious FOOBAR \n", + "\n", + " detection falsepositives file_name \\\n", + "0 {'condition': 'keywords', 'keywords': ['*fooba... [Unknown] N/A \n", + "1 {'condition': 'keywords', 'keywords': ['*fooba... [Unknown] N/A \n", + "2 {'condition': 'keywords', 'keywords': ['*zmap*']} [Unknown] N/A \n", + "\n", + " id level \\\n", + "0 7f4d2d41-19f9-4427-9227-1ef288247f52 medium \n", + "1 f71185d4-f2a2-4054-85b3-94c3ac9ce438 medium \n", + "2 1289ad6d-1801-44aa-94f6-e16e596028b5 medium \n", + "\n", + " logsource modified references \\\n", + "0 {'product': 'google_workspace', 'service': 'go... 2022/10/04 [https://] \n", + "1 {'category': 'process_creation', 'product': 'l... 2022/10/04 [https://] \n", + "2 {'category': 'clamav', 'product': 'linux'} 2022/10/04 [https://] \n", + "\n", + " rule_uuid \\\n", + "0 7f4d2d41-19f9-4427-9227-1ef288247f52 \n", + "1 f71185d4-f2a2-4054-85b3-94c3ac9ce438 \n", + "2 1289ad6d-1801-44aa-94f6-e16e596028b5 \n", + "\n", + " rule_yaml \\\n", + "0 title: Foobar\\nid: 7f4d2d41-19f9-4427-9227-1ef... \n", + "1 title: Foobar\\nid: f71185d4-f2a2-4054-85b3-94c... \n", + "2 title: Foobar\\nid: 1289ad6d-1801-44aa-94f6-e16... \n", + "\n", + " search_query status tags \\\n", + "0 *foobar2* experimental [None] \n", + "1 (data_type:(\"shell:zsh:history\" OR \"bash:histo... experimental [None] \n", + "2 *zmap* experimental [None] \n", + "\n", + " title updated_at \n", + "0 Foobar 2022-10-04 16:40:49.916821 \n", + "1 Foobar 2022-10-04 16:48:25.620548 \n", + "2 Foobar 2022-10-04 16:49:04.403246 " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sigme_rule" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "new_rule = '''\n", + "title: Installation of foobar\n", + "id: bb1e0d1d-cd13-4b65-bf7e-69b4e740266ba\n", + "description: Detects suspicious installation of foobar\n", + "references:\n", + " - https://samle.com/foobar\n", + "author: Alexander Jaeger\n", + "date: 2020/12/10\n", + "modified: 2020/12/10\n", + "logsource:\n", + " product: linux\n", + " service: shell\n", + "detection:\n", + " keywords:\n", + " # Generic suspicious commands\n", + " - '*apt-get install foobar*'\n", + " condition: keywords\n", + "falsepositives:\n", + " - Unknown\n", + "level: high\n", + "'''" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "result = ts_client.create_sigmarule(new_rule)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'experimental'" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result.status" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "# Provide a path where a rule is stored\n", + "\n", + "RULE_File = '/usr/local/google/home/jaegeral/dev/timesketch/data/sigma/rules/lnx_susp_zmap.yml'\n", + "\n", + "with open(RULE_File, 'r') as sigma_rule_file:\n", + " sigma_rule = sigma_rule_file.read()\n", + " \n", + "#sigma_config = sigma_configuration.SigmaConfiguration(sigma_config)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"title: Suspicious Installation of ZMap\\nid: 5266a592-b793-11ea-b3de-0242ac130004\\ndescription: Detects suspicious installation of ZMap\\nreferences:\\n - https://rmusser.net/docs/ATT&CK-Stuff/ATT&CK/Discovery.html\\nauthor: Alexander Jaeger\\ndate: 2020/06/26\\nmodified: 2020/06/26\\ntags:\\n - attack.discovery\\n - attack.t1046\\nlogsource:\\n product: linux\\n service: shell\\ndetection:\\n keywords:\\n # Generic suspicious commands\\n - '*apt-get install zmap*'\\n condition: keywords\\nfalsepositives:\\n - Unknown\\nlevel: high\\n\"" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check that the file is actually read\n", + "sigma_rule" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Deprecated, use SigmaRule object instead\n" + ] + }, + { + "data": { + "text/plain": [ + "'(data_type:(\"shell:zsh:history\" OR \"bash:history:command\" OR \"apt:history:line\" OR \"selinux:line\") AND \"apt-get install zmap\")'" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "parsed_rule = ts_client.parse_sigmarule_by_text(sigma_rule)\n", + "parsed_rule.search_query" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Failed response: [403] Rule 5266a592-b793-11ea-b3de-0242ac130004 was already found in the database FORBIDDEN\n", + "Failed response: [403] Rule 5266a592-b793-11ea-b3de-0242ac130004 was already found in the database FORBIDDEN\n", + "Failed response: [403] Rule 5266a592-b793-11ea-b3de-0242ac130004 was already found in the database FORBIDDEN\n", + "Failed response: [403] Rule 5266a592-b793-11ea-b3de-0242ac130004 was already found in the database FORBIDDEN\n", + "Failed response: [403] Rule 5266a592-b793-11ea-b3de-0242ac130004 was already found in the database FORBIDDEN\n" + ] + }, + { + "ename": "RuntimeError", + "evalue": "Unable to create a new Sigma Rule.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [32], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mts_client\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate_sigmarule\u001b[49m\u001b[43m(\u001b[49m\u001b[43msigma_rule\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/dev/timesketch/api_client/python/timesketch_api_client/client.py:678\u001b[0m, in \u001b[0;36mTimesketchApi.create_sigmarule\u001b[0;34m(self, rule_yaml)\u001b[0m\n\u001b[1;32m 675\u001b[0m retry_count \u001b[39m+\u001b[39m\u001b[39m=\u001b[39m \u001b[39m1\u001b[39m\n\u001b[1;32m 677\u001b[0m \u001b[39mif\u001b[39;00m retry_count \u001b[39m>\u001b[39m\u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mDEFAULT_RETRY_COUNT:\n\u001b[0;32m--> 678\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39mUnable to create a new Sigma Rule.\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[1;32m 680\u001b[0m rule_uuid \u001b[39m=\u001b[39m objects[\u001b[39m0\u001b[39m][\u001b[39m\"\u001b[39m\u001b[39mrule_uuid\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[1;32m 681\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mget_sigmarule(rule_uuid)\n", + "\u001b[0;31mRuntimeError\u001b[0m: Unable to create a new Sigma Rule." + ] + } + ], + "source": [ + "ts_client.create_sigmarule(sigma_rule)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# you can only add the same rule once:\n", + "\n", + "ts_client.create_sigmarule(sigma_rule)\n", + "\n", + "# will give you:\n", + "# Failed response: [403] Rule 5266a592-b793-11ea-b3de-0242ac130004 was already found in the database FORBIDDEN" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.7 ('.venv': pipenv)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.7" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "a34c381f30693eab9e91429498d23c5bee65cfe0188b27a9a25a7dd65b2078b0" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Sigma_test_Notebook.ipynb b/notebooks/Sigma_test_Notebook.ipynb new file mode 100644 index 0000000000..f81d47710b --- /dev/null +++ b/notebooks/Sigma_test_Notebook.ipynb @@ -0,0 +1,423 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Sigma example notebook\n", + "\n", + "This notebook should showcase some use cases with regards to Sigma." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -q timesketch_api_client\n", + "!pip install -q timesketch_import_client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from timesketch_api_client import client as timesketch_client\n", + "\n", + "import requests\n", + "import io\n", + "import altair as alt\n", + "import numpy as np\n", + "import pandas as pd\n", + "from timesketch_api_client import config\n", + "from timesketch_import_client import helper\n", + "from timesketch_import_client import importer\n", + "from timesketch_api_client import search" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create the sketch and import some data\n", + "\n", + "First we want to create a sketch and import a small data set. It is recommended to do that with the dev docker container." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ts_client = config.get_client()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We create a new sketch\n", + "\n", + "That will be called test and will be filled with some test data from the Github repository.\n", + "\n", + "The downloaded csv will be read into a pandas dataframe for further processing." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketch = ts_client.create_sketch(name=\"test\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "url = \"https://raw.githubusercontent.com/google/timesketch/master/tests/test_events/sigma_events.csv\" \n", + "download = requests.get(url).content" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.read_csv(io.StringIO(download.decode('utf-8')))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df.head(4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Import the data to timesketch\n", + "\n", + "The easiest way to do that is using the import client as shown below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper) \n", + "\n", + " streamer.set_timeline_name('sigma_events.csv')\n", + " streamer.add_data_frame(df)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Fetch Rules\n", + "\n", + "Now we want to fetch all the rules installed on the Timesketch instance. For the dev docker container we only expect one rule.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rules = ts_client.list_sigmarules()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for rule in rules:\n", + " print(f'ID: {rule.id} Title: {rule.title}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rule1 = rules[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The API also gives us the elastic search query we could use to explore the data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rule1.search_query" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create a rule\n", + "\n", + "Lets create a single rule from a string" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ZENMAPSIGMARULE = \"\"\"\n", + "title: Suspicious Installation of Zenmap\n", + "id: 5266a592-b793-11ea-b3de-0242ac130004\n", + "description: Detects suspicious installation of Zenmap\n", + "references:\n", + " - https://rmusser.net/docs/ATT&CK-Stuff/ATT&CK/Discovery.html\n", + "author: Alexander Jaeger\n", + "date: 2020/06/26\n", + "modified: 2021/01/01\n", + "logsource:\n", + " product: linux\n", + " service: shell\n", + "detection:\n", + " keywords:\n", + " # Generic suspicious commands\n", + " - '*apt-get install zmap*'\n", + " condition: keywords\n", + "falsepositives:\n", + " - Unknown\n", + "level: high\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ts_client.create_sigmarule(ZENMAPSIGMARULE)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Single rule\n", + "\n", + "Next we want to fetch a single rule by a given uuid." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "single_rule = ts_client.get_sigmarule(rule_uuid='5266a592-b793-11ea-b3de-0242ac130004')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "single_rule.id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "single_rule.search_query" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Text Sigma examples\n", + "\n", + "The API also provides the option to provide a Sigma rule by text and the backend will parse it with the installed Sigma mappings. This can be especially helpful when developing new rules before installing and exposing them to all the other user of a Timesketch instance." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "MOCK_SIGMA_RULE = r\"\"\"\n", + "title: Suspicious Installation of Zenmap\n", + "id: 5266a592-b793-11ea-b3de-0242ac130004\n", + "description: Detects suspicious installation of Zenmap\n", + "references:\n", + " - https://rmusser.net/docs/ATT&CK-Stuff/ATT&CK/Discovery.html\n", + "author: Alexander Jaeger\n", + "date: 2020/06/26\n", + "modified: 2021/01/01\n", + "logsource:\n", + " product: linux\n", + " service: shell\n", + "detection:\n", + " keywords:\n", + " # Generic suspicious commands\n", + " - '*apt-get install zmap*'\n", + " condition: keywords\n", + "falsepositives:\n", + " - Unknown\n", + "level: high\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rule_by_text = ts_client.parse_sigmarule_by_text(MOCK_SIGMA_RULE)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rule_by_text.search_query" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rule_by_text.references" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Analyzer\n", + "\n", + "Timesketch also has a Sigma analyzer that will add labels to all matching events. To do so you need a Timeline object to run the analyzer. The Analyzer then will take all rules installed on the Timesketch instance and go over the Timeline." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "timelines = sketch.list_timelines()\n", + "timeline = None\n", + "for timeline_ in timelines:\n", + " if timeline_.name == 'sigma_events.csv':\n", + " timeline = timeline_\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result = timeline.run_analyzer(analyzer_name='sigma', ignore_previous=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketch.get_analyzer_status()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This should show something like:\n", + "```\n", + "[{'index': ,\n", + " 'timeline_id': 1,\n", + " 'session_id': 1,\n", + " 'analyzer': 'sigma',\n", + " 'results': 'Applied 1 tags\\n* lnx_susp_zenmap.yml: 1\\nProblematic rules:',\n", + " 'status': 'DONE'}]\n", + "```" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + }, + "metadata": { + "interpreter": { + "hash": "2556566ac8fd219b8b3cb0c76c8e4f226085ddd0e18628d37e0282e6a68fc0ff" + } + }, + "orig_nbformat": 2, + "vscode": { + "interpreter": { + "hash": "a34c381f30693eab9e91429498d23c5bee65cfe0188b27a9a25a7dd65b2078b0" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Stolen_Szechuan_Sauce_Analysis.ipynb b/notebooks/Stolen_Szechuan_Sauce_Analysis.ipynb new file mode 100644 index 0000000000..75dc93bbeb --- /dev/null +++ b/notebooks/Stolen_Szechuan_Sauce_Analysis.ipynb @@ -0,0 +1,3243 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Stolen Szechuan Sauce - Analysis.ipynb", + "private_outputs": true, + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "STgOOx_i9NKV" + }, + "source": [ + "# The Case of The Stolen Szechuan Sauce\n", + "\n", + "This is a simple colab demonstrating one way of analyzing data from the Stolen Szechuan Sauce challenge (found [here](https://dfirmadness.com/the-stolen-szechuan-sauce/)).\n", + "\n", + "This colab will not go into any of the data upload. It assumes that all data is already collected and uploaded to Timesketch. To see one way of uploading the data to Timesketch, use [this colab](https://colab.research.google.com/github/google/timesketch/blob/master/notebooks/Stolen_Szechuan_Sauce_Data_Upload.ipynb)\n", + "\n", + "For a more generic instructions of Colab can be [found here](https://colab.research.google.com/github/google/timesketch/blob/master/notebooks/colab-timesketch-demo.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uy3o_dS2T6hg" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VlUAyi73BJUI" + }, + "source": [ + "If you are running this on a cloud runtime you'll need to install these dependencies:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YywEaQSTBOjH" + }, + "source": [ + "# @markdown Only execute if not already installed and running a cloud runtime\n", + "!pip install -q timesketch_api_client\n", + "!pip install -q vt-py nest_asyncio pandas\n", + "!pip install -q picatrix" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fi9-7n--lXOV", + "cellView": "form" + }, + "source": [ + "# @title Import libraries\n", + "# @markdown This cell will import all the libraries needed for the running of this colab.\n", + "\n", + "import re\n", + "import requests\n", + "\n", + "import pandas as pd\n", + "\n", + "from timesketch_api_client import config\n", + "from picatrix import notebook_init\n", + "\n", + "import vt\n", + "import nest_asyncio # https://github.com/VirusTotal/vt-py/issues/21\n", + "\n", + "nest_asyncio.apply()\n", + "notebook_init.init()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MQg0I0Cl6ecu", + "cellView": "form" + }, + "source": [ + "# @title VirusTotal Configuration\n", + "# @markdown In order to be able to lookup domains/IPs/samples using VirtusTotal we need to get an API key.\n", + "# @markdown\n", + "# @markdown If you don't have an API key you must sign up to [VirusTotal Community](https://www.virustotal.com/gui/join-us).\n", + "# @markdown Once you have a valid VirusTotal Community account you will find your personal API key in your personal settings section. \n", + "\n", + "VT_API_KEY = '' # @param {type: \"string\"}\n", + "\n", + "# @markdown If you don't have the API key you will not be able to use the Virustotal API\n", + "# @markdown to lookup information." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "REUKmoy_G1p_", + "cellView": "form" + }, + "source": [ + "# @title Declare functions\n", + "\n", + "# @markdown This cell will define few functions that we will use throughout\n", + "# @markdown this colab. This would be better to define outside of the notebook\n", + "# @markdown in a library that would be imported, but we keep it here for now.\n", + "\n", + "def print_dict(my_dict, space_before=0):\n", + " \"\"\"Print the content of a dictionary.\"\"\"\n", + " max_len = max([len(x) for x in my_dict.keys()])\n", + " spaces = ' '*space_before\n", + " format_str = f'{spaces}{{key:{max_len}s}} = {{value}}'\n", + " for key, value in my_dict.items():\n", + " if isinstance(value, dict):\n", + " print(format_str.format(key=key, value=''))\n", + " print_dict(value, space_before=space_before + 8)\n", + " elif isinstance(value, list):\n", + " value_str = ', '.join(value)\n", + " print(format_str.format(key=key, value=value_str))\n", + " else:\n", + " print(format_str.format(key=key, value=value))\n", + "\n", + "\n", + "def ip_info(address):\n", + " \"\"\"Print out information about an IP address using the VT API.\"\"\"\n", + " url = 'https://www.virustotal.com/vtapi/v2/ip-address/report'\n", + " params = {\n", + " 'apikey': VT_API_KEY,\n", + " 'ip': address}\n", + "\n", + " response = requests.get(url, params=params)\n", + " j_obj = response.json()\n", + "\n", + " def _print_stuff(part):\n", + " print('')\n", + " header = part.replace('_', ' ').capitalize()\n", + " print(f'{header}:')\n", + " for item in j_obj.get(part, []):\n", + " print_dict(item, 2)\n", + "\n", + " _print_stuff('resolutions')\n", + " _print_stuff('detected_urls')\n", + " _print_stuff('detected_referrer_samples')\n", + " _print_stuff('detected_communicating_samples')\n", + " _print_stuff('detected_downloaded_samples')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FiPTLA-qlkWQ", + "cellView": "form" + }, + "source": [ + "# @markdown Get a copy of the Timesketch client object.\n", + "# @markdown Parameters to configure the client:\n", + "# @markdown + host_uri: https://demo.timesketch.org\n", + "# @markdown + username: demo\n", + "# @markdown + auth_mode: timesketch (username/password)\n", + "# @markdown + password: demo\n", + "\n", + "ts_client = config.get_client(confirm_choices=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hkQ98MnC-x3p" + }, + "source": [ + "Now that we've got a copy of the TS client we need to get to the sketch." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RN5fKCshls9L" + }, + "source": [ + "for sketch in ts_client.list_sketches():\n", + " if not sketch.name.startswith('Szechuan'):\n", + " continue\n", + "\n", + " print('We found the sketch to use')\n", + " print(f'[{sketch.id}] {sketch.name} - {sketch.description}')\n", + " break" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bpz29qgAGLFt" + }, + "source": [ + "OK, sketch nr 6 is the one that we are after, let's set that as the active sketch. This is something that the Timesketch picatrix magics expect, that is to first set the active sketch that you will be using. After that all the magics don't need sketch definitions." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pO76nz3TGZAH" + }, + "source": [ + "%timesketch_set_active_sketch 6" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R6kRDR2fToLC" + }, + "source": [ + "To learn more about picatrix and how it works, please use the magic `%picatrixmagics` and see what magics are available and then use `%magic --help` or `magic_func?` to see more information about that magic.\n", + "\n", + "One such example could be:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RJheDxzhTxS2" + }, + "source": [ + "timesketch_list_saved_searches_func?" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2Ir9TevSLGBq" + }, + "source": [ + "## Pre-Thoughts" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xgwQlv1FLHzx" + }, + "source": [ + "Timesketch analyzers can provide quite a lot of value to any analysis. They can do pretty much everything that can be achieved in a colab like this, and in the Timesketch UI, except programatically. In this case, one of the very valuable analyzers is the `logon` analyzer. That analyzer will look for evidence of logons, and then extract values out of the logon entries and add them to the dataset.\n", + "\n", + "Another potentially valuable analyzer is browser search, etc. To get a history of what analyzers have been run you can visit [this page](https://demo.timesketch.org/sketch/6/manage/timelines) or run the following code snippet:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kIjGq8dmMYJv" + }, + "source": [ + "for status in sketch.get_analyzer_status():\n", + " print(f'Analyzer: {status[\"analyzer\"]} - status: {status[\"status\"]}')\n", + " print(f'Results: {status[\"results\"]}')\n", + " print('')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lLlaWPgi_o1r" + }, + "source": [ + "From there you can get a glance at what has analysis has been done on the dataset, and what the results were.. for instance that `login` was completed and it found several logon and logoff entries.\n", + "\n", + "However now we can start answering the questions.\n", + "\n", + "## Questions" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kNyG9uur_1xK" + }, + "source": [ + "### What’s the Operating System of the Server?\n", + "\n", + "Let's start exploring this, OS information is stored in the registry. Let's query it" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_gDu_58uk3Go" + }, + "source": [ + "search_query = timesketch_query_func(\n", + " 'parser:\"winreg/windows_version\"',\n", + " fields='datetime,key_path,data_type,message,timestamp_desc,parser,display_name,product_name,hostname,timestamp_desc'\n", + ")\n", + "cur_df = search_query.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "hfAIKnt-EKak" + }, + "source": [ + "cur_df[['hostname', 'product_name']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mQ4RxzwnDrbu" + }, + "source": [ + "So we now have the all the data, we can read the data from the table or do one more filtering to get the answer:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "x01scNWNG9Zn" + }, + "source": [ + "cur_df[cur_df.hostname == 'CITADEL-DC01'].product_name.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2ksIYrrI_8Be" + }, + "source": [ + "### What’s the Operating System of the Desktop?\n", + "\n", + "we can use the same data as we collected before:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jDRnhdlUHG4S" + }, + "source": [ + "cur_df[cur_df.hostname == 'DESKTOP-SDN1RPT'].product_name.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wrpH_DttAejS" + }, + "source": [ + "### What was the local time of the Server?\n", + "\n", + "To answer that we need to get the current control set" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XRo0pe4eJyMi" + }, + "source": [ + "cur_df = timesketch_query_func(\n", + " 'HKEY_LOCAL_MACHINE*System*Select AND hostname:\"CITADEL-DC01\"',\n", + " fields=(\n", + " 'datetime,key_path,data_type,message,timestamp_desc,parser,display_name,'\n", + " 'product_name,hostname,timestamp_desc,values')\n", + ").table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oPECs_jt_T_H" + }, + "source": [ + "Now let's look at what the value is set for the key." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1TwaMYZBJ2ce" + }, + "source": [ + "for key, value in cur_df[['key_path', 'values']].values:\n", + " print(f'Key: {key}')\n", + " print(f'Value: {value}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1taojYh2_kDX" + }, + "source": [ + "We can parse this out a bit more if we want to, or just read from there that the current value is 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MaRYpTIN_on9" + }, + "source": [ + "cur_df['current_value'] = cur_df['values'].str.extract(r'Current: \\[[A-Z_]+\\] (\\d) ')\n", + "\n", + "cur_df[['key_path', 'current_value']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VSAo1MWHJ-vP" + }, + "source": [ + "The current one is set 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "duOb8qURKJpn" + }, + "source": [ + "cur_df = timesketch_query_func(\n", + " 'TimeZoneInformation AND hostname:\"CITADEL-DC01\"',\n", + " fields='datetime,key_path,data_type,message,timestamp_desc,parser,display_name,product_name,hostname,timestamp_desc,configuration'\n", + ").table\n", + "cur_df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VTkHkocEB9Iy" + }, + "source": [ + "Let's increase the column with for pandas, that will make it easier to read columns with longer text in them." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LQIF_bVFLYLt" + }, + "source": [ + "pd.set_option('max_colwidth', 400)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3ZeK5sfCKcwi" + }, + "source": [ + "cur_df[cur_df.key_path.str.contains('ControlSet001')][['configuration']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IJMrF5txAjHm" + }, + "source": [ + "So we need to extract what is in `TimeZoneKeyName`, we can do this differently. For now we can just read the configuration field, and then split it into a dict and then construct a new DataFrame with these fields, that is taking a line that is `key1: value1 key2: value2 ...` and creating a data frame with `key1, key2, ...` being the column names." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eBSQDEI33wdH" + }, + "source": [ + "lines = []\n", + "\n", + "for value in cur_df[cur_df.key_path.str.contains('ControlSet001')]['configuration'].values:\n", + " items = value.split(':')\n", + " line_dict = {}\n", + " key = items[0]\n", + " for item in items[1:-1]:\n", + " *values, new_key = item.split()\n", + "\n", + " line_dict[key] = ' '.join(values)\n", + " key = new_key\n", + "\n", + " line_dict[key] = items[-1]\n", + " lines.append(line_dict)\n", + "\n", + "time_df = pd.DataFrame(lines)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LG_9D9mzCBrX" + }, + "source": [ + "Let's look at the newly constructed data frame" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cgtctQ_hCEfi" + }, + "source": [ + "time_df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9f4lPffKEByw" + }, + "source": [ + "Then we've got the time zone of the server, which is `Pacific Standard Time`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oNZXvnc5Ajs1" + }, + "source": [ + "### What was the initial entry vector (how did they get in)?\n", + "\n", + "If we assume they got in from externally, doing some statistics on the network data might be useful. For that we need to do some aggregations.\n", + "\n", + "First to understand what aggregations are available to use, and how to use them, let's use the `list_available_aggregators` which produces a data frame with the names of the aggregators and what parameters they need for configuration.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y76Xnu7AEmO8" + }, + "source": [ + "%timesketch_available_aggregators" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QHok29TaExGy" + }, + "source": [ + "Now that we know what aggregators are available, let's start with aggregating the field `Source`, and get the top 10.\n", + "\n", + "For that we need to use the `field_bucket` aggregator, and configuring it using the parameters `field`, `limit` and `supported_charts`.\n", + "\n", + "The charts that are available are:\n", + " + barchart\n", + " + hbarchart\n", + " + table\n", + " + circlechart\n", + " + linechart\n", + "\n", + "For this let's use a horizontal bar chart, `hbarchart`" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gLMtyrWtLqLj" + }, + "source": [ + "params = {\n", + " 'field': 'Source',\n", + " 'limit': 10,\n", + " 'supported_charts': 'hbarchart',\n", + " 'chart_title': 'Top 10 Source IP',\n", + "}\n", + "\n", + "aggregation = timesketch_run_aggregator_func(\n", + " 'field_bucket', parameters=params\n", + ")\n", + "aggregation.chart" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X0oGT9mk0B5D" + }, + "source": [ + "If you are viewing this as in Colab but connecting to a local runtime you may need to enable this in order to be able to view the charts:\n", + "\n", + "(if it doesn't work, uncomment the code that is applicable to you and then re-run the aggregation cell)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0VqBw5ovz4p5" + }, + "source": [ + "# Remove the commend and run this code if you are running in colab\n", + "# but have a local Jupyter kernel running:\n", + "# alt.renderers.enable('colab')\n", + "\n", + "# Remove this comment if you are running in Jupyter and the chart is not displayed\n", + "# alt.renderers.enable('notebook')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GHNhwNsGFSUH" + }, + "source": [ + "If you prefer to get the data frame instead of the chart you can call `aggregation.table`" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZFnInNAnFZYB" + }, + "source": [ + "aggregation.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0EsPZ5wyFbxY" + }, + "source": [ + "Now let's look at the `Destination` field, same as before:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WNauKP1OL1Ps" + }, + "source": [ + "params = {\n", + " 'field': 'Destination',\n", + " 'limit': 10,\n", + " 'supported_charts': 'hbarchart',\n", + " 'chart_title': 'Top 10 Source IP',\n", + "}\n", + "\n", + "aggregation = timesketch_run_aggregator_func('field_bucket', parameters=params)\n", + "aggregation.chart" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dm5dT3ZyL3rU" + }, + "source": [ + "We can clearly see that the ```194.61.24.102``` sticks out, so lets try to understand what this IP did. Also note that it is not common that a system from the internet tries to connect to a intranet IP." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w-QQPvb8MIgr" + }, + "source": [ + "#### A Look at IP 194.61.24.102" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Os8SYJiMM96R" + }, + "source": [ + "attacker_dst = timesketch_query_func(\n", + " 'Source:\"194.61.24.102\" AND data_type:\"pcap:wireshark:entry\"',\n", + " fields='datetime,message,timestamp_desc,Destination,DST port,Source,Protocol,src port').table\n", + "attacker_dst.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NQarJWFW_K4h" + }, + "source": [ + "OK, we can see that the API says we got 40k records returned but the search actually produced 128.328 records,so let's increase our max entries..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwIEey96_TUA" + }, + "source": [ + "search_obj = timesketch_query_func(\n", + " 'Source:\"194.61.24.102\" AND data_type:\"pcap:wireshark:entry\"',\n", + " fields='datetime,message,timestamp_desc,Destination,DST port,Source,Protocol,src port')\n", + "\n", + "search_obj.max_entries = 150000\n", + "attacker_dst = search_obj.table\n", + "attacker_dst.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yHK4xt7mGAz1" + }, + "source": [ + "We got a fairly large table, let's look at the size:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2_MxJxRqGE6L" + }, + "source": [ + "attacker_dst.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XFmjxrW2GHyf" + }, + "source": [ + "We will now need to do some aggregation on the data that we got, let's use pandas for that. For that there is a function called `groupby` where we can run aggregations.\n", + "\n", + "We want to group based on `DST port` and `Destination`, so we only need those two columns + one more to store the count/sum." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D0uY7rFeGW4u" + }, + "source": [ + "attacker_group = attacker_dst[['DST port','Destination', 'Protocol']].groupby(\n", + " ['DST port','Destination'], as_index=False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RWDgHXLdG37E" + }, + "source": [ + "Now we got a group, and to get a count, we can use the `count()` function of the group." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GZ2OEKNmG7NY" + }, + "source": [ + "attacker_dst_mytable = attacker_group.count()\n", + "attacker_dst_mytable.rename(columns={'Protocol': 'Count'}, inplace=True)\n", + "attacker_dst_mytable.sort_values(by=['Count'], ascending=False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0TWTkbGONNkj" + }, + "source": [ + "So we can already point out that there is a lot of traffic from this ip to ```10.42.85.10``` on port ```3389```which is used for Remote Desktop Protocol (RDP)\n", + "\n", + "Let's now look at the IP traffic as it was parsed by scapy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pmqx3AFHNlCc" + }, + "source": [ + "attacker_dst = timesketch_query_func(\n", + " '194.61.24.102 AND data_type:\"scapy:pcap:entry\"',\n", + " fields='datetime,message,timestamp_desc,ip_flags,ip_dst,ip_src,payload,tcp_flags,tcp_seq,tcp_sport,tcp_dport,tcp_window').table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QCbCRWmxH7ML" + }, + "source": [ + "Let's look at a few entries here:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "esIgaBjeOwCN" + }, + "source": [ + "attacker_dst.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-VfhmF4eIW2Q" + }, + "source": [ + "What we can see here is that quite a bit of the information is in the message field that we need to decode.\n", + "\n", + "We also see that the `evil` bit is set... we could query for that as well. Let's start there, to do an aggregation based on that." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fYpGly-JIe26" + }, + "source": [ + "params = {\n", + " 'field': 'ip_src',\n", + " 'query_string': 'ip_flags:\"evil\"',\n", + " 'supported_charts': 'hbarchart',\n", + " 'chart_title': 'Source IPs with \"evil\" bit set',\n", + "}\n", + "\n", + "aggregation = timesketch_run_aggregator_func('query_bucket', parameters=params)\n", + "aggregation.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7m7YfTJ5JZbw" + }, + "source": [ + "We could even save this (if you have write access to the sketch, which the demo user does not have)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GVfPCwpcJdjV" + }, + "source": [ + "name = 'Source IPs with \"evil\" bit set'\n", + "aggregation.name = name\n", + "aggregation.title = name\n", + "aggregation.save()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4zTQKnpJlm1" + }, + "source": [ + "And now we could use this in a story for instance.\n", + "\n", + "But let's move on and parse the message field:\n", + "\n", + "First let's look at a single entry. To see how it is constructed:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-l2C19JEJsSp" + }, + "source": [ + "attacker_dst.iloc[0].message" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZYX6y6yPPef3" + }, + "source": [ + "Now that we know that, let's first remove the `\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "myeER0OQAt1r" + }, + "source": [ + "# The Stolen Szechuan Sauce\n", + "\n", + "This is a simple colab demonstrating one way of uploading data from the Stolen Szechuan Sauce challenge (found [here](https://dfirmadness.com/the-stolen-szechuan-sauce/)).\n", + "\n", + "This colab will not go into any analysis of the data, only uploading data to a sketch.\n", + "\n", + "A word of notice, this notebook can be run on the cloud runtimes, but then few changes need to be made. However it is assumed that you are connecting to a local runtime, see [instructions here](https://research.google.com/colaboratory/local-runtimes.html). This makes it easier to import data that is already on your system.\n", + "\n", + "For a more generic instructions of Colab can be [found here](https://colab.research.google.com/github/google/timesketch/blob/master/notebooks/colab-timesketch-demo.ipynb)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "40A429x4Ajfc", + "cellView": "form" + }, + "source": [ + "# @title Import libraries\n", + "# @markdown This cell loads libraries that we will use througout the notebook.\n", + "import io\n", + "import os\n", + "import codecs\n", + "\n", + "import altair as alt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "from timesketch_api_client import config\n", + "from timesketch_import_client import helper\n", + "from timesketch_import_client import importer" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ITjKgNRtBBdx" + }, + "source": [ + "## AutoRuns File\n", + "\n", + "Let's read the file that contains the output of the AutoRuns file." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rxtTjR8RA8SB", + "cellView": "both" + }, + "source": [ + "# @markdown This needs to be changed to reflect the correct path.\n", + "\n", + "PATH_TO_FOLDER = '/mnt/chromeos/MyFiles/Downloads' # @param {type: \"string\"}\n", + "# @markdown the path to the folder will be used for all subsequent paths\n", + "# @markdown as a root folder.\n", + "AUTO_RUN_FILENAME = 'autoruns-desktop-sdn1rpt.csv' # @param {type: \"string\"}\n", + "\n", + "PATH_TO_CSV = os.path.join(PATH_TO_FOLDER, AUTO_RUN_FILENAME)\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LFKpjpo66pve" + }, + "source": [ + "Now we can read the content of the file:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L05NWGvRBC0R" + }, + "source": [ + "df = None\n", + "with codecs.open(PATH_TO_CSV, 'r', encoding='utf-8', errors='replace') as fh:\n", + " df = pd.read_csv(fh, error_bad_lines=False)\n", + "\n", + "print(df.shape)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TORG4J8CHI4P" + }, + "source": [ + "Quite a few errors, let's look at the data." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lOcjM6ECFVkj" + }, + "source": [ + "df.head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-_NPKhANJSc-" + }, + "source": [ + "This does not look right, let's look at the content of the file, let's look at the hex code (for that we will use the `!` which allows us to execute shell commands)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t-wWKfrEJW50" + }, + "source": [ + "!dd if=$PATH_TO_CSV bs=128 count=1 | xxd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ERWnpjHNJflb" + }, + "source": [ + "This file is not UTF-8, it's encoded as UTF-16, so let's now read the file in again, this time as UTF-16" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UPdW8UvlFvn1" + }, + "source": [ + "df = None\n", + "with codecs.open(PATH_TO_CSV, 'r', encoding='utf-16', errors='replace') as fh:\n", + " df = pd.read_csv(fh, error_bad_lines=False)\n", + "\n", + "print(df.shape)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8B4ew2-PJpj9" + }, + "source": [ + "No errors, let's look at the content" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3rs0U_wZH59M" + }, + "source": [ + "df.head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8hxAw8QKJslL" + }, + "source": [ + "This looks correct now, let's make the data a bit more Timesketch ready.\n", + "\n", + "The first thing is to create a datetime field that contains the timestamp. We will use the built-in conversion in pandas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qtn7JXS-Iob-" + }, + "source": [ + "df['datetime'] = pd.to_datetime(df['Time'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7deDQiar682s" + }, + "source": [ + "The next thing is to add few fields that Timesketch expects:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1sCIIv0YJ57-" + }, + "source": [ + "df['data_type'] = 'autoruns:record'\n", + "df['timestamp_desc'] = 'Entry Recorded'\n", + "df['message'] = 'AutoRun: [' + df['Category'] + ' - ' + df['Profile'] + '] ' + df['Image Path']\n", + "\n", + "df.head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v9Hivygb7Axp" + }, + "source": [ + "We can take a quick look at the data frame we just read in:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hQ7WkDPOM4mk" + }, + "source": [ + "df.info()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cUUjqZWUKIna" + }, + "source": [ + "### Upload To TS\n", + "\n", + "Let's upload this data to TS. For that we first need to get a copy of the Timesketch client, then we will need to get a copy of a sketch object." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VZWk8dRWKDRr" + }, + "source": [ + "ts_client = config.get_client()\n", + "[(x.id, x.name) for x in ts_client.list_sketches()]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0VEfTaLOBtZs" + }, + "source": [ + "# @markdown This needs to be changed to reflect the correct sketch.\n", + "\n", + "SKETCH_ID = 6 # @param {type: \"integer\"}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DFKwoCTi7NXm" + }, + "source": [ + "Now we are ready to upload the data. The sketch that we want to use is the one with the ID of 6.\n", + "\n", + "We will use the importer client to import the data as a data frame, for that we need to setup an import streamer:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "riyNlxSXKh4m" + }, + "source": [ + "sketch = ts_client.get_sketch(SKETCH_ID)\n", + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper) \n", + "\n", + " streamer.set_timeline_name('autoruns_desktop_sdn1rpt')\n", + "\n", + " streamer.add_data_frame(df)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xdJJbJfL7YVq" + }, + "source": [ + "What we did there was create a copy of the Import client, and then configured it (defining the sketch to use and what the name of the timeline we are going to choose)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6AWrR8-8MSs0" + }, + "source": [ + "Now this data has been uploaded to the sketch in TS but there is an error in TS import, that is if we go and visit the sketch we can see that the sketch hasn't been uploaded correctly, so let's copy the error here.\n", + "\n", + "Then we will delete/remove the timeline from the sketch so that there isn't an error one in TS.\n", + "\n", + "\n", + "```\n", + "Traceback (most recent call last):\n", + " File \"/usr/local/lib/python3.6/dist-packages/timesketch/lib/tasks.py\", line 558, in run_csv_jsonl\n", + " for event in read_and_validate(file_handle):\n", + " File \"/usr/local/lib/python3.6/dist-packages/timesketch/lib/utils.py\", line 225, in read_and_validate_jsonl\n", + " linedict['timestamp'] = parser.parse(linedict['datetime'])\n", + " File \"/usr/local/lib/python3.6/dist-packages/dateutil/parser/_parser.py\", line 1374, in parse\n", + " return DEFAULTPARSER.parse(timestr, **kwargs)\n", + " File \"/usr/local/lib/python3.6/dist-packages/dateutil/parser/_parser.py\", line 646, in parse\n", + " res, skipped_tokens = self._parse(timestr, **kwargs)\n", + " File \"/usr/local/lib/python3.6/dist-packages/dateutil/parser/_parser.py\", line 725, in _parse\n", + " l = _timelex.split(timestr) # Splits the timestr into tokens\n", + " File \"/usr/local/lib/python3.6/dist-packages/dateutil/parser/_parser.py\", line 207, in split\n", + " return list(cls(s))\n", + " File \"/usr/local/lib/python3.6/dist-packages/dateutil/parser/_parser.py\", line 76, in __init__\n", + " '{itype}'.format(itype=instream.__class__.__name__))\n", + "TypeError: Parser must be a string or character stream, not NoneType\n", + "```\n", + "\n", + "This does indicate issues with datetime parsing. Let's take a closer look at the data frame in question. The first thing we check is to see whether there are any empty dates in the frame:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "srRmvAEKMs0S" + }, + "source": [ + "df[df.datetime.isna()]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R-sFv9JmOj9V" + }, + "source": [ + "The check we use is `isna` which checks to see if a field is empty or (Not a number).\n", + "\n", + "There are quite a few records with an empty date field. Let's exclude those. For that we will need to upload a slice of the data frame that doesn't contain any records with an empty date." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s5U6sWVEOPDV" + }, + "source": [ + "df.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zcm01gnJOoWB" + }, + "source": [ + "df[~df.datetime.isna()].shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G5Xsyhl1OsHC" + }, + "source": [ + "There seem to be 9 records without a date... let's remove them from the upload (by just uploading a slice of the data)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gdrtzphrOqwM" + }, + "source": [ + "sketch = ts_client.get_sketch(SKETCH_ID)\n", + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper) \n", + "\n", + " streamer.set_timeline_name('autoruns_desktop_sdn1rpt_w_time')\n", + "\n", + " streamer.add_data_frame(df[~df.datetime.isna()].copy())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UKmKE3hbgHaR" + }, + "source": [ + "### Server AutoRun File\n", + "\n", + "Let's take the server Autoruns next" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vDFCbU41O1yx" + }, + "source": [ + "DC_FILENAME = 'autorunsc-citadel-dc01.csv' # @param {type: \"string\"}\n", + "\n", + "dc_path = os.path.join(PATH_TO_FOLDER, DC_FILENAME)\n", + "\n", + "auto_server_df = None\n", + "with codecs.open(dc_path, 'r', encoding='utf-16', errors='replace') as fh:\n", + " auto_server_df = pd.read_csv(fh, error_bad_lines=False)\n", + "\n", + "print(auto_server_df.shape)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mTYjxb01grgw" + }, + "source": [ + "Let's `groom` it for TS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-sxxS7CZgi3k" + }, + "source": [ + "auto_server_df['datetime'] = pd.to_datetime(df['Time'])\n", + "auto_server_df['data_type'] = 'autoruns:record'\n", + "auto_server_df['timestamp_desc'] = 'Entry Recorded'\n", + "auto_server_df['message'] = 'AutoRun: [' + auto_server_df['Category'] + ' - ' + auto_server_df['Profile'] + '] ' + auto_server_df['Image Path']\n", + "\n", + "auto_server_df.head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R8OhonO8g0ip" + }, + "source": [ + "And upload (using the same method as before)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SUeAQtEqgvfi" + }, + "source": [ + "sketch = ts_client.get_sketch(SKETCH_ID)\n", + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper) \n", + "\n", + " streamer.set_timeline_name('autoruns_citadel_dc01_w_time')\n", + "\n", + " streamer.add_data_frame(auto_server_df[~auto_server_df.datetime.isna()].copy())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mh2SAJOYhBBU" + }, + "source": [ + "Now we've got both autoruns in there\n", + "\n", + "## Plaso Files\n", + "\n", + "Let's in the plaso files, using:\n", + "\n", + "```shell\n", + "$ timesketch_importer --sketch_id 6 20200918_0417_DESKTOP-SDN1RPT.plaso \n", + "```\n", + "\n", + "or using the importer client in colab" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EiotgxxjxMUE", + "cellView": "form" + }, + "source": [ + "DESKTOP_PATH = '20200918_0417_DESKTOP-SDN1RPT.plaso' #@param {type: \"string\"}\n", + "SERVER_PATH = '20200918_0347_CDrive_new.plaso' #@param {type: \"string\"}\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q4ePXTVZg97K" + }, + "source": [ + "sketch = ts_client.get_sketch(SKETCH_ID)\n", + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper) \n", + "\n", + " streamer.set_timeline_name('desktop-sdn1rpt.plaso')\n", + " streamer.add_file(os.path.join(PATH_TO_FOLDER, DESKTOP_PATH))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UZYiobwO0-uj" + }, + "source": [ + "sketch = ts_client.get_sketch(SKETCH_ID)\n", + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper) \n", + "\n", + " streamer.set_timeline_name('dc1_plaso')\n", + " streamer.add_file(os.path.join(PATH_TO_FOLDER, SERVER_PATH))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7f_qM5Xd8HCL" + }, + "source": [ + "## PCAP Files\n", + "\n", + "Another important factor in the challenge are the provided PCAP files. We need to get them checked into TS.\n", + "\n", + "Let's start parsing them. There are essentially two different methods of doing so:\n", + "\n", + "1. Using Wireshark to do the parsing and work with a CSV file\n", + "2. Parse the PCAP file using python libraries and use that.\n", + "\n", + "Let's explore both options." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GfEUJ4z5NI6p" + }, + "source": [ + "### Wireshark Route\n", + "\n", + "Wireshark has a neat feature to export a set of packages or all packets into various other formats. This also includes CSV. As Timesketch is able to handle CSV data, this is worth an attempt.\n", + "\n", + "To export packets to csv use:\n", + "\n", + "```Wireshark → File → Export Packet Dissections```\n", + "\n", + "And choose CSV.\n", + "\n", + "The exported CSV will include all displayed columns. One thing to note here is that the time by default is relative to the first packet in the capture. You need to adjust that. \n", + "\n", + "Go to:\n", + "\n", + "```Wireshark → View → Time Display Format```\n", + "\n", + "And select ```UTC Date and Time of the Day```\n", + "\n", + "To learn more about Time settings in Wireshark, visit wireshark.org\n", + "\n", + "The now exported CSV looks promising. Some things need to be adjusted like the datetime column name and the format, but we already know how to do that from the autoruns csv file.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MHApjgTmFZro", + "cellView": "form" + }, + "source": [ + "# @markdown Change the path to what fits on your system.\n", + "PCAP_CSV_PATH = 'all_packets.csv' #@param {type: \"string\"}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ruqzafD72LLH" + }, + "source": [ + "pcap_df = pd.read_csv(\n", + " os.path.join(PATH_TO_FOLDER, PCAP_CSV_PATH),\n", + " encoding='utf-8', parse_dates=False)\n", + "\n", + "pcap_df.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7xA4laexGYFl" + }, + "source": [ + "#### Modify DataFrame\n", + "\n", + "Now let's rename fields and add other fields to make it work better for Timesketch." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wz3y2J0hOE-y" + }, + "source": [ + "pcap_df.head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ylJwSl15OGaC" + }, + "source": [ + "Now we've got a general idea about how the data looks like, so we can change it." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tXNcE60jEEIx" + }, + "source": [ + "# convert the 'Date' column to datetime format \n", + "pcap_df['Time']= pd.to_datetime(pcap_df['Time']) \n", + "pcap_df['data_type'] = 'pcap:wireshark:entry'\n", + "pcap_df['timestamp_desc'] = 'Time Logged'\n", + "pcap_df['source_short'] = 'LOG'\n", + "pcap_df['source'] = 'Network'\n", + "pcap_df['message'] = '[' + pcap_df['Protocol'] + '] ' + pcap_df['Info'] + ' (' + pcap_df['Source'] + ':' + pcap_df['src port'].astype('str') + ' -> ' + pcap_df['Destination'] + ':' + pcap_df['DST port'].astype('str') + ')'\n", + "\n", + "pcap_df = pcap_df.rename(columns={'Time': 'datetime'})\n", + "\n", + "pcap_df.info()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AShtCJv4PucM" + }, + "source": [ + "Let's look at the data frame now" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SsL4agghGcKT" + }, + "source": [ + "pcap_df.head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hpjRqMdlGfpb" + }, + "source": [ + "Adjust ports" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ik9sjjIdGjLD" + }, + "source": [ + "pcap_df['DST port'] = pcap_df['DST port'].astype(pd.Int32Dtype())\n", + "pcap_df['src port'] = pcap_df['src port'].astype(pd.Int32Dtype())\n", + "\n", + "pcap_df.head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tITKx61LGn_I" + }, + "source": [ + "#### Upload CSV\n", + "\n", + "Now we can upload the data to TS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "x2dVlUyLHzzX" + }, + "source": [ + "sketch = ts_client.get_sketch(SKETCH_ID)\n", + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper) \n", + "\n", + " streamer.set_timeline_name('wireshark_decoded_pcap')\n", + "\n", + " streamer.add_data_frame(pcap_df[~pcap_df.datetime.isna()].copy())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cDCabjJFLOYE" + }, + "source": [ + "### Using Python Libraries\n", + "\n", + "Now we can use python libraries, such as scapy. This is a much slower method than using Wireshark and a CSV. It is however more flexible, there are more things that can be done here.\n", + "\n", + "(for this we also have a progress bar since this will take some time to execute)\n", + "\n", + "Make sure that your environment has scapy installed, if not you can execute:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FzAVgN5PLR5O" + }, + "source": [ + "!pip install -q scapy\n", + "!pip install -q tqdm\n", + "!pip install -q ipywidgets" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cz0xDJm5LUxN" + }, + "source": [ + "# @markdown Import needed libraries for using scapy.\n", + "import binascii\n", + "import datetime\n", + "import pytz\n", + "\n", + "import tqdm\n", + "from tqdm import tqdm_notebook, tnrange\n", + "\n", + "import ipywidgets as widgets\n", + "\n", + "from scapy import all as scapy_all" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WCxbpYo5LX8G", + "cellView": "form" + }, + "source": [ + "# @markdown Change this to the correct path on your system.\n", + "PCAP_PATH = 'case001.pcap' # @param {type: \"string\"}\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G-34CmPKUss8" + }, + "source": [ + "Let's read in the PCAP file, word of warning, this will take a **really long time**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gpL9tqlALZVe" + }, + "source": [ + "packets = scapy_all.rdpcap(\n", + " os.path.join(PATH_TO_FOLDER, PCAP_PATH))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TG57s2ZOLbM1" + }, + "source": [ + "# @markdown check how many packets are in there\n", + "packets" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_tDnPoVYWBLK" + }, + "source": [ + "Now we can start going through the packets to generate a data frame, since that's what we want so that we can upload data to TS\n", + "\n", + "To convert the data to a dataframe we are borrowing code from : https://github.com/secdevopsai/Packet-Analytics/blob/master/Packet-Analytics.ipynb (see the [medium post here](https://medium.com/hackervalleystudio/learning-packet-analysis-with-data-science-5356a3340d4e))" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "V9B7TMZJLdmS" + }, + "source": [ + "# @markdown Collect field names from IP/TCP/UDP\n", + "# @markdown *These will be columns in DF*\n", + "ip_fields = [(field.name) for field in scapy_all.IP().fields_desc]\n", + "tcp_fields = [(field.name) for field in scapy_all.TCP().fields_desc]\n", + "udp_fields = [(field.name) for field in scapy_all.UDP().fields_desc]\n", + "\n", + "print(ip_fields)\n", + "print(tcp_fields)\n", + "print(udp_fields)\n", + "\n", + "ip_fields_new = [(\"ip_\"+field.name) for field in scapy_all.IP().fields_desc]\n", + "tcp_fields_new = [(\"tcp_\"+field.name) for field in scapy_all.TCP().fields_desc]\n", + "udp_fields_new = [(\"udp_\"+field.name) for field in scapy_all.UDP().fields_desc]\n", + "\n", + "dataframe_fields = ip_fields_new + ['time'] + tcp_fields_new + ['payload', 'datetime', 'raw']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a06-AzxItGfC" + }, + "source": [ + "#### Upload Data To Timesketch\n", + "\n", + "Now that we've got the columns sorted out, we can now move on to go through each of the packets, create a dict and upload that directly to Timesketch.\n", + "\n", + "Let's use the code from our previous example, except this time adding a progress bar. We are going to stream the results from the parsing directly to Timesketch.\n", + "\n", + "**Word of warning: this will also take considerable amount of time to execute and it may even crash your notebook. You have been warned!**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fqYR84a7Liks" + }, + "source": [ + "sketch = ts_client.get_sketch(SKETCH_ID)\n", + "import_helper = helper.ImportHelper() \n", + "\n", + "with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper)\n", + "\n", + " # Lower the threshold, which defines how many entries we go through before we flush the buffer.\n", + " streamer.set_entry_threshold(1000)\n", + " streamer.set_data_type('scapy:pcap:entry')\n", + " streamer.set_timestamp_description('PCAP Entry')\n", + " streamer.set_timeline_name('network_pcap_with_scapy')\n", + " streamer.set_message_format_string('{raw:s}')\n", + "\n", + " for packet in tqdm_notebook(packets[scapy_all.IP]):\n", + " # Field array for each row of DataFrame\n", + " \n", + " field_values = []\n", + " # Add all IP fields to dataframe\n", + " for field in ip_fields:\n", + " if field == 'options':\n", + " # Retrieving number of options defined in IP Header\n", + " field_values.append(len(packet[scapy_all.IP].fields[field]))\n", + " else:\n", + " field_values.append(packet[scapy_all.IP].fields[field])\n", + " \n", + " field_values.append(packet.time)\n", + " layer_type = type(packet[scapy_all.IP].payload)\n", + " for field in tcp_fields:\n", + " try:\n", + " if field == 'options':\n", + " field_values.append(len(packet[layer_type].fields[field]))\n", + " else:\n", + " field_values.append(packet[layer_type].fields[field])\n", + " except:\n", + " field_values.append(None)\n", + " \n", + " # Append payload\n", + " field_values.append(len(packet[layer_type].payload))\n", + " \n", + " date_value = datetime.datetime.fromtimestamp(packet.time, tz=pytz.utc)\n", + " field_values.append(date_value.isoformat())\n", + " field_values.append(str(packet.show2))\n", + "\n", + " # Create a dict and upload it to timesketch.\n", + " packet_dict = dict(zip(dataframe_fields, field_values))\n", + " ip_flags = packet_dict.get('ip_flags')\n", + " if not ip_flags is None:\n", + " packet_dict['ip_flags'] = ip_flags.names\n", + "\n", + " tcp_flags = packet_dict.get('tcp_flags')\n", + " if not tcp_flags is None:\n", + " packet_dict['tcp_flags'] = tcp_flags.names\n", + "\n", + " del packet_dict['time']\n", + "\n", + " streamer.add_dict(packet_dict)" + ], + "execution_count": null, + "outputs": [] + } + ] +} diff --git a/notebooks/add_a_single_event_to_a_sketch.ipynb b/notebooks/add_a_single_event_to_a_sketch.ipynb new file mode 100644 index 0000000000..96debf9377 --- /dev/null +++ b/notebooks/add_a_single_event_to_a_sketch.ipynb @@ -0,0 +1,176 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "add_a_single_event_to_a_sketch.ipynb", + "provenance": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E2meYbWjdnyR" + }, + "source": [ + "# Setup\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZoKUE_mbwOyy", + "cellView": "form" + }, + "source": [ + "# @title Install dependencies\n", + "# @markdown Only execute if not already installed and running a cloud runtime\n", + "!pip install -q timesketch_api_client\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cFNfts9KNOKi" + }, + "source": [ + "# @title Import libraries\n", + "# @markdown This cell will import all the libraries needed for the running of this colab.\n", + "\n", + "import altair as alt # For graphing.\n", + "import numpy as np # Never know when this will come in handy.\n", + "import pandas as pd # We will be using pandas quite heavily.\n", + "\n", + "from timesketch_api_client import config" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_En91RhFQ5l8" + }, + "source": [ + "# @title Sketch Configuration\n", + "# @markdown Set the sketch ID for the rest of the notebook\n", + "\n", + "Sketch_id = 1 #@param {type:\"integer\"}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "c_rcGvf2yLvJ" + }, + "source": [ + "# @title Timesketch connnection\n", + "ts_client = config.get_client()\n", + "sketch = ts.get_sketch(Sketch_id)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IO_HPkC84muI" + }, + "source": [ + "# Fill in your event data\n", + "\n", + "Put in your message, date and timestamp description" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fgL9ISpKggQ2" + }, + "source": [ + "#message: A string that will be used as the message string. \n", + "message = \"\" #@param {type:\"string\"}\n", + "\n", + "#date: A string with the timestamp of the message. \n", + "# This should be in a human readable format, eg: \"2020-09-03T22:52:21\". \n", + "# if empty it will set to now\n", + "\n", + "date = \"2020-08-06T12:48:06.994188Z\" #@param {type:\"string\"}\n", + "\n", + "#timestamp_desc : Description of the timestamp. \n", + "timestamp_desc = \"Test_description\" #@param {type:\"string\"}\n", + "\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "48S5ch1P4s44" + }, + "source": [ + "# Attributes / Tags (optional)\n", + "Fill in additional attributes and tags\n", + "\n", + "If you do not need that, empty them.\n", + "\n", + "## Examples: \n", + "attributes: A dict of extra attributes to add to the event. \n", + "````\n", + "attributes = {\"a\": \"alpha\", \"o\": \"omega\", \"g\": \"gamma\"}\n", + "````\n", + "\n", + "tags: A list of strings to include as tags.\n", + "````tags = [\"not\", \"important\"]```` " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PVoR7JVM42_J" + }, + "source": [ + "#attributes: A dict of extra attributes to add to the event. \n", + "attributes = {\"a\": \"alpha\", \"o\": \"omega\", \"g\": \"gamma\"}\n", + "\n", + "#tags: A list of strings to include as tags.\n", + "tags = [\"not\", \"important\"] " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EULXHP4YgZ-S" + }, + "source": [ + "sketch.add_event(message, date, timestamp_desc, attributes, tags)" + ], + "execution_count": null, + "outputs": [] + } + ] +} diff --git a/notebooks/colab-timesketch-demo.ipynb b/notebooks/colab-timesketch-demo.ipynb new file mode 100644 index 0000000000..24eed054a8 --- /dev/null +++ b/notebooks/colab-timesketch-demo.ipynb @@ -0,0 +1,1589 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Timesketch And Colab.ipynb", + "private_outputs": true, + "provenance": [], + "toc_visible": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mZWOhSLNRInc" + }, + "source": [ + "# Timesketch and Colab\n", + "\n", + "This is a small colab that is built to demonstrate how to interact with Timesketch from colab to do some additional exploration of the data.\n", + "\n", + "Colab can greatly complement investigations by providing the analyst with access to the powers of using python to manipulate the data stored in Timeskech. Additionally it provides developers with the ability to do research on the data in order to speed up developments of analyzers, aggregators and graphing. The purpose of this colab is simply to briefly introduce the powers of colab to analysts and developers, with the hope of inspiring more to take advantage of this powerful platform. It is also an option to use jupyter notebook instead of colab, both are just as valid options.\n", + "\n", + "Each code cell (denoted by the [] and grey color) can be run simply by hitting \"shift + enter\" inside it. The first code that you execute will automatically connect you to a public runtime for colab and connect to the publicly open demo timesketch. You can easily add new code cells, or modify the code that is already there to experiment.\n", + "\n", + "## README\n", + "\n", + "If you simply click the `connect` button in the upper right corner you will\n", + "connect to a kernel runtime running in the cloud. It is a great way to explore\n", + "what colab has to offer and provides a quick way to play with the demo data.\n", + "\n", + "However if you want to connect to your own Timesketch instance, or load data\n", + "from local drive or don't want the data to be read into a cloud machine then\n", + "it is better to run from a local runtime environment. Install jupyter on\n", + "your machine and follow the [guideline posted here](https://research.google.com/colaboratory/local-runtimes.html).\n", + "These instructions are also available from the pop-up that comes when\n", + "you select a local runtime.\n", + "\n", + "Once you have your local runtime setup you should be able to reach your local Timesketch instance.\n", + "\n", + "You cannot save changes to this colab document, if you want to have your own copy of the colab to make changes or do some other experimentation you can simply select \"File / Save a Copy in Drive\" button to make your own copy of this colab and start making changes.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4_TQvEgTRRVK" + }, + "source": [ + "## Installation\n", + "\n", + "Let's start by installing the TS API client... all commands that start with ! are executed in the shell, therefore if you are missing Python packages you can use pip.\n", + "\n", + "This is not needed if you are running a local kernel, that has the library already installed." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qmu0lOJYRFYD" + }, + "source": [ + "!pip install --upgrade timesketch-api-client" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mFQTCGbNeRoR" + }, + "source": [ + "### Remember to execute the cell below\n", + "\n", + "Just a gentle reminder that the cell below is a code cell, so it needs to be executed (you can see the \"play\" button next to it)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nh4pwmG-RI2w", + "cellView": "form" + }, + "source": [ + "# @title Import Libraries\n", + "# @markdown We first need to import libraries that we will use throughout the colab.\n", + "import altair as alt # For graphing.\n", + "import numpy as np # Never know when this will come in handy.\n", + "import pandas as pd # We will be using pandas quite heavily.\n", + "\n", + "from timesketch_api_client import config\n", + "from timesketch_api_client import search" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ojceENS4hEP5" + }, + "source": [ + "(notice that the cell above is an actual code cell, it is just using formatting to *look nice*. If you want to see the code behind it, select the cell, and click the three dots and select \"Form | Show Code\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uMYsDkCgYK5y" + }, + "source": [ + "## Connect to TS" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9IUzNc8yRanl" + }, + "source": [ + "And now we can start creating a timesketch client. The client is the object used to connect to the TS server and provides the API to interact with it.\n", + "\n", + "The TS API consists of several objects, each with it's own purpose, some of them are:\n", + "+ **client**: A TS client object is the main `gateway` to TS. That includes\n", + "authenticating to TS, keeping a session to interact with the REST API, and providing functions that allow you to create new sketches, get a sketch, and work with search indices.\n", + "+ **sketch**: A sketch object is what you will most likely interact with the most. That allows you to operate on a sketch, so that means to see the sketch ACL, attributes, labels and other metadata as well as to run analyzers, search queries, aggregations, stories, tag or label events, etc.\n", + "+ **timeline**: A timeline object allows you to view properties of a timeline, as well as adding/removing labels from it.\n", + "+ **story**: A story object allows you to interact with a story, add/delete/edit blocks, move them around, export the story, etc.\n", + "+ **view**: A view object is an object that holds information about saved searches, or views in a sketch. This can be passed to the sketch to query data, or to view the content of the view.\n", + "+ **aggregation**: An aggregation object is used to run aggregation queries on the dataset. It can provide you with a data frame, a chart, or the option to save/delete aggregations.\n", + "\n", + "Let's start by getting a TS client object. There are multiple ways of getting that, yet the easiest way is to use the configuration object. That automates most of the actions that are needed, and prompts the user with questions if data is missing (reading information from a configuration file to fill in the blanks).\n", + "\n", + "The first time you request the client it will ask you questions (since for the first time there will be no configuration file). For this demonstration we are going to be using the demo server, so we will use the following configs:\n", + "\n", + "+ host_uri: **https://demo.timesketch.org**\n", + "+ auth_mode: **timesketch** (this is simple user/pass)\n", + "+ Username: **demo**\n", + "+ Password: **demo**\n", + "\n", + "*keep in mind that after answering these questions for the first time, a configuration file ~/.timesketchrc and ~/.timesketch.token will be saved so you don't need to answer these questions again.*\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1QQFoUFWRP4N", + "cellView": "both" + }, + "source": [ + "ts_client = config.get_client(confirm_choices=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pX1B1gccRv9L" + }, + "source": [ + "### Let's Explore\n", + "And now we can start to explore. The first thing is to get all the sketches that are available. Most of the operations you want to do with TS are available in the sketch API." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QN2r9x3uRvRG" + }, + "source": [ + "sketches = ts_client.list_sketches()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r6Qmi4v_SGX1" + }, + "source": [ + "Now that we've got a lis of all available sketches, let's print out the names of the sketches as well as the index into the list, so that we can more easily choose a sketch that interests us." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Wn0zDL6SRuYY" + }, + "source": [ + "for i, sketch in enumerate(sketches):\n", + " print(f'[{i}] `\n", + "\n", + "In colab you can use TAB completion to get a list of all attributes of the object you are working with. See a function you may want to call? Try calling it with `gd_sketch.function_name?` and hit enter.. let's look at an example:\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e7oEZ80sYzc7" + }, + "source": [ + "gd_sketch.list_saved_searches?" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8h2S3dXBY6c0" + }, + "source": [ + "This way you'll get a list of all the parameters you may want or need to use. You can also use tab completion as soon as you type, `gd_sketch.e` will give you all options that start with an `e`, etc.\n", + "\n", + "You can also type `gd_sketch.list_saved_searches()` and get a pop-up with a list of what parameters this function provides.\n", + "\n", + "Now let's look at somethings we can do with the sketch object and the TS client. For example if we want to get all starred events in the sketch we can do that by querying the sketch for available labels. You can look at a label as a \"sketch specific tag\", that is unlike a tag that is stored in the Elastic document and therefore is shared among all sketches that have that same timeline attached, a label is bound to the actual sketch and therefore not available outside of it... this is used in various places, most notably to indicate which events have labels, are hidden from views and are starred. These pre-defined labels are:\n", + "\n", + "+ __ts_star: Starred event\n", + "+ __ts_comment: Event with a comment\n", + "+ __ts_hidden: A hidden event\n", + "\n", + "Let's for instance look at all starred events in the Greendale index. We will use the parameter `as_pandas=True`. That will mean that the events will be returned as a [pandas DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html). This is a very flexible object that we will use throughout this colab. We will try to introduce some basic operations on a pandas object, yet for more details there are plenty of guides that can be found online. One way to think about pandas is to think about spreadsheets, or databases, where the data is stored in a table (data frame), which consists of columns and rows. And then there are operations that work on either the column or the row.\n", + "\n", + "But let's start by looking at one such data frame, by looking for all starred events.\n", + "\n", + "There are two ways of doing that, either by using the search object (preferred) or via the sketch object (soon to be deprecated)\n", + "\n", + "Once we get the data frame back, we call `data_frame.shape`, which returns a tuple with two items, number of rows and number of columns. That way we can assess the size of the dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HejGxei3hfnM" + }, + "source": [ + "starred_events = gd_sketch.search_by_label('__ts_star', as_pandas=True)\n", + "starred_events.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NVtbz3xaFfvK" + }, + "source": [ + "Let's look at how to achieve the same using the search object." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ats7kiVYFixE" + }, + "source": [ + "search_obj = search.Search(gd_sketch)\n", + "label_chip = search.LabelChip()\n", + "label_chip.use_star_label()\n", + "search_obj.add_chip(label_chip)\n", + "search_obj.query_string = '*'\n", + "\n", + "starred_events = search_obj.table\n", + "starred_events.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VFmX8tY-bRnC" + }, + "source": [ + "As you noticed there are quite a few starred events.. to limit this, let's look at just the first 10" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Logz1UvNbV87" + }, + "source": [ + "starred_events.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6RZS868gbakg" + }, + "source": [ + "Or a single one..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "168Ny0fObbx1" + }, + "source": [ + "pd.set_option('display.max_colwidth', 100) # this is just meant to make the output wider\n", + "starred_events.iloc[9]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hMzUvQt2aU37" + }, + "source": [ + "To continue let's look at what searches have been stored in the sketch:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AYgCmg_yZOO7" + }, + "source": [ + "saved_searches = gd_sketch.list_saved_searches()\n", + "\n", + "for index, saved_search in enumerate(saved_searches):\n", + " print('[{0:d}] {1:s}'.format(index, saved_search.name))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tt5SWKzgZZe5" + }, + "source": [ + "You can then start to query the API to get back results from these saved searches. Let's try one of them...\n", + "\n", + "Word of caution, try to limit your search so that you don't get too many results back. The API will happily let you get all the results back as you choose, but the more records you get back the longer the API call will take (10k events per API call). " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yY8jk_UzSpCE" + }, + "source": [ + "# You can change this number if you would like to test out another view.\n", + "# The way the code works is that it checks first of you set the \"view_text\", and uses that to pick a view, otherwise the number is used.\n", + "saved_search_id = 1\n", + "saved_search_text = 'Phishy Domains'\n", + "\n", + "if saved_search_text:\n", + " for index, saved_search in enumerate(saved_searches):\n", + " if saved_search.name == saved_search_text:\n", + " saved_search_id = index\n", + " break\n", + "\n", + "print('Fetching data from : {0:s}'.format(saved_searches[saved_search_id].name))\n", + "print(' Query used : {0:s}'.format(\n", + " saved_searches[saved_search_id].query_string if saved_searches[saved_search_id].query_string else saved_searches[saved_search_id].query_dsl))\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zLgLBXXMlDKa" + }, + "source": [ + "If you want to issue this query, then you can run the cell below, otherwise you can change the view_number to try another one." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MmlF6oYcj8wh" + }, + "source": [ + "greendale_frame = saved_searches[saved_search_id].table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEki5_BmZpKu" + }, + "source": [ + "One thing you may notice is that throughout this colab we will use the \"`.table`\" property of the search object. That means that the data that we'll get back is a pandas DataFrame that we can now start exploring. \n", + "\n", + "Let's start with seeing how many entries we got back." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1_fjRL4XZ-XW" + }, + "source": [ + "greendale_frame.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kuoh1BXcwndC" + }, + "source": [ + "This tells us that we got back only 40 records... and that's because we are using a saved search, that limited the number of records returned back, let's confirm that:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Kvz85LIrwwv9" + }, + "source": [ + "saved_search = saved_searches[saved_search_id]\n", + "\n", + "saved_search.query_filter" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7MuRsRsMw2eE" + }, + "source": [ + "You can see that the size of the return value is only 40 entries... but the log entry before told us that there were `2240` entries to be gathered so let's increase that.\n", + "\n", + "*warning... since this is a saved search the API will attempt to update the actual saved search on the backend, but the demo user you are using is not allowed to change the saved search, so there will be a RuntimeError raised. Don't worry though, you can still change the value locally though.*" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GmGTa4Pyw0GK" + }, + "source": [ + "saved_search.max_entries = 4000" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "okanF4TGxFfh" + }, + "source": [ + "greendale_frame = saved_search.table\n", + "greendale_frame.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XWjrJnivaSo9" + }, + "source": [ + "This tells us that the view returned back 2.284 events with 12 columns. Let's explore the first few entries, just so that we can wrap our head around what we got back.\n", + "\n", + "This is a great way to just get a feeling of what the data looks like that will be returned back. To see the first five entries we can use the `.head(5)` function, and the same if we want the last entries, we can use `.tail(5)`." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ymR_NtseaRrO" + }, + "source": [ + "greendale_frame.head(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bdPUgvNtl82r" + }, + "source": [ + "Let's look at what columns we got back... and maybe create a slice that contains fewer columns, or not necessarily fewer but at least more the ones that we want to be able to see." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zuu7VFCAmB9e" + }, + "source": [ + "greendale_frame.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D-5xReYEHxKc" + }, + "source": [ + "Since this is a result from the analyzers we have few extra fields we can pull in. \n", + "\n", + "Looking at the results you see the same column names in the UI, but when you click an event you'll notice that it has a lot more fields in it than the default view is. This can also be changed in the API client. For that we use the variable `return_fields`. Let's set that one.\n", + "\n", + "```\n", + " return_fields: List of fields that should be included in the\n", + " response.\n", + " ```\n", + " \n", + "We can use that to specify what fields we would like to get back. Let's add few more fields (you can see what fields are available in the UI)\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Dqv6gXlKmEUW" + }, + "source": [ + "search_obj = saved_searches[saved_search_id]\n", + "try:\n", + " search_obj.return_fields = 'datetime,timestamp_desc,tag,message,label,url,domain,human_readable,access_count,title,domain_count,search_string'\n", + "except RuntimeError:\n", + " pass\n", + "\n", + "try:\n", + " search_obj.max_entries = 10000\n", + "except RuntimeError:\n", + " pass\n", + "greendale_frame = search_obj.table\n", + "greendale_frame.head(4)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_mvDnsFfIful" + }, + "source": [ + "Let's briefly look at these events." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PKioTKqoI85E" + }, + "source": [ + "OK,.... since this is a phishy domain analyzer, and all the results we got back are essentially from that analyzer, let's look at few things. First of all let's look at the tags that are available.\n", + "\n", + "Let's start by doing a simple method of converting the tags that are now a list into a string and then finding the unique strings." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFMRBxtRJDcK" + }, + "source": [ + "greendale_frame.tag.str.join('|').unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5Ii81u63t_NJ" + }, + "source": [ + "Then we can start to do this slightly differently, this time we want to get a list of all the different tags." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JuTczR1_uKzO" + }, + "source": [ + "tags = set()\n", + "def add_tag(tag_list):\n", + " list(map(tags.add, tag_list))\n", + "\n", + "greendale_frame.tag.apply(add_tag)\n", + "\n", + "print(tags)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WYhye26yuepx" + }, + "source": [ + "Let's go over the code above to understand what just happened.\n", + "\n", + "First of all a set is created, called `tags`, since this is a set it cannot contain duplicates (duplicates are ignored).\n", + "\n", + "Then we define a function that accepts a list, and then applies the function `tags.add` against every item in the list (the map function). This mean that for each entry in the supplied `tag_list` the function `tags.add` is called.\n", + "\n", + "Then finally we take the dataframe `greendale_frame` and call the `apply` function on the series `tag`. That takes the column or series `tag`, which contains lists of tags applied and then for each row in the data frame applies the function `add_tag` that we created.\n", + "\n", + "This code effectively does the following:\n", + "+ For each row of `greendale_frame` extract the `tag` list and apply the `add_tag` function\n", + "+ The add tag function takes then each entry in the tag list and adds it to the set `tags`\n", + "\n", + "This gives us a final set that contains exactly one copy of each tag that was applied to the records." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KP_joLR7JVJ8" + }, + "source": [ + "Looking at the results from the tags, we do see some `outside-active-hours` tags. Let's look at those specifically. What does that mean? That means that the timeframe analyzer determined that the browsing activity occurred outside regular hours of the timeline it analyzed." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h9l165w_JdtT" + }, + "source": [ + "greendale_frame[greendale_frame.tag.str.join(',').str.contains('outside-active-hours')].domain.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VADR_gpAJzMz" + }, + "source": [ + "OK... now we get to see all the domains that the domain analyzer considered to be potentially \"phishy\"... is there a domain that stands out??? what about that grendale one?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-1PBtCtjJ5Ag" + }, + "source": [ + "greendale_frame[greendale_frame.domain == 'grendale.xyz'][['datetime', 'url']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4PbDcNMzJ-8S" + }, + "source": [ + "OK... this seems odd.. let's look at few things, a the `human_readable` string as well as the URL..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vxnMcThfKEOs" + }, + "source": [ + "grendale = greendale_frame[greendale_frame.domain == 'grendale.xyz']\n", + "\n", + "string_set = set()\n", + "for string_list in grendale.human_readable:\n", + " new_list = [x for x in string_list if 'phishy_domain' in x]\n", + " _ = list(map(string_set.add, new_list))\n", + "\n", + "for entry in string_set:\n", + " print('Human readable string is: {0:s}'.format(entry))\n", + " \n", + "\n", + "print('')\n", + "print('Counts for URL connections to the grendale domain:')\n", + "grendale_count = grendale.url.value_counts()\n", + "for index in grendale_count.index:\n", + " print('[{0:d}] {1:s}'.format(grendale_count[index], index))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1QH7LFksLuLd" + }, + "source": [ + "We can start doing a lot more now if we want to... let's look at when these things occurred..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-EShYajvL1RE" + }, + "source": [ + "grendale_array = grendale.url.unique()\n", + "\n", + "greendale_frame[greendale_frame.url.isin(grendale_array)]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DrvPXI8zMETu" + }, + "source": [ + "OK... we can then start to look at surrounding events.... let's look at one date in particular... \"2015-08-29 12:21:06\"" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kwJrIsErMNGv" + }, + "source": [ + "search_obj = search.Search(gd_sketch)\n", + "date_chip = search.DateIntervalChip()\n", + "\n", + "# Let's set the date\n", + "date_chip.date = '2015-08-29T12:21:06'\n", + "\n", + "# And now how much time we want before and after.\n", + "date_chip.before = 1\n", + "date_chip.after = 1\n", + "\n", + "# and the unit, we want minutes.. so that is m\n", + "date_chip.unit = 'm'\n", + "\n", + "search_obj.query_string = '*'\n", + "search_obj.add_chip(date_chip)\n", + "\n", + "search_obj.return_fields = 'message,human_readable,datetime,timestamp_desc,source_short,data_type,tags,url,domain'\n", + "\n", + "data = search_obj.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NvIl0ucuzBvL" + }, + "source": [ + "And now we can start to look at the results:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6NSD4izoNExQ" + }, + "source": [ + "data[['datetime', 'message', 'human_readable', 'url']].head(4)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gEQ9yZbTNzjJ" + }, + "source": [ + "Let's find the grendale and just look at events two seconds before/after" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wA9lQ1JANdGg" + }, + "source": [ + "data[(data.datetime > '2015-08-29 12:21:04') & (data.datetime < '2015-08-29 12:21:08')][['datetime', 'message', 'timestamp_desc']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9F2gAu6ScnEh" + }, + "source": [ + "## Let's look at aggregation\n", + "\n", + "Timesketch also has aggregation capabilities that we can call from the client. Let's take a quick look.\n", + "\n", + "Start by checking out whether there are any stored aggregations that we can just take a look at.\n", + "\n", + "You can also store your own aggregations using the `gd_sketch.store_aggregation` function. However we are not going to do that in this colab." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hwe_qoUR14wL" + }, + "source": [ + "[(x.id, x.name, x.title, x.description) for x in gd_sketch.list_aggregations()]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G3w-Wgbc8Am_" + }, + "source": [ + "OK, so there are some aggregations stored. Let's just pick one of those to take a closer look at." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0-sNmn4a1-K-" + }, + "source": [ + "aggregation = gd_sketch.get_aggregation(24)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JFeCKrPA8IlZ" + }, + "source": [ + "Now we've got an aggregation object that we can take a closer look at." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xj46DN9W8PdD" + }, + "source": [ + "aggregation.description" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1_H6Xtdy8RoX" + }, + "source": [ + "OK, so from the name, we can guess what it contains. We can also look at all of the stored aggregations" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z-ihf1uP8Xwd" + }, + "source": [ + "pd.DataFrame([{'name': x.name, 'description': x.description} for x in gd_sketch.list_aggregations()])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q7okh3ik8lsL" + }, + "source": [ + "Let's look at the aggregation visually, both as a table and a chart." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XGMT_d0K8ooP" + }, + "source": [ + "aggregation.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MMtWdtTI8qkR" + }, + "source": [ + "aggregation.chart" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DrtWSb5Ix60q" + }, + "source": [ + "The chart there is empty, since the aggregation didn't contain a chart.\n", + "\n", + "\n", + "We can also take a look at what aggregators can be used, if we want to run our own custom aggregator." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DZ7pbVCHyC-s" + }, + "source": [ + "gd_sketch.list_available_aggregators()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bJdAaL-Jc172" + }, + "source": [ + "Now we can see that there are at least the \"field_bucket\" and \"query_bucket\" aggregators that we can look at. The `field_bucket` one is a terms bucket aggregation, which means we can take any field in the dataset and aggregate on that.\n", + "\n", + "So if we want to for instance see the top 20 domains that were visited we can just ask for an aggregation of the field `domain` and limit it to 20 records (which will be the top 20). Let's do that:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DtzPsBQmc3Du" + }, + "source": [ + "aggregator = gd_sketch.run_aggregator(\n", + " aggregator_name='field_bucket',\n", + " aggregator_parameters={'field': 'domain', 'limit': 20, 'supported_charts': 'barchart'})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VHNfI5g-yj-e" + }, + "source": [ + "Now we've got an aggregation object that we can take a closer look at... let's look at the data it stored. What we were trying to get out was the top 20 domains that were visited." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EbwgvEczvJw_" + }, + "source": [ + "aggregator.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "70zZ8p53yssc" + }, + "source": [ + "Or we can look at this visually... as a chart" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3RhPxNrAyuu4" + }, + "source": [ + "aggregator.chart" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DRGKWSnfzg2D" + }, + "source": [ + "We can also do something a bit more complex. The other aggregator, the `query_bucket` works in a similar way, except you can filter the results first. We want to aggregate all the domains that have been tagged with the phishy domain tag." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ON6j4snf9vtC" + }, + "source": [ + "tag_aggregator = gd_sketch.run_aggregator(\n", + " aggregator_name='query_bucket',\n", + " aggregator_parameters={\n", + " 'field': 'domain',\n", + " 'query_string': 'tag:\"phishy-domain\"',\n", + " 'supported_charts': 'barchart',\n", + " }\n", + ")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kImHNTCT_gbQ" + }, + "source": [ + "Let's look at the results." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EqRjvsxY_hre" + }, + "source": [ + "tag_aggregator.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aB9VkZlV_4RT" + }, + "source": [ + "We can also look at all the tags in the timeline. What tags have been applied and how frequent are they." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "H-YUCbxv-W1Y" + }, + "source": [ + "gd_sketch.run_aggregator(\n", + " aggregator_name='field_bucket',\n", + " aggregator_parameters={\n", + " 'field': 'tag',\n", + " 'limit': 10,\n", + " }\n", + ").table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bBEORm6E__PG" + }, + "source": [ + "And then to see what are the most frequent applications executed on the machine.\n", + "\n", + "Since not all of the execution events have the same fields in them we'll have to create few tables here... let's start with looking at what data types are there." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i7R2uGp2AE4D" + }, + "source": [ + "gd_sketch.run_aggregator(\n", + " aggregator_name='query_bucket',\n", + " aggregator_parameters={\n", + " 'field': 'data_type',\n", + " 'query_string': 'tag:\"browser-search\"',\n", + " 'supported_charts': 'barchart',\n", + " }\n", + ").table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NQRD_9mZBHH_" + }, + "source": [ + "And then we can do a summary for each one." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GM_a666aBIzI" + }, + "source": [ + "gd_sketch.run_aggregator(\n", + " aggregator_name='query_bucket',\n", + " aggregator_parameters={\n", + " 'field': 'domain',\n", + " 'query_string': 'tag:\"browser-search\"',\n", + " 'supported_charts': 'barchart',\n", + " }\n", + ").table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EtRw5wEABLIt" + }, + "source": [ + "agg = gd_sketch.run_aggregator(\n", + " aggregator_name='query_bucket',\n", + " aggregator_parameters={\n", + " 'field': 'search_string',\n", + " 'query_string': 'tag:\"browser-search\"',\n", + " 'supported_charts': 'hbarchart',\n", + " }\n", + ")\n", + "\n", + "agg.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NAV-KN6zIg82" + }, + "source": [ + "Or as a chart" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LM_CT7eWIfRS" + }, + "source": [ + "agg.chart" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0tA4pHRLOj5g" + }, + "source": [ + "## Let's look at logins...\n", + "\n", + "Let's do a search to look at login entries..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vbsb58imPVCQ" + }, + "source": [ + "search_obj = search.Search(gd_sketch)\n", + "search_obj.query_string = 'tag:\"logon-event\"'\n", + "search_obj.max_entries = 500000\n", + "search_obj.return_fields = (\n", + " 'datetime,timestamp_desc,human_readable,message,tag,event_identifier,hostname,record_number,'\n", + " 'recovered,strings,username,strings_parsed,logon_type,logon_process,windows_domain,'\n", + " 'source_username,user_id,computer_name')\n", + "\n", + "login_data = search_obj.table" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YydMkgThab09" + }, + "source": [ + "This will produce quite a bit of events... let's look at how many." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-PxPYIA5Pvks" + }, + "source": [ + "login_data.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZsM5me3KQwp4" + }, + "source": [ + "Let's look at usernames...." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kfuzWPfJQynH" + }, + "source": [ + "login_data.username.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5ApoSLqLfXbX" + }, + "source": [ + "Let's also look at what windows domains where used:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tKF9UR3mbSC-" + }, + "source": [ + "login_data.windows_domain.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9fy6EAURSpvK" + }, + "source": [ + "And the logon types:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DFU56oKaSUMC" + }, + "source": [ + "login_data.logon_type.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vG1SCs_wLTwe" + }, + "source": [ + "login_data.computer_name.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8IApcGWwfaMS" + }, + "source": [ + "Let's graph.... and you can then interact with the graph... try zomming in, etc.\n", + "\n", + "First we'll define a graph function that we can then call with parameters..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HwU4K4MnaYdt" + }, + "source": [ + "def GraphLogins(data_frame, machine_name=None):\n", + " \n", + " if machine_name:\n", + " data_slice = data_frame[data_frame.computer_name == machine_name]\n", + " title = 'Accounts Logged In - {0:s}'.format(machine_name)\n", + " else:\n", + " data_slice = data_frame\n", + " title = 'Accounts Logged In'\n", + " \n", + " data_grouped = data_slice[['username', 'datetime']].groupby('username', as_index=False).count()\n", + " data_grouped.rename(columns={'datetime': 'count'}, inplace=True)\n", + "\n", + " return alt.Chart(data_grouped, width=400).mark_bar().encode(\n", + " x='username', y='count',\n", + " tooltip=['username', 'count']\n", + " ).properties(\n", + " title=title\n", + " ).interactive()\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9stCil8TgXhq" + }, + "source": [ + "Start by graphing all machines" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T-oUET5AgYyW" + }, + "source": [ + "GraphLogins(login_data)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "drEG2TTSncoS" + }, + "source": [ + "Or we can look at this for a particular machine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SP1vf_xBUr2a" + }, + "source": [ + "GraphLogins(login_data, 'Student-PC1.internal.greendale.edu')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2axKKhp7Unfe" + }, + "source": [ + "Or we can look at this as a scatter plot...\n", + "\n", + "First we'll define a function that munches the data for us. This function will essentially graph all logins in a day with a scatter plot, using colors to denote the count value.\n", + "\n", + "**This graph will be very interactive... try selecting a time period by clicking with the mouse on the upper graph and drawing a selection.**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D9DiG03hazwY" + }, + "source": [ + "login_data['day'] = login_data['datetime'].dt.strftime('%Y-%m-%d')\n", + "\n", + "def GraphScatterLogin(data_frame, machine_name=''):\n", + " if machine_name:\n", + " data_slice = data_frame[data_frame.computer_name == machine_name]\n", + " title = 'Accounts Logged In - {0:s}'.format(machine_name)\n", + " else:\n", + " data_slice = data_frame\n", + " title = 'Accounts Logged In'\n", + " \n", + " login_grouped = data_slice[['day', 'computer_name', 'username', 'message']].groupby(['day', 'computer_name', 'username'], as_index=False).count()\n", + " login_grouped.rename(columns={'message': 'count'}, inplace=True)\n", + " \n", + " brush = alt.selection_interval(encodings=['x'])\n", + " click = alt.selection_multi(encodings=['color'])\n", + " color = alt.Color('count:Q')\n", + "\n", + " chart1 = alt.Chart(login_grouped).mark_point().encode(\n", + " x='day', \n", + " y='username',\n", + " color=alt.condition(brush, color, alt.value('lightgray')),\n", + " ).properties(\n", + " title=title,\n", + " width=600\n", + " ).add_selection(\n", + " brush\n", + " ).transform_filter(\n", + " click\n", + " )\n", + " \n", + " chart2 = alt.Chart(login_grouped).mark_bar().encode(\n", + " x='count',\n", + " y='username',\n", + " color=alt.condition(brush, color, alt.value('lightgray')),\n", + " tooltip=['count'],\n", + " ).transform_filter(\n", + " brush\n", + " ).properties(\n", + " width=600\n", + " ).add_selection(\n", + " click\n", + " )\n", + " \n", + " return chart1 & chart2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z4s-lEHxhQXH" + }, + "source": [ + "OK, let's start by graphing for all logins..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PuaJmcJMhShS" + }, + "source": [ + "GraphScatterLogin(login_data)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dpLDsdSGhT1r" + }, + "source": [ + "And now just for the Student-PC1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2XaBqZqRVIoL" + }, + "source": [ + "GraphScatterLogin(login_data, 'Student-PC1.internal.greendale.edu')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z0f-qAxyhYa4" + }, + "source": [ + "And now it is your time to shine, experiment with python pandas, the graphing library and other data science techniques." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vfCXHHx8YNPv" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} diff --git a/notebooks/debugging_timesketch.ipynb b/notebooks/debugging_timesketch.ipynb new file mode 100644 index 0000000000..7a7cc5d744 --- /dev/null +++ b/notebooks/debugging_timesketch.ipynb @@ -0,0 +1,512 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# DEBUGGING TIMESKETCH API WITH PYTHON" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook can be used to debug Timesketch: it can create/delete/visualize sketches and timelines, retrieve analyzers' results, run queries on a sketch and many others. Feel free to use and modify the section that you find more useful." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -q timesketch_api_client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "from timesketch_api_client import config\n", + "from timesketch_api_client import sketch\n", + "from timesketch_api_client import timeline\n", + "from timesketch_api_client import analyzer\n", + "from timesketch_api_client import search\n", + "\n", + "from timesketch_import_client import helper\n", + "from timesketch_import_client import importer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialization section\n", + "Define here the name of the sketch" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "sketch_name = \"foobar\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ts_client = config.get_client()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## GET section\n", + "This section has the command to retrieve the list of sketches, timelines, analyzers..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### GET list of sketches" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketches = [(x.id, x.name) for x in ts_client.list_sketches()]\n", + "for sketch in sketches:\n", + " print(f\"Sketch name: {sketch[1]} ({sketch[0]})\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### GET list of sketch - timeline - datasource" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketches = [(x.id, x.name) for x in ts_client.list_sketches()]\n", + "for sketch_info in sketches:\n", + " try:\n", + " sketch = ts_client.get_sketch(sketch_info[0])\n", + " print(f\"[S] {sketch.name} ({sketch.id})\")\n", + " for timeline in sketch.list_timelines():\n", + " print(f\" - [T] {timeline.name} ({timeline.id})\")\n", + " for datasource in timeline.data_sources:\n", + " print(f\" - [D] {datasource['context']} ({datasource['status'][0]['status']})\")\n", + " except Exception as e:\n", + " print(f\"[S]{sketch_info[1]} ({sketch_info[0]}) skipped\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### GET detailed events of a sketch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketch_ID = 1\n", + "print(f\"Using sketch ID {sketch_ID}\")\n", + "sketch = ts_client.get_sketch(sketch_ID)\n", + "print(json.dumps(sketch.data, indent=4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### GET detailed events of a timeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "timeline_ID = 12\n", + "\n", + "# first need to find the sketch of that timeline\n", + "sketches = [(x.id, x.name) for x in ts_client.list_sketches()]\n", + "for sketch_info in sketches:\n", + " try:\n", + " sketch = ts_client.get_sketch(sketch_info[0])\n", + " timelines_ID = [x.id for x in sketch.list_timelines()]\n", + " if timeline_ID in timelines_ID:\n", + " print(f\"Found timeline ID {timeline_ID} in sketch {sketch_info[1]}\")\n", + " print(f\"Print information of timeline ID {timeline_ID}...\")\n", + " timeline_info = sketch.get_timeline(timeline_ID).data\n", + " print(json.dumps(timeline_info, indent=4))\n", + " break\n", + " except Exception as e:\n", + " print(f\"Cannot retrieve timeline ID {timeline_id}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### GET events by running a QUERY" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketch_ID = 1\n", + "screenshot_events = None\n", + "\n", + "try:\n", + " sketch = ts_client.get_sketch(sketch_ID)\n", + " query = ('*')\n", + "\n", + " search_obj = search.Search(sketch)\n", + "\n", + " search_obj.query_string = query\n", + " screenshot_events = search_obj.table\n", + "except Exception as e:\n", + " print(f\"Cannot find sketch ID {sketch_ID}\")\n", + "\n", + "print(f\"Query: {query}\")\n", + "screenshot_events" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## CREATE section\n", + "In this section the are commands to create new sketch, a single timeline, a single timeline with multiple datasource and multiple timelines." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a new sketch (if the name is unique)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketches = [(x.id, x.name) for x in ts_client.list_sketches() if x.name == sketch_name]\n", + "sketch = None\n", + "if sketches:\n", + " print(\"Sketch already exists\")\n", + " sketch = ts_client.get_sketch(sketches[0][0])\n", + "else:\n", + " print(\"Create new sketch\")\n", + " sketch = ts_client.create_sketch(name=sketch_name)\n", + "\n", + "sketch_ID = sketch.id\n", + "print(f\"Sketch information: {sketch.name} ({sketch_ID})\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create new timeline given a sketch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "filename = \"/tmp/sample_chrome_logs.plaso\"\n", + "timeline_name = \"_\".join(filename.split(\"/\")[-1].split(\".\")[:-1])\n", + "\n", + "sketches = [(x.id, x.name) for x in ts_client.list_sketches() if x.name == sketch_name]\n", + "sketch = None\n", + "if sketches:\n", + " print(f\"Using sketch {sketch_name}\")\n", + " sketch = ts_client.get_sketch(sketches[0][0])\n", + " import_helper = helper.ImportHelper() \n", + " with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper)\n", + " streamer.set_timeline_name(timeline_name)\n", + " streamer.add_file(filename)\n", + " print(f\"Timeline {timeline_name} inserted\")\n", + "else:\n", + " print(\"No sketch with that name\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create timelines given a list of files" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# feel free to modify these lines as they are only used to fill the array list_files\n", + "import os\n", + "dir_path = r'/tmp/list_files'\n", + "\n", + "# list to store files\n", + "list_files = []\n", + "\n", + "# Iterate directory\n", + "for path in os.listdir(dir_path):\n", + " # check if current path is a file\n", + " if os.path.isfile(os.path.join(dir_path, path)):\n", + " list_files.append(dir_path + '/' + path)\n", + "print(f\"List of files: {', '.join(list_files)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketches = [(x.id, x.name) for x in ts_client.list_sketches() if x.name == sketch_name]\n", + "sketch = None\n", + "if sketches:\n", + " print(f\"Using sketch {sketch_name}\")\n", + " sketch = ts_client.get_sketch(sketches[0][0])\n", + " import_helper = helper.ImportHelper() \n", + " for filename in list_files:\n", + " timeline_name = \"_\".join(filename.split(\"/\")[-1].split(\".\")[:-1])\n", + " try:\n", + " with importer.ImportStreamer() as streamer:\n", + " streamer.set_sketch(sketch)\n", + " streamer.set_config_helper(import_helper)\n", + " streamer.set_timeline_name(timeline_name)\n", + " streamer.add_file(filename)\n", + " print(f\"Timeline {timeline_name} inserted\")\n", + " except Exception as e:\n", + " print(f\"{filename} skipped\")\n", + "else:\n", + " print(f\"no sketch found with name {sketch_name}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a manual event" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datetime = \"2020-08-06T12:48:06.994188Z\"\n", + "message = \"only a test to insert a manual event v2\"\n", + "timestamp_desc = \"creation time\"\n", + "attributes = {\"a\": \"alpha\", \"o\": \"omega\", \"g\": \"gamma\"}\n", + "tags = [\"this\", \"field\", \"is\", \"optional\",]\n", + "sketches = [(x.id, x.name) for x in ts_client.list_sketches() if x.name == sketch_name]\n", + "sketch = None\n", + "if sketches:\n", + " print(f\"Using sketch {sketch_name}\")\n", + " sketch = ts_client.get_sketch(sketches[0][0])\n", + " sketch.add_event(message, datetime, timestamp_desc, attributes, tags)\n", + " print(\"Manual event added\")\n", + "else:\n", + " print(f\"no sketch found with name {sketch_name}\") " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## DELETE section" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Delete one or more timelines in the sketch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "timeline_names = [\"ac01-chrome-history\"]\n", + "sketches = [(x.id, x.name) for x in ts_client.list_sketches() if x.name == sketch_name]\n", + "sketch = None\n", + "if sketches:\n", + " print(f\"Using sketch {sketch_name}\")\n", + " sketch = ts_client.get_sketch(sketches[0][0])\n", + " for timeline_name in timeline_names:\n", + " timeline = sketch.get_timeline(timeline_name=timeline_name)\n", + " if timeline:\n", + " timeline.delete()\n", + " print(f\"Timeline {timeline_name} deleted\")\n", + " else:\n", + " print(f\"Timeline {timeline_name} not found\")\n", + "else:\n", + " print(f\"no sketch found with name {sketch_name}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Delete all the timelines in the sketch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketches = [(x.id, x.name) for x in ts_client.list_sketches() if x.name == sketch_name]\n", + "sketch = None\n", + "if sketches:\n", + " print(f\"Using sketch {sketch_name}\")\n", + " sketch = ts_client.get_sketch(sketches[0][0])\n", + " timelines = sketch.list_timelines()\n", + " for timeline in timelines:\n", + " try:\n", + " timeline_name = timeline.name\n", + " timeline.delete()\n", + " print(f\"Timeline {timeline_name} deleted\")\n", + " except Exception as e:\n", + " print(f\"ERROR: Timeline {timeline_name} skipped\")\n", + "else:\n", + " print(f\"no sketch found with name {sketch_name}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ANALYZER Section\n", + "In this section the user can list and run the analyzers available on Timesketch" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### GET list of available analyzers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sketch_ID = 1\n", + "print(f\"Listing analyzers available for sketch ID {sketch_ID}\")\n", + "for list_analyzers in ts_client.get_sketch(sketch_ID).list_available_analyzers():\n", + " print(json.dumps(list_analyzers, indent=4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Retrieve the result of an analyzer\n", + "Retrieve the results of an analyzer given a timeline ID" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "analyzer_name = \"domain\"\n", + "timeline_ID = 12\n", + "sketches = [(x.id, x.name) for x in ts_client.list_sketches()]\n", + "for sketch_info in sketches:\n", + " try:\n", + " sketch = ts_client.get_sketch(sketch_info[0])\n", + " timelines_ID = [x.id for x in sketch.list_timelines()]\n", + " if timeline_ID in timelines_ID:\n", + " print(f\"Found timeline ID {timeline_ID} in sketch {sketch_info[1]}\")\n", + " print(f\"Run anylyzer {analyzer_name} for timeline ID {timeline_ID}...\")\n", + " timeline = sketch.get_timeline(timeline_ID)\n", + " analyzer = timeline.run_analyzer(analyzer_name=analyzer_name, ignore_previous=True)\n", + " print(\"Run below cells to get the analyzer's result\")\n", + " break\n", + " except Exception as e:\n", + " print(f\"Cannot run analyzer on timeline ID {timeline_ID}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "all_results = [x._fetch_data() for x in analyzer]\n", + "all_results" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/requirements.txt b/requirements.txt index 4e8b1aae4b..ae2480fc53 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ alembic==1.11.1 altair==4.1.0 celery==5.2.7 -cryptography==43.0.1 -datasketch==1.5.0 +cryptography==44.0.1 +datasketch==1.6.5 dfir-unfurl==20240627 opensearch-py==2.6.0 Flask==3.0.3 @@ -15,24 +15,24 @@ flask_wtf==1.2.1 google-auth==2.32.0 google_auth_oauthlib==0.4.1 google-cloud-aiplatform==1.70.0 -gunicorn==22.0.0 -numpy==1.23.4 +gunicorn==23.0.0 +numpy==1.26.4 oauthlib==3.1.0 -packaging==24.2 -pandas==1.5.0 +pandas==2.2.3 PyJWT==2.4.0 -python_dateutil==2.8.1 +python_dateutil==2.9.0 PyYAML==6.0.1 redis==4.4.4 requests==2.32.3 +setuptools>=67.0.0 sigmatools==0.19.1 ; python_version > '3.4' -six==1.12.0 +six==1.17.0 SQLAlchemy==1.4.48 -Werkzeug==3.0.3 +Werkzeug==3.0.6 WTForms==3.0.1 xlrd==1.2.0 tabulate==0.9.0 -markdown==3.2.2 +markdown==3.8 networkx==2.5 prometheus-client==0.16.0 prometheus-flask-exporter==0.22.4 diff --git a/run_tests.py b/run_tests.py index 1a7a3035a3..759fcd947b 100755 --- a/run_tests.py +++ b/run_tests.py @@ -4,7 +4,20 @@ def run_python_tests(): - subprocess.check_call(["python3", "-m", "pytest", "timesketch/", "api_client/"]) + # To run pytest in parallel, add "-n" and "auto" (or a specific number + # of workers like "4") to the list of arguments. + subprocess.check_call( + [ + "python3", + "-m", + "pytest", + "-n", + "auto", + "timesketch/", + "api_client/", + "cli_client/", + ] + ) def main(): diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000000..86d1f48b73 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,72 @@ +[metadata] +license_file = LICENSE + +[bdist_rpm] +release = 1 +packager = Timesketch development team +doc_files = AUTHORS + LICENSE +build_requires = python2-setuptools +requires = Mako >= 1.0.7 + PyYAML >= 3.10 + kombu >= 4.1.0 + python-elasticsearch >= 6.0 + python2-alembic >= 0.9.5 + python2-altair >= 2.4.1 + python2-amqp >= 2.2.1 + python2-aniso8601 >= 1.2.1 + python2-asn1crypto >= 0.24.0 + python2-attrs >= 19.1.0 + python2-bcrypt >= 3.1.3 + python2-beautifulsoup4 >= 4.6.3 + python2-billiard >= 3.5.0.3 + python2-blinker >= 1.4 + python2-celery >= 4.1.0 + python2-certifi >= 2017.7.27.1 + python2-cffi >= 1.10.0 + python2-chardet >= 3.0.4 + python2-click >= 6.7 + python2-configparser >= 3.5.0 + python2-cryptography >= 2.4.1 + python2-datasketch >= 1.2.5 + python2-dateutil >= 2.6.1 + python2-editor >= 1.0.3 + python2-entrypoints >= 0.2.3 + python2-enum34 >= 1.1.6 + python2-flask >= 1.0.2 + python2-flask-bcrypt >= 0.7.1 + python2-flask-login >= 0.4.0 + python2-flask-migrate >= 2.1.1 + python2-flask-restful >= 0.3.6 + python2-flask-script >= 2.0.5 + python2-flask-sqlalchemy >= 2.2 + python2-flask-wtf >= 0.14.2 + python2-gunicorn >= 19.7.1 + python2-idna >= 2.6 + python2-ipaddress >= 1.0.22 + python2-itsdangerous >= 0.24 + python2-jinja2 >= 2.10 + python2-jsonschema >= 2.6.0 + python2-jwt >= 1.6.4 + python2-markupsafe >= 1.0 + python2-neo4jrestclient >= 2.1.1 + python2-numpy >= 1.13.3 + python2-pandas >= 0.22.0 + python2-parameterized >= 0.6.1 + python2-pycparser >= 2.18 + python2-pyrsistent >= 0.14.11 + python2-pytz + python2-redis >= 2.10.6 + python2-requests >= 2.20.1 + python2-six >= 1.10.0 + python2-sqlalchemy >= 1.1.13 + python2-toolz >= 0.8.2 + python2-typing >= 3.6.2 + python2-urllib3 >= 1.24.1 + python2-vine >= 1.1.4 + python2-werkzeug >= 0.14.1 + python2-wtforms >= 2.1 + +[bdist_wheel] +universal = 1 + diff --git a/setup.py b/setup.py index 131f54a212..9018ee4c69 100755 --- a/setup.py +++ b/setup.py @@ -18,17 +18,21 @@ sudo python setup.py install """ -from __future__ import print_function, unicode_literals +from __future__ import print_function +from __future__ import unicode_literals import glob import os import sys import pkg_resources -from setuptools import find_packages, setup + +from setuptools import find_packages +from setuptools import setup from timesketch import version + version_tuple = (sys.version_info[0], sys.version_info[1]) if version_tuple < (3, 6): print( @@ -80,6 +84,11 @@ def parse_requirements_from_file(path): "Operating System :: OS Independent", "Programming Language :: Python", ], + data_files=[ + ("share/timesketch", glob.glob(os.path.join("data", "*.*"))), + ("share/timesketch/linux", glob.glob(os.path.join("data", "linux", "*.*"))), + ("share/doc/timesketch", ["AUTHORS", "LICENSE", "README.md"]), + ], packages=find_packages(), include_package_data=True, zip_safe=False, diff --git a/test_dependencies.ini b/test_dependencies.ini new file mode 100644 index 0000000000..cc382f43ab --- /dev/null +++ b/test_dependencies.ini @@ -0,0 +1,26 @@ +[Flask-Testing] +dpkg_name: python3-flask-testing +minimum_version: 0.6.2 +rpm_name: python3-flask-testing + +[mock] +dpkg_name: python3-mock +minimum_version: 2.0.0 +rpm_name: python3-mock +version_property: __version__ + +[nose] +dpkg_name: python3-nose +minimum_version: 1.3.7 +rpm_name: python3-nose + +[pbr] +dpkg_name: python3-pbr +minimum_version: 4.2.0 +rpm_name: python3-pbr + +[six] +dpkg_name: python3-six +minimum_version: 1.1.0 +rpm_name: python3-six +version_property: __version__ diff --git a/test_requirements.txt b/test_requirements.txt index a68f4f1e41..90c14a20c3 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -5,4 +5,6 @@ pbr >= 4.2.0 beautifulsoup4 >= 4.8.2 coverage >= 5.0.2 httmock >= 1.3.0 -astroid==2.4.0 +pylint==2.17.7 +astroid==2.15.8 +pytest-xdist>=3.6.1 \ No newline at end of file diff --git a/timesketch.ini b/timesketch.ini new file mode 100644 index 0000000000..75f90809ed --- /dev/null +++ b/timesketch.ini @@ -0,0 +1,10 @@ +[project] +name: timesketch +name_description: Timesketch +maintainer: Timesketch development team +homepage_url: http://timesketch.org +description_short: Collaborative digital forensic timeline analysis +description_long: Timesketch is a web based tool for collaborative forensic + timeline analysis. Using sketches you and your collaborators can easily + organize timelines and analyze them all at the same time. Add meaning + to your raw data with rich annotations, comments, tags and stars. diff --git a/timesketch/__init__.py b/timesketch/__init__.py index 17f97b280e..026caf45a8 100644 --- a/timesketch/__init__.py +++ b/timesketch/__init__.py @@ -25,7 +25,7 @@ def create_app(config=None): Returns: Application object (instance of flask.Flask). """ - + # pylint: disable=import-outside-toplevel from timesketch import app return app.create_app(config) diff --git a/timesketch/api/v1/export.py b/timesketch/api/v1/export.py index 6eb69500da..8d56a063bd 100644 --- a/timesketch/api/v1/export.py +++ b/timesketch/api/v1/export.py @@ -13,7 +13,6 @@ # limitations under the License. """This module holds methods and classes to export events.""" -from __future__ import unicode_literals import io import json @@ -24,6 +23,7 @@ from timesketch.api.v1 import utils from timesketch.lib.stories import api_fetcher as story_api_fetcher + logger = logging.getLogger("timesketch.api_exporter") @@ -37,7 +37,7 @@ def export_aggregation(aggregation, sketch, zip_file): zip_file (ZipFile): a zip file handle that can be used to write content to. """ - name = "{0:04d}_{1:s}".format(aggregation.id, aggregation.name) + name = f"{aggregation.id:04d}_{aggregation.name:s}" parameters = json.loads(aggregation.parameters) result_obj, meta = utils.run_aggregator( sketch.id, @@ -45,7 +45,7 @@ def export_aggregation(aggregation, sketch, zip_file): aggregator_parameters=parameters, ) - zip_file.writestr("aggregations/{0:s}.meta".format(name), data=json.dumps(meta)) + zip_file.writestr(f"aggregations/{name:s}.meta", data=json.dumps(meta)) html = result_obj.to_chart( chart_name=meta.get("chart_type"), @@ -54,13 +54,13 @@ def export_aggregation(aggregation, sketch, zip_file): interactive=True, as_html=True, ) - zip_file.writestr("aggregations/{0:s}.html".format(name), data=html) + zip_file.writestr(f"aggregations/{name:s}.html", data=html) string_io = io.StringIO() data_frame = result_obj.to_pandas() data_frame.to_csv(string_io, index=False) string_io.seek(0) - zip_file.writestr("aggregations/{0:s}.csv".format(name), data=string_io.read()) + zip_file.writestr(f"aggregations/{name:s}.csv", data=string_io.read()) def export_aggregation_group(group, sketch, zip_file): @@ -73,11 +73,11 @@ def export_aggregation_group(group, sketch, zip_file): zip_file (ZipFile): a zip file handle that can be used to write content to. """ - name = "{0:04d}_{1:s}".format(group.id, group.name) + name = f"{group.id:04d}_{group.name:s}" chart, _, meta = utils.run_aggregator_group(group, sketch_id=sketch.id) - zip_file.writestr("aggregation_groups/{0:s}.meta".format(name), json.dumps(meta)) - zip_file.writestr("aggregation_groups/{0:s}.html".format(name), chart.to_html()) + zip_file.writestr(f"aggregation_groups/{name:s}.meta", json.dumps(meta)) + zip_file.writestr(f"aggregation_groups/{name:s}.html", chart.to_html()) def export_story(story, sketch, story_exporter, zip_file): @@ -106,7 +106,7 @@ def export_story(story, sketch, story_exporter, zip_file): exporter.set_title(story.title) zip_file.writestr( - "stories/{0:04d}_{1:s}.html".format(story.id, story.title), + f"stories/{story.id:04d}_{story.title:s}.html", data=exporter.export_story(), ) @@ -177,7 +177,7 @@ def query_to_filehandle( event_count = len(result["hits"]["hits"]) while event_count < total_count: - + # pylint: disable=unexpected-keyword-arg result = datastore.client.scroll(scroll_id=scroll_id, scroll="1m") event_count += len(result["hits"]["hits"]) add_frame = query_results_to_dataframe(result, sketch) @@ -186,8 +186,11 @@ def query_to_filehandle( else: logger.warning( "Data Frame returned from a search operation was " - "empty, count {0:d} out of {1:d} total. Query is: " - '"{2:s}"'.format(event_count, total_count, query_string or query_dsl) + "empty, count %d out of %d total. Query is: " + '"%s"', + event_count, + total_count, + query_string or query_dsl, ) fh = io.StringIO() diff --git a/timesketch/api/v1/resources/__init__.py b/timesketch/api/v1/resources/__init__.py index 9092b3b4f8..6328916d96 100644 --- a/timesketch/api/v1/resources/__init__.py +++ b/timesketch/api/v1/resources/__init__.py @@ -15,9 +15,9 @@ The timesketch API is a RESTful API that exposes the following resources: """ -from __future__ import unicode_literals import logging +from typing import Optional, Dict from flask import current_app from flask import jsonify @@ -35,7 +35,7 @@ ) -class ResourceMixin(object): +class ResourceMixin: """Mixin for API resources.""" # Schemas for database model resources @@ -379,7 +379,11 @@ def datastore(self): ) def to_json( - self, model, model_fields=None, meta=None, status_code=HTTP_STATUS_CODE_OK + self, + model: object, + model_fields: Optional[Dict] = None, + meta: Optional[Dict] = None, + status_code: int = HTTP_STATUS_CODE_OK, ): """Create json response from a database models. @@ -393,7 +397,7 @@ def to_json( Response in json format (instance of flask.wrappers.Response) """ if not meta: - meta = dict() + meta = {} schema = {"meta": meta, "objects": []} diff --git a/timesketch/api/v1/resources/aggregation.py b/timesketch/api/v1/resources/aggregation.py index 630a34484c..f5aff7f3e7 100644 --- a/timesketch/api/v1/resources/aggregation.py +++ b/timesketch/api/v1/resources/aggregation.py @@ -16,32 +16,39 @@ import json import time -from flask import abort, jsonify, request -from flask_login import current_user, login_required -from flask_restful import Resource, marshal from opensearchpy.exceptions import NotFoundError -from timesketch.api.v1 import resources, utils +from flask import current_app +from flask import jsonify +from flask import request +from flask import abort +from flask_restful import marshal +from flask_restful import Resource +from flask_login import login_required +from flask_login import current_user + +from timesketch.api.v1 import resources +from timesketch.api.v1 import utils from timesketch.lib import forms from timesketch.lib import utils as lib_utils from timesketch.lib.aggregators import apex +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND from timesketch.lib.aggregators import manager as aggregator_manager -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) from timesketch.models import db_session -from timesketch.models.sketch import Aggregation, AggregationGroup, Sketch +from timesketch.models.sketch import Aggregation +from timesketch.models.sketch import AggregationGroup +from timesketch.models.sketch import Sketch class AggregationResource(resources.ResourceMixin, Resource): """Resource to query for aggregated results.""" @login_required - def get(self, sketch_id, aggregation_id): + def get(self, sketch_id: int, aggregation_id: int): """Handles GET request to the resource. Handler for /api/v1/sketches/:sketch_id/aggregation/:aggregation_id @@ -68,16 +75,14 @@ def get(self, sketch_id, aggregation_id): if not aggregation: abort( HTTP_STATUS_CODE_NOT_FOUND, - "The aggregation ID ({0:d}) does not exist.".format(aggregation_id), + f"The aggregation ID ({aggregation_id:d}) does not exist.", ) # Check that this aggregation belongs to the sketch if aggregation.sketch_id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "The sketch ID ({0:d}) does not match with the defined " - "sketch in the aggregation ({1:d})".format( - aggregation.sketch_id, sketch.id - ), + f"The sketch ID ({aggregation.sketch_id:d}) does not match with " + f"the defined sketch in the aggregation ({sketch.id:d})", ) # If this is a user state view, check that it @@ -94,7 +99,8 @@ def get(self, sketch_id, aggregation_id): return self.to_json(aggregation) @login_required - def post(self, sketch_id, aggregation_id): + # pylint: disable=unused-argument + def post(self, sketch_id: int, aggregation_id: int): """Handles POST request to the resource. Handler for /api/v1/sketches/:sketch_id/aggregation/:aggregation_id @@ -161,12 +167,12 @@ def post(self, sketch_id, aggregation_id): return self.to_json(aggregation, status_code=HTTP_STATUS_CODE_CREATED) @login_required - def delete(self, sketch_id, aggregation_id): + def delete(self, sketch_id: int, aggregation_id: int): """Handles DELETE request to the resource. Args: sketch_id: Integer primary key for a sketch database model. - group_id: Integer primary key for an aggregation group database + aggregation_id: Integer primary key for an aggregation group database model. """ sketch = Sketch.get_with_acl(sketch_id) @@ -186,8 +192,8 @@ def delete(self, sketch_id, aggregation_id): # Check that this aggregation belongs to the sketch if aggregation.sketch_id != sketch.id: msg = ( - "The sketch ID ({0:d}) does not match with the aggregation " - "sketch ID ({1:d})".format(sketch.id, aggregation.sketch_id) + f"The sketch ID ({sketch.id:d}) does not match with the aggregation " + f"sketch ID ({aggregation.sketch_id:d})" ) abort(HTTP_STATUS_CODE_FORBIDDEN, msg) @@ -267,7 +273,7 @@ class AggregationGroupResource(resources.ResourceMixin, Resource): """Resource for aggregation group requests.""" @login_required - def get(self, sketch_id, group_id): + def get(self, sketch_id: int, group_id: int): """Handles GET request to the resource. Args: @@ -292,8 +298,8 @@ def get(self, sketch_id, group_id): # Check that this group belongs to the sketch if group.sketch_id != sketch.id: msg = ( - "The sketch ID ({0:d}) does not match with the aggregation " - "group sketch ID ({1:d})".format(sketch.id, group.sketch_id) + f"The sketch ID ({sketch.id:d}) does not match with the aggregation " + f"group sketch ID ({group.sketch_id:d})" ) abort(HTTP_STATUS_CODE_FORBIDDEN, msg) @@ -313,7 +319,7 @@ def get(self, sketch_id, group_id): return jsonify(schema) @login_required - def post(self, sketch_id, group_id): + def post(self, sketch_id: int, group_id: int): """Handles POST request to the resource. Args: @@ -332,8 +338,8 @@ def post(self, sketch_id, group_id): # Check that this group belongs to the sketch if group.sketch_id != sketch.id: msg = ( - "The sketch ID ({0:d}) does not match with the aggregation " - "group sketch ID ({1:d})".format(sketch.id, group.sketch_id) + f"The sketch ID ({sketch.id:d}) does not match with the aggregation " + f"group sketch ID ({group.sketch_id:d})" ) abort(HTTP_STATUS_CODE_FORBIDDEN, msg) @@ -366,7 +372,7 @@ def post(self, sketch_id, group_id): if not aggregation: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "No aggregation found for ID: {0:d}".format(agg_id), + f"No aggregation found for ID: {agg_id:d}", ) aggregations.append(aggregation) @@ -378,7 +384,7 @@ def post(self, sketch_id, group_id): return self.to_json(group, status_code=HTTP_STATUS_CODE_CREATED) @login_required - def delete(self, sketch_id, group_id): + def delete(self, sketch_id: int, group_id: int): """Handles DELETE request to the resource. Args: @@ -398,8 +404,8 @@ def delete(self, sketch_id, group_id): # Check that this group belongs to the sketch if group.sketch_id != sketch.id: msg = ( - "The sketch ID ({0:d}) does not match with the aggregation " - "group sketch ID ({1:d})".format(sketch.id, group.sketch_id) + f"The sketch ID ({sketch.id:d}) does not match with the aggregation " + f"group sketch ID ({group.sketch_id:d})" ) abort(HTTP_STATUS_CODE_FORBIDDEN, msg) @@ -424,7 +430,7 @@ class AggregationExploreResource(resources.ResourceMixin, Resource): REMOVE_FIELDS = frozenset(["_shards", "hits", "timed_out", "took"]) @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Handler for /api/v1/sketches//aggregation/explore/ @@ -458,10 +464,17 @@ def post(self, sketch_id): "Not able to run aggregation on an archived sketch.", ) + include_processing_timelines = form.include_processing_timelines.data + allowed_statuses = ["ready"] + if include_processing_timelines and current_app.config.get( + "SEARCH_PROCESSING_TIMELINES", False + ): + allowed_statuses.append("processing") + sketch_indices = { t.searchindex.index_name for t in sketch.timelines - if t.get_status.status.lower() == "ready" + if t.get_status.status.lower() in allowed_statuses } aggregation_dsl = form.aggregation_dsl.data @@ -485,10 +498,12 @@ def post(self, sketch_id): aggregator_parameters = {} indices = aggregator_parameters.pop("index", sketch_indices) - indices, timeline_ids = lib_utils.get_validated_indices(indices, sketch) + indices, timeline_ids = lib_utils.get_validated_indices( + indices, sketch, form.include_processing_timelines.data + ) if not (indices or timeline_ids): - abort(HTTP_STATUS_CODE_BAD_REQUEST, "No indices to aggregate on") + abort(HTTP_STATUS_CODE_NOT_FOUND, "No indices to aggregate on found.") aggregator = agg_class( sketch_id=sketch_id, indices=indices, timeline_ids=timeline_ids @@ -502,17 +517,16 @@ def post(self, sketch_id): try: result_obj = aggregator.run(**aggregator_parameters) except NotFoundError: + indices_msg = ", ".join(indices) abort( HTTP_STATUS_CODE_NOT_FOUND, - "Attempting to run an aggregation on a non-existing " - "index, index: {0:s} and parameters: {1!s}".format( - ",".join(indices), aggregator_parameters - ), + "Attempting to run an aggregation on a non-existing index, " + f"index: {indices_msg:s} and parameters: {aggregator_parameters!s}", ) except ValueError as exc: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Unable to run the aggregation, with error: {0!s}".format(exc), + f"Unable to run the aggregation, with error: {exc!s}", ) time_after = time.time() @@ -548,7 +562,7 @@ def post(self, sketch_id): meta["vega_chart_title"] = chart_title elif aggregation_dsl: - + # pylint: disable=unexpected-keyword-arg result = self.datastore.client.search( index=",".join(sketch_indices), body=aggregation_dsl, size=0 ) @@ -581,7 +595,7 @@ class AggregationListResource(resources.ResourceMixin, Resource): """Resource to query for a list of stored aggregation queries.""" @login_required - def get(self, sketch_id): + def get(self, sketch_id: int): """Handles GET request to the resource. Handler for /api/v1/sketches//aggregation/ @@ -609,7 +623,9 @@ def get(self, sketch_id): return self.to_json(aggregations) @staticmethod - def create_aggregation_from_form(sketch, form): + def create_aggregation_from_form( + sketch: Sketch, form: forms.AggregationExploreForm + ): """Creates an aggregation from form data. Args: @@ -653,7 +669,7 @@ def create_aggregation_from_form(sketch, form): return aggregation @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Args: @@ -691,7 +707,7 @@ class AggregationGroupListResource(resources.ResourceMixin, Resource): """Resource to query for a list of stored aggregation queries.""" @login_required - def get(self, sketch_id): + def get(self, sketch_id: int): """Handles GET request to the resource. Handler for /api/v1/sketches//aggregation/group/ @@ -735,7 +751,7 @@ def get(self, sketch_id): return response @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Args: diff --git a/timesketch/api/v1/resources/analysis.py b/timesketch/api/v1/resources/analysis.py index 524c976f3f..37d2559111 100644 --- a/timesketch/api/v1/resources/analysis.py +++ b/timesketch/api/v1/resources/analysis.py @@ -12,24 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. """Analysis resources for version 1 of the Timesketch API.""" -import collections import fnmatch +import collections import logging import prometheus_client -from flask import abort, jsonify, request -from flask_login import current_user, login_required -from flask_restful import Resource, reqparse + +from flask import jsonify +from flask import request +from flask import abort +from flask_restful import Resource +from flask_restful import reqparse +from flask_login import login_required +from flask_login import current_user from timesketch.api.v1 import resources from timesketch.lib.analyzers import manager as analyzer_manager -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, - METRICS_NAMESPACE, -) -from timesketch.models.sketch import Analysis, AnalysisSession, Sketch, Timeline +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND +from timesketch.lib.definitions import METRICS_NAMESPACE +from timesketch.models.sketch import Analysis +from timesketch.models.sketch import AnalysisSession +from timesketch.models.sketch import Sketch +from timesketch.models.sketch import Timeline # Metrics definitions METRICS = { @@ -287,7 +293,7 @@ def post(self, sketch_id): return abort(HTTP_STATUS_CODE_BAD_REQUEST, "No analyzers found to run.") # Import here to avoid circular imports. - + # pylint: disable=import-outside-toplevel from timesketch.lib import tasks # TODO: Change to run on Timeline instead of Index @@ -315,7 +321,7 @@ def post(self, sketch_id): except KeyError as e: logger.warning( "Unable to build analyzer pipeline, analyzer does not " - "exists. Error message: {0!s}".format(e) + "exists. Error message: {!s}".format(e) ) continue diff --git a/timesketch/api/v1/resources/archive.py b/timesketch/api/v1/resources/archive.py index 2b493fc4e5..5010cc55a8 100644 --- a/timesketch/api/v1/resources/archive.py +++ b/timesketch/api/v1/resources/archive.py @@ -13,7 +13,6 @@ # limitations under the License. """This module holds archive API calls for version 1 of the Timesketch API.""" -from __future__ import unicode_literals import datetime import io @@ -22,21 +21,30 @@ import zipfile import opensearchpy -import pandas as pd -from flask import abort, current_app, jsonify, request, send_file -from flask_login import current_user, login_required + +from flask import abort +from flask import current_app +from flask import jsonify +from flask import request +from flask import send_file +from flask_login import current_user +from flask_login import login_required from flask_restful import Resource +import pandas as pd + from timesketch import version -from timesketch.api.v1 import export, resources, utils -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) +from timesketch.api.v1 import export +from timesketch.api.v1 import resources +from timesketch.api.v1 import utils +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK from timesketch.lib.stories import manager as story_export_manager -from timesketch.models.sketch import Event, Sketch +from timesketch.models.sketch import Event +from timesketch.models.sketch import Sketch + logger = logging.getLogger("timesketch.api_archive") @@ -159,10 +167,10 @@ def post(self, sketch_id): return abort( HTTP_STATUS_CODE_NOT_FOUND, - "The action: [{0:s}] is not supported.".format(action), + f"The action: [{action:s}] is not supported.", ) - def _get_all_events_with_a_label(self, label, sketch): + def _get_all_events_with_a_label(self, label: str, sketch: Sketch): """Returns a DataFrame with events in a sketch with a certain label. Args: @@ -275,7 +283,7 @@ def _export_tagged_events(self, sketch, zip_file): string_io.seek(0) zip_file.writestr("events/tagged_event_stats.csv", data=string_io.read()) - def _export_sketch(self, sketch): + def _export_sketch(self, sketch: Sketch): """Returns a ZIP file with the exported content of a sketch.""" file_object = io.BytesIO() sketch_is_archived = sketch.get_status.status == "archived" @@ -332,7 +340,7 @@ def _export_view(self, view, sketch, zip_file): zip_file (ZipFile): a zip file handle that can be used to write content to. """ - name = "{0:04d}_{1:s}".format(view.id, view.name) + name = f"{view.id:04d}_{view.name:s}" if view.query_filter: query_filter = json.loads(view.query_filter) @@ -377,7 +385,7 @@ def _export_view(self, view, sketch, zip_file): event_count = len(result["hits"]["hits"]) while event_count < total_count: - + # pylint: disable=unexpected-keyword-arg result = self.datastore.client.scroll(scroll_id=scroll_id, scroll="1m") event_count += len(result["hits"]["hits"]) add_frame = export.query_results_to_dataframe(result, sketch) @@ -386,8 +394,8 @@ def _export_view(self, view, sketch, zip_file): else: logger.warning( "Data Frame returned from a search operation was " - "empty, count {0:d} out of {1:d} total. Query is: " - '"{2:s}"'.format( + "empty, count {:d} out of {:d} total. Query is: " + '"{:s}"'.format( event_count, total_count, view.query_string or query_dsl ) ) @@ -398,7 +406,7 @@ def _export_view(self, view, sketch, zip_file): else: fh = export.query_results_to_filehandle(result, sketch) - zip_file.writestr("views/{0:s}.csv".format(name), data=fh.read()) + zip_file.writestr(f"views/{name:s}.csv", data=fh.read()) if not view.user: username = "System" @@ -414,9 +422,9 @@ def _export_view(self, view, sketch, zip_file): "username": username, "sketch_id": view.sketch_id, } - zip_file.writestr("views/{0:s}.meta".format(name), data=json.dumps(meta)) + zip_file.writestr(f"views/{name:s}.meta", data=json.dumps(meta)) - def _unarchive_sketch(self, sketch): + def _unarchive_sketch(self, sketch: Sketch): """Unarchives a sketch by opening up all indices and removing labels. Args: @@ -426,7 +434,7 @@ def _unarchive_sketch(self, sketch): abort( HTTP_STATUS_CODE_BAD_REQUEST, "Unable to unarchive a sketch that wasn't already archived " - "(sketch: {0:d})".format(sketch.id), + "(sketch: {:d})".format(sketch.id), ) sketch.set_status(status="ready") @@ -446,14 +454,14 @@ def _unarchive_sketch(self, sketch): self.datastore.client.indices.open(",".join(indexes_to_open)) except opensearchpy.NotFoundError: logger.error( - "Unable to open index, not found: {0:s}".format( + "Unable to open index, not found: {:s}".format( ",".join(indexes_to_open) ) ) return HTTP_STATUS_CODE_OK - def _archive_sketch(self, sketch): + def _archive_sketch(self, sketch: Sketch): """Unarchives a sketch by opening up all indices and removing labels. Args: @@ -463,7 +471,7 @@ def _archive_sketch(self, sketch): abort( HTTP_STATUS_CODE_BAD_REQUEST, "Unable to archive a sketch that was already archived " - "(sketch: {0:d})".format(sketch.id), + "(sketch: {:d})".format(sketch.id), ) labels_to_prevent_deletion = current_app.config.get( @@ -474,8 +482,7 @@ def _archive_sketch(self, sketch): if sketch.has_label(label): abort( HTTP_STATUS_CODE_FORBIDDEN, - "A sketch with the label {0:s} cannot be " - "archived.".format(label), + "A sketch with the label {:s} cannot be " "archived.".format(label), ) sketch.set_status(status="archived") @@ -493,7 +500,7 @@ def _archive_sketch(self, sketch): search_index = timeline.searchindex if not all( - [x.get_status.status == "archived" for x in search_index.timelines] + x.get_status.status == "archived" for x in search_index.timelines ): continue search_index.set_status(status="archived") @@ -505,7 +512,7 @@ def _archive_sketch(self, sketch): self.datastore.client.indices.close(",".join(indexes_to_close)) except opensearchpy.NotFoundError: logger.error( - "Unable to close indices, not found: {0:s}".format( + "Unable to close indices, not found: {:s}".format( ",".join(indexes_to_close) ) ) diff --git a/timesketch/api/v1/resources/attribute.py b/timesketch/api/v1/resources/attribute.py index cc09e56484..3a1c3748b4 100644 --- a/timesketch/api/v1/resources/attribute.py +++ b/timesketch/api/v1/resources/attribute.py @@ -55,10 +55,10 @@ def _validate_form_entry(self, form, key_to_check): """ value = form.get(key_to_check) if not value: - return "Unable to save an attribute without a {0:s}.".format(key_to_check) + return f"Unable to save an attribute without a {key_to_check:s}." if not isinstance(value, str): - return "Unable to save an attribute without a {0:s}.".format(key_to_check) + return f"Unable to save an attribute without a {key_to_check:s}." return "" @@ -133,7 +133,7 @@ def post(self, sketch_id): ontology_lib.OntologyManager.encode_value(x, cast_as_string) for x in values ] - if any([not isinstance(x, str) for x in value_strings]): + if any(not isinstance(x, str) for x in value_strings): return abort( HTTP_STATUS_CODE_BAD_REQUEST, "All values needs to be stored as strings.", diff --git a/timesketch/api/v1/resources/datafinder.py b/timesketch/api/v1/resources/datafinder.py index 46b0930a7b..bc9db47751 100644 --- a/timesketch/api/v1/resources/datafinder.py +++ b/timesketch/api/v1/resources/datafinder.py @@ -16,17 +16,18 @@ import logging import uuid -from flask import abort, jsonify, request -from flask_login import login_required +from flask import jsonify +from flask import request +from flask import abort from flask_restful import Resource +from flask_login import login_required from timesketch.api.v1 import resources -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_NOT_FOUND, -) +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND from timesketch.models.sketch import Sketch + logger = logging.getLogger("timesketch.data_api") @@ -79,7 +80,7 @@ def post(self, sketch_id): if not isinstance(rule_names, (list, tuple)): abort(HTTP_STATUS_CODE_BAD_REQUEST, "Rule names needs to a list") - if any([not isinstance(x, str) for x in rule_names]): + if any(not isinstance(x, str) for x in rule_names): abort( HTTP_STATUS_CODE_BAD_REQUEST, "Rule names needs to a list of string values.", @@ -100,7 +101,7 @@ def post(self, sketch_id): # Start Celery pipeline for indexing and analysis. # Import here to avoid circular imports. - + # pylint: disable=import-outside-toplevel from timesketch.lib import tasks pipeline = tasks.run_data_finder( diff --git a/timesketch/api/v1/resources/datasource.py b/timesketch/api/v1/resources/datasource.py index 8b3da0b333..61e7e84fee 100644 --- a/timesketch/api/v1/resources/datasource.py +++ b/timesketch/api/v1/resources/datasource.py @@ -98,7 +98,7 @@ def post(self, sketch_id): if not sketch.has_permission(current_user, "write"): abort( HTTP_STATUS_CODE_FORBIDDEN, - ("User does not have sufficient write access to " "to the sketch."), + ("User does not have sufficient write access to the sketch."), ) form = request.json @@ -109,7 +109,7 @@ def post(self, sketch_id): if not timeline_id: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Unable to create a data source without a timeline " "identifier.", + "Unable to create a data source without a timeline identifier.", ) timeline = Timeline.get_by_id(timeline_id) @@ -119,7 +119,7 @@ def post(self, sketch_id): if timeline not in sketch.active_timelines: abort( HTTP_STATUS_CODE_NOT_FOUND, - "The timeline is not part of the active timelines in " "the sketch.", + "The timeline is not part of the active timelines in the sketch.", ) datasource = DataSource( diff --git a/timesketch/api/v1/resources/event.py b/timesketch/api/v1/resources/event.py index 870967b7e7..bc68828169 100644 --- a/timesketch/api/v1/resources/event.py +++ b/timesketch/api/v1/resources/event.py @@ -14,31 +14,42 @@ """Event resources for version 1 of the Timesketch API.""" import codecs +import datetime import hashlib import json import logging import math import time +import six +import dateutil +from opensearchpy.exceptions import RequestError import numpy as np import pandas as pd -import six -from flask import abort, jsonify, request -from flask_login import current_user, login_required -from flask_restful import Resource, reqparse -from opensearchpy.exceptions import RequestError + +from flask import current_app +from flask import jsonify +from flask import request +from flask import abort +from flask_restful import Resource, inputs +from flask_restful import reqparse +from flask_login import login_required +from flask_login import current_user from timesketch.api.v1 import resources from timesketch.lib import forms -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND from timesketch.models import db_session -from timesketch.models.sketch import Event, SearchHistory, SearchIndex, Sketch, Timeline +from timesketch.models.sketch import Event +from timesketch.models.sketch import SearchIndex +from timesketch.models.sketch import Sketch +from timesketch.models.sketch import Timeline +from timesketch.models.sketch import SearchHistory + logger = logging.getLogger("timesketch.event_api") @@ -88,12 +99,12 @@ class EventCreateResource(resources.ResourceMixin, Resource): """Resource to create an annotation for an event.""" @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Handler for /api/v1/sketches/:sketch_id/event/create/ Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: An annotation in JSON (instance of flask.wrappers.Response) @@ -113,12 +124,29 @@ def post(self, sketch_id): form = request.data timeline_name = "Manual events" - index_name_seed = "timesketch_{0:d}".format(sketch_id) + index_name_seed = f"timesketch_{sketch_id:d}" date_string = form.get("date_string") + if not date_string: + date = datetime.datetime.utcnow().isoformat() + else: + # derive datetime from timestamp: + try: + date = dateutil.parser.parse(date_string) + except (dateutil.parser.ParserError, OverflowError) as e: + logger.error("Unable to convert date string", exc_info=True) + abort( + HTTP_STATUS_CODE_BAD_REQUEST, + "Unable to add event, not able to convert the date " + f"string. Was it properly formatted? Error: {e!s}", + ) + + timestamp = int(time.mktime(date.utctimetuple())) * 1000000 + timestamp += date.microsecond event = { "datetime": date_string, + "timestamp": timestamp, "timestamp_desc": form.get("timestamp_desc", "Event Happened"), "message": form.get("message", "No message string"), } @@ -174,6 +202,8 @@ def post(self, sketch_id): db_session.commit() if sketch and sketch.has_permission(current_user, "write"): + self.datastore.import_event(index_name, event, flush_interval=1) + timeline = Timeline.get_or_create( name=searchindex.name, description=searchindex.description, @@ -185,25 +215,20 @@ def post(self, sketch_id): if timeline not in sketch.timelines: sketch.timelines.append(timeline) - # Include the timeline ID in the event, otherwise Timesketch is not - # aware that the event is part of a timeline. - event["__ts_timeline_id"] = timeline.id - self.datastore.import_event(index_name, event, flush_interval=1) - timeline.set_status("ready") db_session.add(timeline) db_session.commit() # TODO: Can this be narrowed down, both in terms of the scope it # applies to, as well as not to catch a generic exception. - except Exception as e: + except Exception as e: # pylint: disable=broad-except abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Failed to add event ({0!s})".format(e), + f"Failed to add event ({e!s})", ) # Return Timeline if it was created. - + # pylint: disable=no-else-return if timeline: return self.to_json(timeline, status_code=HTTP_STATUS_CODE_CREATED) @@ -222,19 +247,23 @@ def __init__(self): super().__init__() self.parser = reqparse.RequestParser() self.parser.add_argument( - "searchindex_id", type=six.text_type, required=True, location="args" + "searchindex_id", type=str, required=True, location="args" ) + self.parser.add_argument("event_id", type=str, required=True, location="args") self.parser.add_argument( - "event_id", type=six.text_type, required=True, location="args" + "include_processing_timelines", + type=inputs.boolean, + required=False, + location="args", ) @login_required - def get(self, sketch_id): + def get(self, sketch_id: int): """Handles GET request to the resource. Handler for /api/v1/sketches/:sketch_id/event/ Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: JSON of the datastore event @@ -251,12 +280,6 @@ def get(self, sketch_id): ) searchindex_id = args.get("searchindex_id") - - # In case the index is part of an alias index, the alias name is used as searchindex - searchindex_id, searchindex_name = self.datastore.resolve_index_alias( - searchindex_id - ) - searchindex = SearchIndex.query.filter_by(index_name=searchindex_id).first() if not searchindex: abort( @@ -270,21 +293,29 @@ def get(self, sketch_id): ) event_id = args.get("event_id") + include_processing_timelines = bool( + args.get("include_processing_timelines", False) + ) + allowed_statuses = ["ready"] + if include_processing_timelines and current_app.config.get( + "SEARCH_PROCESSING_TIMELINES", False + ): + allowed_statuses.append("processing") indices = [ t.searchindex.index_name for t in sketch.timelines - if t.get_status.status.lower() == "ready" + if t.get_status.status.lower() in allowed_statuses ] # Check if the requested searchindex is part of the sketch if searchindex_id not in indices: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Search index ID ({0!s}) does not belong to the list " - "of indices".format(searchindex_id), + f"Search index ID ({searchindex_id!s}) does not belong to the list" + " of indices", ) - result = self.datastore.get_event(searchindex_name, event_id) + result = self.datastore.get_event(searchindex_id, event_id) event = Event.query.filter_by( sketch=sketch, searchindex=searchindex, document_id=event_id @@ -323,6 +354,7 @@ class EventAddAttributeResource(resources.ResourceMixin, Resource): ATTRIBUTE_FIELDS = ["attr_name", "attr_value"] RESERVED_ATTRIBUTE_NAMES = [ "datetime", + "timestamp", "message", "timestamp_desc", ] @@ -389,13 +421,13 @@ def _parse_request(self, flask_request): return events_by_index @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST requests to the resource. Allows new attributes to be added to multiple events in one request. Args: - sketch_id: Integer primary key for a sketch database model. + sketch_id: (int) Integer primary key for a sketch database model. Returns: A JSON instance of flask.wrappers.Response. Response metadata @@ -436,12 +468,13 @@ def post(self, sketch_id): query_body["size"] = size query_body["terminate_after"] = size + # pylint: disable=unexpected-keyword-arg eventid_search = datastore.client.search( body=json.dumps(query_body), index=[index], search_type="query_then_fetch", ) - + # pylint: enable=unexpected-keyword-arg existing_events = eventid_search["hits"]["hits"] existing_events_dict = { event["_id"]: event for event in existing_events @@ -519,11 +552,11 @@ class EventTaggingResource(resources.ResourceMixin, Resource): BUFFER_SIZE_FOR_ES_BULK_UPDATES = 10000 @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: An annotation in JSON (instance of flask.wrappers.Response) @@ -555,7 +588,7 @@ def post(self, sketch_id): except json.JSONDecodeError as e: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Unable to read the tags, with error: {0!s}".format(e), + f"Unable to read the tags, with error: {e!s}", ) if not isinstance(tags_to_add, list): @@ -574,14 +607,13 @@ def post(self, sketch_id): if field not in event_df: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Events need to have a [{0:s}] field associated " - "to it.".format(field), + f"Events need to have a [{field:s}] field associated to it.", ) if any(event_df[field].isna()): abort( HTTP_STATUS_CODE_BAD_REQUEST, - "All events need to have a [{0:s}] field " - "set, it cannot have a non-value.".format(field), + f"All events need to have a [{field:s}] field set, it cannot" + "have a non-value.", ) # Remove any potential extra fields from the events. @@ -596,8 +628,8 @@ def post(self, sketch_id): if event_size > self.MAX_EVENTS_TO_TAG: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Cannot tag more than {0:d} events in a single " - "request".format(self.MAX_EVENTS_TO_TAG), + f"Cannot tag more than {self.MAX_EVENTS_TO_TAG:d} events in a " + "single request", ) tag_dict["number_of_events_passed_to_api"] = event_size @@ -633,20 +665,28 @@ def post(self, sketch_id): query_body["terminate_after"] = size try: - - search = datastore.client.search( - body=json.dumps(query_body), - index=[_index], - _source_includes=["tag"], - search_type="query_then_fetch", - ) + # pylint: disable=unexpected-keyword-arg + if datastore.version.startswith("6"): + search = datastore.client.search( + body=json.dumps(query_body), + index=[_index], + _source_include=["tag"], + search_type="query_then_fetch", + ) + else: + search = datastore.client.search( + body=json.dumps(query_body), + index=[_index], + _source_includes=["tag"], + search_type="query_then_fetch", + ) except RequestError as e: logger.error("Unable to query for events", exc_info=True) - errors.append("Unable to query for events, {0!s}".format(e)) + errors.append(f"Unable to query for events, {e!s}") abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Unable to query events, {0!s}".format(e), + f"Unable to query events, {e!s}", ) for result in search["hits"]["hits"]: @@ -712,6 +752,7 @@ class EventAnnotationResource(resources.ResourceMixin, Resource): event_id: The datastore event id as string annotation_type: The annotation type (comment,label) as string annotation_id: The annotation id as integer + currentSearchNode_id: The search node id as string """ def __init__(self): @@ -727,9 +768,12 @@ def __init__(self): self.parser.add_argument( "annotation_id", type=int, required=False, location="args" ) + self.parser.add_argument( + "currentSearchNode_id", type=int, required=False, location="args" + ) def _get_sketch(self, sketch_id): - """Helper function: Returns Sketch object givin a sketch id. + """Helper function: Returns Sketch object given a sketch id. Args: sketch_id: Integer primary key for a sketch database model @@ -747,13 +791,13 @@ def _get_sketch(self, sketch_id): ) return sketch - def _get_current_search_node(self, current_search_node_id, sketch): - """Helper function: Returns Current Search Node object givin a search + def _get_current_search_node(self, current_search_node_id: str, sketch: Sketch): + """Helper function: Returns Current Search Node object given a search node id Args: - current_search_node_id: search node id - sketch: Sketch object + current_search_node_id: (str) search node id + sketch: (object) Sketch object Returns: Search history object representing the current search node @@ -777,11 +821,11 @@ def _get_current_search_node(self, current_search_node_id, sketch): return current_search_node @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: An annotation in JSON (instance of flask.wrappers.Response) @@ -798,29 +842,28 @@ def post(self, sketch_id): if _search_node_id: current_search_node = self._get_current_search_node(_search_node_id, sketch) + allowed_statuses = ["ready"] + if current_app.config.get("SEARCH_PROCESSING_TIMELINES", False): + allowed_statuses.append("processing") + indices = [ t.searchindex.index_name for t in sketch.timelines - if t.get_status.status.lower() == "ready" + if t.get_status.status.lower() in allowed_statuses ] annotation_type = form.annotation_type.data events = form.events.raw_data for _event in events: searchindex_id = _event["_index"] - - # In case the index is part of an alias index, the alias name is used as searchindex - searchindex_id, searchindex_name = self.datastore.resolve_index_alias( - searchindex_id - ) searchindex = SearchIndex.query.filter_by(index_name=searchindex_id).first() event_id = _event["_id"] if searchindex_id not in indices: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Search index ID ({0!s}) does not belong to the list " - "of indices".format(searchindex_id), + f"Search index ID ({searchindex_id!s}) does not belong to the" + " list of indices", ) # Get or create an event in the SQL database to have something @@ -839,7 +882,7 @@ def post(self, sketch_id): ) event.comments.append(annotation) self.datastore.set_label( - searchindex_name, + searchindex_id, event_id, sketch.id, current_user.id, @@ -859,12 +902,13 @@ def post(self, sketch_id): toggle = False if "__ts_star" in form.annotation.data: toggle = True - + if "__ts_hidden" in form.annotation.data: + toggle = True if form.remove.data: toggle = True self.datastore.set_label( - searchindex_name, + searchindex_id, event_id, sketch.id, current_user.id, @@ -881,7 +925,7 @@ def post(self, sketch_id): abort( HTTP_STATUS_CODE_BAD_REQUEST, "Annotation type needs to be either label or comment, " - "not {0!s}".format(annotation_type), + f"not {annotation_type!s}", ) annotations.append(annotation) @@ -892,12 +936,12 @@ def post(self, sketch_id): return self.to_json(annotations, status_code=HTTP_STATUS_CODE_CREATED) @login_required - def put(self, sketch_id): + def put(self, sketch_id: int): """Handles update request to annotations (currently only comments are supported). Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: The updated annotation object in JSON (instance of @@ -926,17 +970,14 @@ def put(self, sketch_id): # only one event will be in the event list for _event in events: searchindex_id = _event["_index"] - - # In case the index is part of an alias index, the alias name is used as searchindex - searchindex_id, _ = self.datastore.resolve_index_alias(searchindex_id) searchindex = SearchIndex.query.filter_by(index_name=searchindex_id).first() event_id = _event["_id"] if searchindex_id not in indices: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Search index ID ({0!s}) does not belong to the list " - "of indices".format(searchindex_id), + f"Search index ID ({searchindex_id!s}) does not belong to the" + " list of indices", ) # Retrieve the event from the SQL database based on the event_id @@ -948,7 +989,7 @@ def put(self, sketch_id): if not event: abort( HTTP_STATUS_CODE_NOT_FOUND, - "No event found with the id: " "{0!s}".format(event_id), + f"No event found with the id: {event_id!s}", ) # Retrieve annotation type supplied in the request @@ -960,11 +1001,11 @@ def put(self, sketch_id): # Retrieve the comment attached to the event bases on the comment # id supplied in the request comment = event.get_comment(annotation["id"]) + annotation_id = annotation["id"] if not comment: abort( HTTP_STATUS_CODE_NOT_FOUND, - "No comment found with " - "this id: {0!d}.".format(annotation["id"]), + f"No comment found with this id: {annotation_id!s}.", ) # Make sure the current user is the owner of the comment @@ -975,9 +1016,7 @@ def put(self, sketch_id): ) # Update the comment with the new value - annotation = event.update_comment( - annotation["id"], annotation["comment"] - ) + annotation = event.update_comment(annotation_id, annotation["comment"]) if not annotation: abort( @@ -989,41 +1028,37 @@ def put(self, sketch_id): else: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Annotation type needs to be a comment, " - "not {0!s}".format(annotation_type), + f"Annotation type needs to be a comment, not {annotation_type!s}", ) return self.to_json(updated_annotations, status_code=HTTP_STATUS_CODE_OK) @login_required - def delete(self, sketch_id): - """Handles delete request of annotations. + def delete(self, sketch_id: int): + """Handles delete request of annotations (currently only comments are + supported). Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: A HTTP 200 if the annotation was successfully deleted and HTTP 400 otherwise """ - form = forms.EventAnnotationForm.build(request) - if not form.validate_on_submit(): - abort(HTTP_STATUS_CODE_BAD_REQUEST, "Unable to validate form data.") - - annotation = form.annotation.data - annotation_type = form.annotation_type.data - annotation_id = form.annotation_id.data - event_id = form.event_id.data - searchindex_id = form.searchindex_id.data - - # In case the index is part of an alias index, the alias name is used as searchindex - searchindex_id, searchindex_name = self.datastore.resolve_index_alias( - searchindex_id - ) + # Retrieve request arguments + args = self.parser.parse_args() + annotation_type = args.get("annotation_type") + annotation_id = args.get("annotation_id") + event_id = args.get("event_id") + searchindex_id = args.get("searchindex_id") sketch = self._get_sketch(sketch_id) + current_search_node = None + _search_node_id = args.get("currentSearchNode_id") + if _search_node_id: + current_search_node = self._get_current_search_node(_search_node_id, sketch) searchindex = SearchIndex.query.filter_by(index_name=searchindex_id).first() # Retrieve the event from the SQL database based on the event_id @@ -1035,17 +1070,17 @@ def delete(self, sketch_id): if not event: abort( HTTP_STATUS_CODE_NOT_FOUND, - "No event found with the id: " "{0!s}".format(event_id), + f"No event found with the id: {event_id!s}", ) - if annotation_type == "comment": + if "comment" in annotation_type: # Retrieve the comment attached to the event bases on the comment # id supplied in the request comment = event.get_comment(annotation_id) if not comment: abort( HTTP_STATUS_CODE_NOT_FOUND, - "No comment found with " "this id: {0!d}.".format(annotation_id), + f"No comment found with this id: {annotation_id!s}.", ) # Make sure the current user is the owner of the comment @@ -1059,38 +1094,28 @@ def delete(self, sketch_id): # Remove label __ts_comment if the event has no more comments if len(event.comments) < 1: self.datastore.set_label( - searchindex_name, + searchindex_id, event_id, sketch.id, current_user.id, "__ts_comment", toggle=True, ) + if current_search_node: + current_search_node.remove_label("__ts_comment") return HTTP_STATUS_CODE_OK - elif annotation_type == "label": - self.datastore.set_label( - searchindex_name, - event_id, - sketch.id, - current_user.id, - annotation, - remove=True, - toggle=True, + else: + abort( + HTTP_STATUS_CODE_BAD_REQUEST, + f"Annotation type needs to be a comment, not {annotation_type!s}", ) - event.remove_label(annotation) - - db_session.add(event) - db_session.commit() - - return HTTP_STATUS_CODE_OK - return ( HTTP_STATUS_CODE_BAD_REQUEST, "Could not delete the annotation" - " type {0!s} with the id {1!d}".format(annotation_type, annotation_id), + f" type {annotation_type!s} with the id {annotation_id!s}", ) @@ -1098,11 +1123,11 @@ class CountEventsResource(resources.ResourceMixin, Resource): """Resource to number of events for sketch timelines.""" @login_required - def get(self, sketch_id): + def get(self, sketch_id: int): """Handles GET request to the resource. Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: Number of events in JSON (instance of flask.wrappers.Response) @@ -1121,8 +1146,8 @@ def get(self, sketch_id): if t.get_status.status != "archived" ] count, bytes_on_disk = self.datastore.count(indices) - meta = dict(count=count, bytes=bytes_on_disk) - schema = dict(meta=meta, objects=[]) + meta = {"count": count, "bytes": bytes_on_disk} + schema = {"meta": meta, "objects": []} return jsonify(schema) @@ -1130,12 +1155,12 @@ class MarkEventsWithTimelineIdentifier(resources.ResourceMixin, Resource): """Resource to add a Timeline identifier to events within an index.""" @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Handler for /api/v1/sketches/:sketch_id/event/create/ Args: - sketch_id: Integer primary key for a sketch database model + sketch_id: (int) Integer primary key for a sketch database model Returns: An annotation in JSON (instance of flask.wrappers.Response) @@ -1201,8 +1226,8 @@ def post(self, sketch_id): if timeline.sketch.id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "The sketch ID ({0:d}) does not match with the timeline " - "sketch ID ({1:d})".format(sketch.id, timeline.sketch.id), + f"The sketch ID ({sketch.id:d}) does not match with the timeline " + f"sketch ID ({timeline.sketch.id:d})", ) query_dsl = { @@ -1223,7 +1248,7 @@ def post(self, sketch_id): } }, } - + # pylint: disable=unexpected-keyword-arg self.datastore.client.update_by_query( body=query_dsl, index=searchindex.index_name, @@ -1261,13 +1286,13 @@ class EventUnTagResource(resources.ResourceMixin, Resource): MAX_TAGS_PER_REQUEST = 500 @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """ Remove tags (max 500) from a list of events (max 500). Args: - sketch_id: Integer primary key for a sketch database model - in request form: + sketch_id: (int) Integer primary key for a sketch database model + in request form: events: list of events to remove tags from with the following values: _id: the event id (e.g. k8P1MYcBkeTGnypeeKJL) _index: the searchindex name @@ -1310,8 +1335,8 @@ def post(self, sketch_id): if len(events) > self.MAX_EVENTS_TO_TAG: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Cannot untag more than {0:d} events in a single " - "request".format(self.MAX_EVENTS_TO_TAG), + f"Cannot untag more than {self.MAX_EVENTS_TO_TAG:d} events in a " + "single request", ) tags_to_remove = form.get("tags_to_remove", []) @@ -1321,8 +1346,8 @@ def post(self, sketch_id): if len(tags_to_remove) > self.MAX_TAGS_PER_REQUEST: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Cannot untag more than {0:d} tags in a single " - "request".format(self.MAX_TAGS_PER_REQUEST), + f"Cannot untag more than {self.MAX_TAGS_PER_REQUEST:d} tags in a " + "single request", ) datastore = self.datastore @@ -1341,15 +1366,12 @@ def post(self, sketch_id): searchindex = None # in both cases we are flexible, no matter what was supplied if searchindex_name: - # In case the index is part of an alias index, the alias name is used as searchindex - searchindex_id, searchindex_name = self.datastore.resolve_index_alias( - searchindex_name - ) searchindex = SearchIndex.query.filter_by( - index_name=searchindex_id + index_name=searchindex_name ).first() elif searchindex_id: searchindex = SearchIndex.get_by_id(searchindex_id) + if not searchindex: abort( HTTP_STATUS_CODE_BAD_REQUEST, @@ -1362,7 +1384,7 @@ def post(self, sketch_id): "Unable to query event on a closed search index.", ) - result = self.datastore.get_event(searchindex_name, _event.get("_id")) + result = self.datastore.get_event(searchindex.index_name, _event.get("_id")) if not result: logger.debug( "Unable to find event %s in index %s to untag", @@ -1379,7 +1401,7 @@ def post(self, sketch_id): # write the new tags to the datastore datastore.import_event( - index_name=searchindex_name, + index_name=searchindex.index_name, event_id=_event.get("_id"), event={"tag": new_tags}, flush_interval=datastore.DEFAULT_FLUSH_INTERVAL, diff --git a/timesketch/api/v1/resources/explore.py b/timesketch/api/v1/resources/explore.py index fa4d6935ab..0c198fff69 100644 --- a/timesketch/api/v1/resources/explore.py +++ b/timesketch/api/v1/resources/explore.py @@ -19,29 +19,35 @@ import zipfile import prometheus_client -from flask import abort, jsonify, request, send_file -from flask_login import current_user, login_required -from flask_restful import Resource, reqparse - -from timesketch.api.v1 import export, resources -from timesketch.lib import forms, utils -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, - METRICS_NAMESPACE, -) + +from flask import abort +from flask import jsonify +from flask import current_app +from flask import request +from flask import send_file +from flask_restful import Resource +from flask_restful import reqparse +from flask_login import login_required +from flask_login import current_user + +from timesketch.api.v1 import export +from timesketch.api.v1 import resources +from timesketch.lib import forms +from timesketch.lib import utils from timesketch.lib.utils import get_validated_indices +from timesketch.lib.definitions import DEFAULT_SOURCE_FIELDS +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND +from timesketch.lib.definitions import METRICS_NAMESPACE from timesketch.models import db_session -from timesketch.models.sketch import ( - Event, - Facet, - InvestigativeQuestion, - Scenario, - SearchHistory, - Sketch, - View, -) +from timesketch.models.sketch import Event +from timesketch.models.sketch import Sketch +from timesketch.models.sketch import View +from timesketch.models.sketch import SearchHistory +from timesketch.models.sketch import Scenario +from timesketch.models.sketch import Facet +from timesketch.models.sketch import InvestigativeQuestion # Metrics definitions METRICS = { @@ -58,7 +64,7 @@ class ExploreResource(resources.ResourceMixin, Resource): """Resource to search the datastore based on a query and a filter.""" @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Handler for /api/v1/sketches/:sketch_id/explore/ @@ -138,19 +144,35 @@ def post(self, sketch_id): parent = request.json.get("parent", None) incognito = request.json.get("incognito", False) + include_processing_timelines = False + if current_app.config.get("SEARCH_PROCESSING_TIMELINES", False): + include_processing_timelines = request.json.get( + "include_processing_timelines", False + ) + + return_field_string = form.fields.data + if return_field_string: + return_fields = [x.strip() for x in return_field_string.split(",")] + else: + return_fields = query_filter.get("fields", []) + return_fields = [field["field"] for field in return_fields] + return_fields.extend(DEFAULT_SOURCE_FIELDS) + if not query_filter: query_filter = {} - all_indices = list({t.searchindex.index_name for t in sketch.timelines}) - indices = query_filter.get("indices", all_indices) + all_timeline_ids = [t.id for t in sketch.timelines] + indices = query_filter.get("indices", all_timeline_ids) # If _all in indices then execute the query on all indices if "_all" in indices: - indices = all_indices + indices = all_timeline_ids # Make sure that the indices in the filter are part of the sketch. # This will also remove any deleted timeline from the search result. - indices, timeline_ids = get_validated_indices(indices, sketch) + indices, timeline_ids = get_validated_indices( + indices, sketch, include_processing_timelines + ) # Remove indices that don't exist from search. indices = utils.validate_indices(indices, self.datastore) @@ -230,6 +252,7 @@ def post(self, sketch_id): "query": form.query.data, "query_dsl": query_dsl, "query_filter": query_filter, + "return_fields": return_fields, } with zipfile.ZipFile(file_object, mode="w") as zip_file: zip_file.writestr("METADATA", data=json.dumps(form_data)) @@ -240,6 +263,7 @@ def post(self, sketch_id): indices=indices, sketch=sketch, datastore=self.datastore, + return_fields=return_fields, timeline_ids=timeline_ids, ) fh.seek(0) @@ -248,7 +272,7 @@ def post(self, sketch_id): return send_file(file_object, mimetype="zip", download_name=file_name) if scroll_id: - + # pylint: disable=unexpected-keyword-arg result = self.datastore.client.scroll(scroll_id=scroll_id, scroll="1m") else: try: @@ -259,6 +283,7 @@ def post(self, sketch_id): query_dsl=query_dsl, indices=indices, aggregations=index_stats_agg, + return_fields=return_fields, enable_scroll=enable_scroll, timeline_ids=timeline_ids, ) @@ -300,17 +325,16 @@ def post(self, sketch_id): except KeyError: pass - # Total count for query that matches the timelines - # Documents that match the query but are not part of a timeline - # are not counted - count_total_complete = sum(count_per_timeline.values()) + # Total count for query regardless of returned results. + count_total_complete = sum(count_per_index.values()) comments = {} - events = Event.get_with_comments(sketch=sketch) - for event in events: - for comment in event.comments: - comments.setdefault(event.document_id, []) - comments[event.document_id].append(comment.comment) + if "comment" in return_fields: + events = Event.get_with_comments(sketch=sketch) + for event in events: + for comment in event.comments: + comments.setdefault(event.document_id, []) + comments[event.document_id].append(comment.comment) # Get labels for each event that matches the sketch. # Remove all other labels. @@ -326,7 +350,8 @@ def post(self, sketch_id): except KeyError: pass - event["_source"]["comment"] = comments.get(event["_id"], []) + if "comment" in return_fields: + event["_source"]["comment"] = comments.get(event["_id"], []) # Update or create user state view. This is used in the UI to let # the user get back to the last state in the explore view. @@ -420,12 +445,12 @@ def post(self, sketch_id): "search_node": search_node, } - # Support OpenSearch + # Elasticsearch version 7.x returns total hits as a dictionary. + # TODO: Refactor when version 6.x has been deprecated. if isinstance(meta["es_total_count"], dict): meta["es_total_count"] = meta["es_total_count"].get("value", 0) schema = {"meta": meta, "objects": result["hits"]["hits"]} - return jsonify(schema) @@ -433,7 +458,7 @@ class QueryResource(resources.ResourceMixin, Resource): """Resource to get a query.""" @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles GET request to the resource. Args: diff --git a/timesketch/api/v1/resources/graph.py b/timesketch/api/v1/resources/graph.py index 33fb32106f..167a2521ef 100644 --- a/timesketch/api/v1/resources/graph.py +++ b/timesketch/api/v1/resources/graph.py @@ -115,7 +115,7 @@ def __init__(self): self.parser.add_argument("format", type=str, required=False, location="args") @login_required - def get(self, sketch_id, graph_id): + def get(self, sketch_id: int, graph_id: int): """Handles GET request to the resource. Returns: @@ -165,7 +165,7 @@ def get(self, sketch_id, graph_id): return jsonify(response) @login_required - def post(self, sketch_id, graph_id): + def post(self, sketch_id: int, graph_id: int): """Handles GET request to the resource. Returns: @@ -223,7 +223,7 @@ def post(self, sketch_id, graph_id): return self.to_json(graph, status_code=HTTP_STATUS_CODE_CREATED) @login_required - def delete(self, sketch_id, graph_id): + def delete(self, sketch_id: int, graph_id: int): """Handles DELETE request to the resource. Args: @@ -313,7 +313,7 @@ def post(self, sketch_id): "Timeline IDs if supplied need to be a list.", ) - if timeline_ids and not all([isinstance(x, int) for x in timeline_ids]): + if timeline_ids and not all(isinstance(x, int) for x in timeline_ids): abort( HTTP_STATUS_CODE_BAD_REQUEST, "Timeline IDs needs to be a list of integers.", diff --git a/timesketch/api/v1/resources/llm.py b/timesketch/api/v1/resources/llm.py new file mode 100644 index 0000000000..e776502aeb --- /dev/null +++ b/timesketch/api/v1/resources/llm.py @@ -0,0 +1,357 @@ +# Copyright 2025 Google Inc. All rights reserved. +# +# 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. +"""Timesketch API endpoint for interacting with LLM features.""" +import logging +import multiprocessing +import multiprocessing.managers +import time +import prometheus_client +from flask import request, abort, jsonify, Response +from flask_login import login_required, current_user +from flask_restful import Resource +from timesketch.api.v1 import resources +from timesketch.lib import definitions, utils +from timesketch.lib.definitions import METRICS_NAMESPACE +from timesketch.lib.llms.providers import manager as llm_manager +from timesketch.lib.llms.features import manager as feature_manager +from timesketch.models.sketch import Sketch + +logger = logging.getLogger("timesketch.api.llm") + + +class LLMResource(resources.ResourceMixin, Resource): + """Resource to interact with LLMs. + + This class provides an API endpoint for accessing and utilizing Large Language + Model features within Timesketch. It handles request validation, processing, + and response handling, while also monitoring performance metrics. + """ + + METRICS = { + "llm_requests_total": prometheus_client.Counter( + "llm_requests_total", + "Total number of LLM requests received", + ["sketch_id", "feature"], + namespace=METRICS_NAMESPACE, + ), + "llm_errors_total": prometheus_client.Counter( + "llm_errors_total", + "Total number of errors during LLM processing", + ["sketch_id", "feature", "error_type"], + namespace=METRICS_NAMESPACE, + ), + "llm_duration_seconds": prometheus_client.Summary( + "llm_duration_seconds", + "Time taken to process an LLM request (in seconds)", + ["sketch_id", "feature"], + namespace=METRICS_NAMESPACE, + ), + } + # TODO(itsmvd): Make this configurable + _LLM_TIMEOUT_WAIT_SECONDS = 30 + + @login_required + def post(self, sketch_id: int) -> Response: + """Handles POST requests to the resource. + + Processes LLM requests, validates inputs, generates prompts, + executes LLM calls, and returns the processed results. + + Args: + sketch_id: The ID of the sketch to process. + + Returns: + A Flask JSON response containing the processed LLM result. + + Raises: + HTTP exceptions for various error conditions. + """ + start_time = time.time() + sketch = self._validate_sketch(sketch_id) + form = self._validate_request_data() + feature = self._get_feature(form.get("feature")) + self._increment_request_metric(sketch_id, feature.NAME) + timeline_ids = self._validate_indices(sketch, form.get("filter", {})) + prompt = self._generate_prompt(feature, sketch, form, timeline_ids) + response = self._execute_llm_call(feature, prompt, sketch_id) + result = self._process_llm_response( + feature, response, sketch, form, timeline_ids + ) + self._record_duration(sketch_id, feature.NAME, start_time) + return jsonify(result) + + def _validate_sketch(self, sketch_id: int) -> Sketch: + """Validates sketch existence and user permissions. + + Args: + sketch_id: The ID of the sketch to validate. + + Returns: + The validated Sketch object. + + Raises: + HTTP 404: If the sketch doesn't exist. + HTTP 403: If the user doesn't have read access to the sketch. + """ + sketch = Sketch.get_with_acl(sketch_id) + if not sketch: + abort( + definitions.HTTP_STATUS_CODE_NOT_FOUND, "No sketch found with this ID." + ) + if not sketch.has_permission(current_user, "read"): + abort( + definitions.HTTP_STATUS_CODE_FORBIDDEN, + "User does not have read access to the sketch.", + ) + return sketch + + def _validate_request_data(self) -> dict: + """Validates the presence of request JSON data. + + Returns: + The validated request data as a dictionary. + + Raises: + HTTP 400: If no JSON data is provided in the request. + """ + form = request.json + if not form: + abort( + definitions.HTTP_STATUS_CODE_BAD_REQUEST, + "The POST request requires data", + ) + return form + + def _get_feature(self, feature_name: str) -> feature_manager.LLMFeatureInterface: + """Retrieves and validates the requested LLM feature. + + Args: + feature_name: The name of the LLM feature to retrieve. + + Returns: + An instance of the requested LLM feature. + + Raises: + HTTP 400: If feature_name is not provided or is invalid. + """ + if not feature_name: + abort( + definitions.HTTP_STATUS_CODE_BAD_REQUEST, + "The 'feature' parameter is required.", + ) + try: + return feature_manager.FeatureManager.get_feature_instance(feature_name) + except KeyError: + abort( + definitions.HTTP_STATUS_CODE_BAD_REQUEST, + f"Invalid LLM feature: {feature_name}", + ) + + def _validate_indices(self, sketch: Sketch, query_filter: dict) -> list: + """Extracts and validates timeline IDs from the query filter for a sketch. + + Args: + sketch: The Sketch object to validate indices for. + query_filter: A dictionary containing filter parameters. + + Returns: + A list of validated timeline IDs. + + Raises: + HTTP 400: If no valid search indices are found. + """ + all_indices = list({t.searchindex.index_name for t in sketch.timelines}) + indices = query_filter.get("indices", all_indices) + if "_all" in indices: + indices = all_indices + indices, timeline_ids = utils.get_validated_indices(indices, sketch) + if not indices: + abort( + definitions.HTTP_STATUS_CODE_BAD_REQUEST, + "No valid search indices were found.", + ) + return timeline_ids + + def _generate_prompt( + self, + feature: feature_manager.LLMFeatureInterface, + sketch: Sketch, + form: dict, + timeline_ids: list, + ) -> str: + """Generates the LLM prompt based on the feature and request data. + + Args: + feature: The LLM feature instance to use. + sketch: The Sketch object. + form: The request form data. + timeline_ids: A list of validated timeline IDs. + + Returns: + The generated prompt string for the LLM. + + Raises: + HTTP 400: If prompt generation fails. + """ + try: + return feature.generate_prompt( + sketch, form=form, datastore=self.datastore, timeline_ids=timeline_ids + ) + except ValueError as e: + abort(definitions.HTTP_STATUS_CODE_BAD_REQUEST, str(e)) + + def _execute_llm_call( + self, feature: feature_manager.LLMFeatureInterface, prompt: str, sketch_id: int + ) -> dict: + """Executes the LLM call with a timeout using multiprocessing. + + Args: + feature: The LLM feature instance to use. + prompt: The generated prompt to send to the LLM. + sketch_id: The ID of the sketch being processed. + + Returns: + The LLM response as a dictionary. + + Raises: + HTTP 400: If the LLM call times out. + HTTP 500: If an error occurs during LLM processing. + """ + with multiprocessing.Manager() as manager: + shared_response = manager.dict() + process = multiprocessing.Process( + target=self._get_content_with_timeout, + args=(feature, prompt, shared_response), + ) + process.start() + process.join(timeout=self._LLM_TIMEOUT_WAIT_SECONDS) + if process.is_alive(): + logger.warning( + "LLM call timed out after %d seconds.", + self._LLM_TIMEOUT_WAIT_SECONDS, + ) + process.terminate() + process.join() + self.METRICS["llm_errors_total"].labels( + sketch_id=str(sketch_id), feature=feature.NAME, error_type="timeout" + ).inc() + abort( + definitions.HTTP_STATUS_CODE_BAD_REQUEST, + "LLM call timed out, please try again. " + "If this issue persists, contact your administrator.", + ) + response = dict(shared_response) + if "error" in response: + self.METRICS["llm_errors_total"].labels( + sketch_id=str(sketch_id), + feature=feature.NAME, + error_type="llm_api_error", + ).inc() + abort( + definitions.HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, + f"Error during LLM processing: {response['error']}", + ) + return response["response"] + + def _process_llm_response( + self, + feature: feature_manager.LLMFeatureInterface, + response: dict, + sketch: Sketch, + form: dict, + timeline_ids: list, + ) -> dict: + """Processes the LLM response into the final result. + + Args: + feature: The LLM feature instance used. + response: The raw LLM response. + sketch: The Sketch object. + form: The request form data. + timeline_ids: A list of validated timeline IDs. + + Returns: + The processed LLM response as a dictionary. + + Raises: + HTTP 400: If response processing fails. + """ + try: + return feature.process_response( + llm_response=response, + form=form, + sketch_id=sketch.id, + datastore=self.datastore, + sketch=sketch, + timeline_ids=timeline_ids, + ) + except ValueError as e: + self.METRICS["llm_errors_total"].labels( + sketch_id=str(sketch.id), + feature=feature.NAME, + error_type="response_processing", + ).inc() + abort(definitions.HTTP_STATUS_CODE_BAD_REQUEST, str(e)) + + def _increment_request_metric(self, sketch_id: int, feature_name: str) -> None: + """Increments the request counter metric. + + Args: + sketch_id: The ID of the sketch being processed. + feature_name: The name of the LLM feature being used. + """ + self.METRICS["llm_requests_total"].labels( + sketch_id=str(sketch_id), feature=feature_name + ).inc() + + def _record_duration( + self, sketch_id: int, feature_name: str, start_time: float + ) -> None: + """Records the duration of the request. + + Args: + sketch_id: The ID of the sketch being processed. + feature_name: The name of the LLM feature being used. + start_time: The timestamp when the request started. + """ + duration = time.time() - start_time + self.METRICS["llm_duration_seconds"].labels( + sketch_id=str(sketch_id), feature=feature_name + ).observe(duration) + + def _get_content_with_timeout( + self, + feature: feature_manager.LLMFeatureInterface, + prompt: str, + shared_response: multiprocessing.managers.DictProxy, + ) -> None: + """Send a prompt to the LLM and get a response within a process. + + This method is executed in a separate process to allow for timeout control. + + Args: + feature: The LLM feature instance to use. + prompt: The generated prompt to send to the LLM. + shared_response: A managed dictionary to store the response or error. + """ + try: + llm = llm_manager.LLMManager.create_provider(feature_name=feature.NAME) + response_schema = ( + feature.RESPONSE_SCHEMA if hasattr(feature, "RESPONSE_SCHEMA") else None + ) + response = llm.generate(prompt, response_schema=response_schema) + shared_response.update({"response": response}) + except Exception as e: # pylint: disable=broad-except + logger.error("Error in LLM call within process: %s", e, exc_info=True) + shared_response.update({"error": str(e)}) diff --git a/timesketch/api/v1/resources/scenarios.py b/timesketch/api/v1/resources/scenarios.py index 04846a593c..a69402adce 100644 --- a/timesketch/api/v1/resources/scenarios.py +++ b/timesketch/api/v1/resources/scenarios.py @@ -15,6 +15,7 @@ import logging import json +from typing import Optional from flask import jsonify from flask import request @@ -51,7 +52,7 @@ def load_dfiq_from_config(): """ dfiq_path = current_app.config.get("DFIQ_PATH") if not current_app.config.get("DFIQ_ENABLED"): - logger.info("DFIQ is disabled. Enable in the timesketch.conf!") + logger.debug("DFIQ is disabled. Enable in the timesketch.conf!") return None if not dfiq_path: logger.error("No DFIQ_PATH configured") @@ -59,7 +60,11 @@ def load_dfiq_from_config(): return DFIQ(dfiq_path) -def check_and_run_dfiq_analysis_steps(dfiq_obj, sketch, analyzer_manager=None): +def check_and_run_dfiq_analysis_steps( + dfiq_obj: object, + sketch: Sketch, + analyzer_manager: Optional[DFIQAnalyzerManager] = None, +): """Checks if any DFIQ analyzers need to be executed for the given DFIQ object. Args: @@ -307,7 +312,7 @@ def post(self, sketch_id): db_session.add(scenario_sql) db_session.commit() - # This does not work, since we don't have Scnearios linked down to + # This does not work, since we don't have Scenarios linked down to # Approaches anymore! We intentionally broke the link to facets to show # Questions in the frontend. # check_and_run_dfiq_analysis_steps(scenario_sql, sketch) diff --git a/timesketch/api/v1/resources/searchindex.py b/timesketch/api/v1/resources/searchindex.py index 3225674719..826029c22e 100644 --- a/timesketch/api/v1/resources/searchindex.py +++ b/timesketch/api/v1/resources/searchindex.py @@ -15,21 +15,23 @@ import logging import opensearchpy -from flask import abort, request -from flask_login import current_user, login_required +from flask import request +from flask import abort from flask_restful import Resource +from flask_login import login_required +from flask_login import current_user from timesketch.api.v1 import resources from timesketch.lib import forms -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND from timesketch.models import db_session -from timesketch.models.sketch import SearchIndex, Timeline +from timesketch.models.sketch import SearchIndex +from timesketch.models.sketch import Timeline + logger = logging.getLogger("timesketch.index_api") @@ -110,26 +112,17 @@ def get(self, searchindex_id): try: mapping = self.datastore.client.indices.get_mapping(searchindex.index_name) except opensearchpy.NotFoundError: - logger.error("Unable to find index: {0:s}".format(searchindex.index_name)) + logger.error("Unable to find index: %s", searchindex.index_name) mapping = {} searchindex.set_status("fail") db_session.commit() - # In case the index is an alias, the mapping of the first index is returned - if self.datastore.client.indices.exists_alias(searchindex.index_name): - fields = list( - mapping.get(next(iter(mapping)), {}) - .get("mappings", {}) - .get("properties", {}) - .keys() - ) - else: - fields = list( - mapping.get(searchindex.index_name, {}) - .get("mappings", {}) - .get("properties", {}) - .keys() - ) + fields = list( + mapping.get(searchindex.index_name, {}) + .get("mappings", {}) + .get("properties", {}) + .keys() + ) meta = { "contains_timeline_id": bool("__ts_timeline_id" in fields), @@ -217,7 +210,7 @@ def delete(self, searchindex_id): if sketches: error_strings = ["WARNING: This timeline is in use by:"] for sketch in sketches: - error_strings.append(" * {0:s}".format(sketch.name)) + error_strings.append(f" * {sketch.id:d}") abort(HTTP_STATUS_CODE_FORBIDDEN, "\n".join(error_strings)) searchindex.set_status(status="deleted") @@ -229,7 +222,7 @@ def delete(self, searchindex_id): ).all() if len(other_indexes) > 1: logger.warning( - "Search index: {0:s} belongs to more than one " + "Search index: {:s} belongs to more than one " "db entry.".format(searchindex.index_name) ) return HTTP_STATUS_CODE_OK @@ -238,7 +231,7 @@ def delete(self, searchindex_id): self.datastore.client.indices.close(index=searchindex.index_name) except opensearchpy.NotFoundError: logger.warning( - "Unable to close index: {0:s}, the index wasn't " + "Unable to close index: {:s}, the index wasn't " "found.".format(searchindex.index_name) ) diff --git a/timesketch/api/v1/resources/searchtemplate.py b/timesketch/api/v1/resources/searchtemplate.py index ea7b7140a6..4e86b4b89c 100644 --- a/timesketch/api/v1/resources/searchtemplate.py +++ b/timesketch/api/v1/resources/searchtemplate.py @@ -84,7 +84,7 @@ class SearchTemplateParseResource(resources.ResourceMixin, Resource): """Resource to parse a search template query string using Jinja2 template.""" @login_required - def post(self, searchtemplate_id): + def post(self, searchtemplate_id: int): """Parse the query string template with Jinja2. This resource take a form with parameters to be parsed with the Jinja2 @@ -95,7 +95,7 @@ def post(self, searchtemplate_id): } Args: - searchtemplate_id: Primary key for a search template database model + searchtemplate_id: (int) Primary key for a search template database model Returns: Parsed and sanitized search query string. @@ -164,7 +164,7 @@ def post(self): if not search_id: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Unable to save the searchtemplate, the saved search ID is " "missing.", + "Unable to save the searchtemplate, the saved search ID is missing.", ) search_obj = View.get_by_id(search_id) diff --git a/timesketch/api/v1/resources/session.py b/timesketch/api/v1/resources/session.py index 372eab1cd2..11f7b5807c 100644 --- a/timesketch/api/v1/resources/session.py +++ b/timesketch/api/v1/resources/session.py @@ -14,14 +14,13 @@ """Session resources for version 1 of the Timesketch API.""" from flask import abort -from flask_login import current_user, login_required from flask_restful import Resource +from flask_login import login_required +from flask_login import current_user from timesketch.api.v1 import resources -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, -) +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND from timesketch.models.sketch import Sketch @@ -85,8 +84,8 @@ def get(self, sketch_id, timeline_index): ts_query_string = ts_filter["bool"]["must"][0]["query_string"] for session_type in session_types: - id_terms["field"] = "session_id.{}.keyword".format(session_type) - + id_terms["field"] = f"session_id.{session_type}.keyword" + # pylint: disable=unexpected-keyword-arg id_agg = self.datastore.client.search( index=list(sketch_indices), body=id_agg_spec, size=0 ) diff --git a/timesketch/api/v1/resources/settings.py b/timesketch/api/v1/resources/settings.py index 39ec97e916..3050b324ce 100644 --- a/timesketch/api/v1/resources/settings.py +++ b/timesketch/api/v1/resources/settings.py @@ -12,11 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. """System settings.""" - import logging +from typing import Any + from flask import current_app, jsonify from flask_restful import Resource from flask_login import login_required +from timesketch.lib.llms.providers import manager as llm_manager logger = logging.getLogger("timesketch.system_settings") @@ -31,35 +33,89 @@ def get(self): Returns: JSON object with system settings. """ - # Settings from timesketch.conf to expose to the frontend clients. - settings_to_return = ["DFIQ_ENABLED"] - result = {} - - for setting in settings_to_return: - result[setting] = current_app.config.get(setting) - - # Derive the default LLM provider from the new configuration. - # Expecting the "default" config to be a dict with exactly one key: - # the provider name. - llm_configs = current_app.config.get("LLM_PROVIDER_CONFIGS", {}) - default_provider = None - default_conf = llm_configs.get("default") - if default_conf and isinstance(default_conf, dict) and len(default_conf) == 1: - default_provider = next(iter(default_conf)) - result["LLM_PROVIDER"] = default_provider - - # TODO(mvd): Remove by 2025/06/01 once all users have updated their config. - old_llm_provider = current_app.config.get("LLM_PROVIDER") + result = { + "DFIQ_ENABLED": current_app.config.get("DFIQ_ENABLED", False), + "SEARCH_PROCESSING_TIMELINES": current_app.config.get( + "SEARCH_PROCESSING_TIMELINES", False + ), + "LLM_FEATURES_AVAILABLE": self._get_llm_features_availability( + current_app.config.get("LLM_PROVIDER_CONFIGS", {}) + ), + } + + return jsonify(result) + + def _get_llm_features_availability( + self, llm_configs: dict[str, Any] + ) -> dict[str, bool]: + """Get availability status for all LLM features. + + Args: + llm_configs: LLM provider configuration dictionary + + Returns: + dict mapping feature names to availability status (bool) + """ + default_provider_working = False + + if not isinstance(llm_configs, dict): + logger.debug( + "LLM_PROVIDER_CONFIGS is not a dictionary: %s", + type(llm_configs).__name__, + ) + return {"default": default_provider_working} + if ( - old_llm_provider and "default" not in llm_configs - ): # Basic check for old config - warning_message = ( - "Your LLM configuration in timesketch.conf is outdated and may cause " - "issues with LLM features. " - "Please update your LLM_PROVIDER_CONFIGS section to the new format. " - "Refer to the documentation for the updated configuration structure." + "default" in llm_configs + and isinstance(llm_configs["default"], dict) + and len(llm_configs["default"]) == 1 + ): + default_provider = next(iter(llm_configs["default"])) + default_provider_config = llm_configs["default"][default_provider] + default_provider_working = self._check_provider_working( + default_provider, default_provider_config ) - result["llm_config_warning"] = warning_message - logger.warning(warning_message) - return jsonify(result) + llm_feature_availability = {"default": default_provider_working} + + for feature_name, feature_conf in llm_configs.items(): + if feature_name == "default": + continue + + feature_provider_working = False + if isinstance(feature_conf, dict) and len(feature_conf) == 1: + feature_provider = next(iter(feature_conf)) + feature_provider_config = feature_conf[feature_provider] + feature_provider_working = self._check_provider_working( + feature_provider, feature_provider_config + ) + + # Feature is available if either specific provider works + # or default provider works + llm_feature_availability[feature_name] = ( + feature_provider_working or default_provider_working + ) + + return llm_feature_availability + + def _check_provider_working(self, provider_name: str, config: dict) -> bool: + """Check if a specific LLM provider works with given configuration. + + Args: + provider_name: Name of the provider to check + config: Configuration dict for the provider + + Returns: + bool: Whether the provider is working + """ + try: + provider_class = llm_manager.LLMManager.get_provider(provider_name) + provider_class(config=config) + return True + except Exception as e: # pylint: disable=broad-except + logger.debug( + "LLM provider '%s' failed to initialize: %s", + provider_name, + str(e), + ) + return False diff --git a/timesketch/api/v1/resources/sigma.py b/timesketch/api/v1/resources/sigma.py index 26ed1331b2..aad1b39628 100644 --- a/timesketch/api/v1/resources/sigma.py +++ b/timesketch/api/v1/resources/sigma.py @@ -14,27 +14,34 @@ """Sigma resources for version 1 of the Timesketch API.""" import logging - import yaml -from flask import abort, jsonify, request -from flask_login import current_user, login_required + +from flask import abort +from flask import jsonify +from flask import request from flask_restful import Resource +from flask_login import login_required +from flask_login import current_user + from sigma.parser import exceptions as sigma_exceptions + from sqlalchemy.exc import IntegrityError import timesketch.lib.sigma_util as ts_sigma_lib + from timesketch.api.v1 import resources -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CONFLICT, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) -from timesketch.models import db_session + +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_CONFLICT +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK +from timesketch.lib.definitions import HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN + from timesketch.models.sigma import SigmaRule +from timesketch.models import db_session + logger = logging.getLogger("timesketch.api.sigma") @@ -97,7 +104,7 @@ def post(self): try: parsed_rule = ts_sigma_lib.parse_sigma_rule_by_text(rule_yaml) except ValueError as e: - error_msg = "Sigma Rule Parsing error: {0!s}".format(e) + error_msg = f"Sigma Rule Parsing error: {e!s}" logger.debug(error_msg) return abort( HTTP_STATUS_CODE_BAD_REQUEST, @@ -109,7 +116,7 @@ def post(self): # Query rules to see if it already exist and exit if found sigma_rule_from_db = SigmaRule.query.filter_by(rule_uuid=rule_uuid).first() if sigma_rule_from_db: - error_msg = "Rule {0!s} was already found in the database".format(rule_uuid) + error_msg = f"Rule {rule_uuid!s} was already found in the database" logger.debug(error_msg) abort(HTTP_STATUS_CODE_FORBIDDEN, error_msg) @@ -130,7 +137,7 @@ def post(self): db_session.add(sigma_rule) db_session.commit() except IntegrityError as e: - error_msg = "Error adding Sigma rule {0!s}".format(e) + error_msg = f"Error adding Sigma rule {e!s}" logger.error(error_msg) abort( HTTP_STATUS_CODE_CONFLICT, @@ -144,7 +151,7 @@ class SigmaRuleResource(resources.ResourceMixin, Resource): """Resource to read / delete / create / update a Sigma rule.""" @login_required - def get(self, rule_uuid): + def get(self, rule_uuid: str): """Fetches a single Sigma rule from the database. Fetches a single Sigma rule selected by the `UUID` in @@ -152,7 +159,7 @@ def get(self, rule_uuid): rule. Args: - rule_uuid: UUID of the rule. + rule_uuid: (str) UUID of the rule. Returns: JSON sigma rule representation @@ -161,8 +168,8 @@ def get(self, rule_uuid): try: rule = SigmaRule.query.filter_by(rule_uuid=rule_uuid).first() - except Exception as e: - error_msg = "Unable to get the Sigma rule {0!s}".format(e) + except Exception as e: # pylint: disable=broad-except + error_msg = f"Unable to get the Sigma rule {e!s}" logger.error( error_msg, exc_info=True, @@ -183,14 +190,14 @@ def get(self, rule_uuid): return jsonify({"objects": return_rule, "meta": {}}) @login_required - def delete(self, rule_uuid): + def delete(self, rule_uuid: str): """Deletes a Sigma rule from the database. Deletes a single Sigma rule selected by the `uuid` in `/sigmarule//`. Args: - rule_uuid: UUID of the rule to be deleted. + rule_uuid: (str) UUID of the rule to be deleted. Returns: HTTP_STATUS_CODE_NOT_FOUND if rule not found. @@ -199,7 +206,7 @@ def delete(self, rule_uuid): rule = SigmaRule.query.filter_by(rule_uuid=rule_uuid).first() if not rule: - error_msg = "No rule found with rule_uuid.{0!s}".format(rule_uuid) + error_msg = f"No rule found with rule_uuid.{rule_uuid!s}" logger.debug(error_msg) # only needed in debug cases abort( HTTP_STATUS_CODE_NOT_FOUND, @@ -212,7 +219,7 @@ def delete(self, rule_uuid): return HTTP_STATUS_CODE_OK @login_required - def put(self, rule_uuid): + def put(self, rule_uuid: str): """Update an existing Sigma rule in the database. Handles calls to `/sigmarule//`, where @@ -226,7 +233,7 @@ def put(self, rule_uuid): If `rule_uuid` doesn't match the UUI in `rule_yaml`, the request will fail. Args: - rule_uuid: UUID of the rule. + rule_uuid: (str) UUID of the rule. Returns: The updated Sigma object in JSON. @@ -236,26 +243,25 @@ def put(self, rule_uuid): if not rule_yaml: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Error parsing Sigma rule {0!s}: no YAML provided".format(rule_uuid), + f"Error parsing Sigma rule {rule_uuid!s}: no YAML provided", ) try: parsed_rule = ts_sigma_lib.parse_sigma_rule_by_text(rule_yaml) except ValueError as e: - error_msg = "Error parsing Sigma rule {0!s}: {1!s}".format(rule_uuid, e) + error_msg = f"Error parsing Sigma rule {rule_uuid!s}: {e!s}" abort(HTTP_STATUS_CODE_BAD_REQUEST, error_msg) if rule_uuid != parsed_rule.get("id"): abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Rule ID mismatch parameter:{0!s} and YAML content:{1!s}".format( - rule_uuid, parsed_rule.get("id") - ), + f"Rule ID mismatch parameter: {rule_uuid!s} and YAML content: " + f"{parsed_rule.get('id')!s}", ) sigma_rule_from_db = SigmaRule.query.filter_by(rule_uuid=rule_uuid).first() if not sigma_rule_from_db: - error_msg = "Sigma rule with UUID: {0!s} not found".format(rule_uuid) + error_msg = f"Sigma rule with UUID: {rule_uuid!s} not found" logger.error(error_msg) abort(HTTP_STATUS_CODE_NOT_FOUND, error_msg) @@ -268,7 +274,7 @@ def put(self, rule_uuid): db_session.add(sigma_rule_from_db) db_session.commit() except IntegrityError as e: - error_msg = "Error adding Sigma rule {0!s}".format(e) + error_msg = f"Error adding Sigma rule {e!s}" logger.error(error_msg) abort( HTTP_STATUS_CODE_CONFLICT, @@ -302,9 +308,7 @@ def post(self): try: sigma_rule = ts_sigma_lib.parse_sigma_rule_by_text(content) except ValueError as e: - error_msg = "Sigma rule Parsing error with provided rule {0!s}".format( - str(e) - ) + error_msg = f"Sigma rule Parsing error with provided rule {e!s}" logger.error( error_msg, exc_info=True, @@ -317,7 +321,7 @@ def post(self): except NotImplementedError as e: error_msg = ( "Sigma Parsing error: Feature in the rule provided" - " is not implemented in this backend {0!s}".format(e) + f" is not implemented in this backend {e!s}" ) logger.error( error_msg, @@ -329,8 +333,7 @@ def post(self): ) except sigma_exceptions.SigmaParseError as e: - error_msg = "Sigma parsing error generating rule" - " with error: {0:s}".format(str(e)) + error_msg = f"Sigma parsing error generating rule with error: {e!s}" logger.error(error_msg, exc_info=True) abort( HTTP_STATUS_CODE_BAD_REQUEST, @@ -338,7 +341,7 @@ def post(self): ) except yaml.parser.ParserError as e: - error_msg = "Sigma parsing error: invalid YAML provided {0!s}".format(e) + error_msg = f"Sigma parsing error: invalid YAML provided {e!s}" logger.error( error_msg, exc_info=True, diff --git a/timesketch/api/v1/resources/sketch.py b/timesketch/api/v1/resources/sketch.py index e89d8e7b3d..185c16c359 100644 --- a/timesketch/api/v1/resources/sketch.py +++ b/timesketch/api/v1/resources/sketch.py @@ -16,24 +16,34 @@ import logging import opensearchpy -from flask import abort, current_app, jsonify, request -from flask_login import current_user, login_required -from flask_restful import Resource, inputs, reqparse -from sqlalchemy import not_, or_ -from timesketch.api.v1 import resources, utils +from flask import jsonify +from flask import request +from flask import abort +from flask import current_app +from flask_restful import Resource +from flask_restful import reqparse +from flask_restful import inputs +from flask_login import login_required +from flask_login import current_user +from sqlalchemy import not_ +from sqlalchemy import or_ + +from timesketch.api.v1 import resources +from timesketch.api.v1 import utils from timesketch.lib import forms +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND from timesketch.lib.aggregators import manager as aggregator_manager -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) from timesketch.lib.emojis import get_emojis_as_dict from timesketch.models import db_session -from timesketch.models.sketch import SearchTemplate, Sketch, View +from timesketch.models.sketch import Sketch +from timesketch.models.sketch import SearchTemplate +from timesketch.models.sketch import View + logger = logging.getLogger("timesketch.sketch_api") @@ -197,9 +207,8 @@ def post(self): form = forms.NameDescriptionForm.build(request) if not form.validate_on_submit(): error_message = "Unable to validate form data: " - for error in form.errors.values(): - error_message += f"{error}, " - abort(HTTP_STATUS_CODE_BAD_REQUEST, error_message[:-2]) + error_message += ", ".join(form.errors.values()) + abort(HTTP_STATUS_CODE_BAD_REQUEST, error_message) sketch = Sketch(name=form.name.data, description=form.description.data) db_session.add(sketch) @@ -222,8 +231,9 @@ def _add_label(sketch, label): """Add a label to the sketch.""" if sketch.has_label(label): logger.warning( - "Unable to apply the label [{0:s}] to sketch {1:d}, " - "already exists.".format(label, sketch.id) + "Unable to apply the label [%s] to sketch %s, already exists.", + label, + sketch.id, ) return False sketch.add_label(label, user=current_user) @@ -234,15 +244,16 @@ def _remove_label(sketch, label): """Removes a label to the sketch.""" if not sketch.has_label(label): logger.warning( - "Unable to remove the label [{0:s}] to sketch {1:d}, " - "label does not exist.".format(label, sketch.id) + "Unable to remove the label [%s] to sketch %s, label does not exist.", + label, + sketch.id, ) return False sketch.remove_label(label) return True @staticmethod - def _get_sketch_for_admin(sketch): + def _get_sketch_for_admin(sketch: Sketch): """Returns a limited sketch view for administrators. An administrator needs to get information about all sketches @@ -254,7 +265,7 @@ def _get_sketch_for_admin(sketch): to the underlying data of the sketch. Args: - sketch: a sketch object (instance of models.Sketch) + sketch: (object) a sketch object (instance of models.Sketch) Returns: A limited view of a sketch in JSON (instance of @@ -313,7 +324,11 @@ def get(self, sketch_id): # Get mappings for all indices in the sketch. This is used to set # columns shown in the event list. - sketch_indices = [t.searchindex.index_name for t in sketch.active_timelines] + sketch_indices = [ + t.searchindex.index_name + for t in sketch.active_timelines + if t.searchindex.get_status.status == "ready" + ] # Make sure the list of index names is uniq sketch_indices = list(set(sketch_indices)) @@ -334,15 +349,24 @@ def get(self, sketch_id): ) except opensearchpy.NotFoundError: logger.error( - "Unable to get indices mapping in datastore, for " - "indices: {0:s}".format(",".join(sketch_indices)) + "Unable to get indices mapping in datastore, for indices: [%s]", + ",".join(sketch_indices), ) mappings_settings = {} mappings = [] - for value in mappings_settings.values(): + for index_name, value in mappings_settings.items(): + # The structure is different in ES version 6.x and lower. This check + # makes sure we support both old and new versions. properties = value["mappings"].get("properties") + if not properties: + properties = next(iter(value["mappings"].values())).get("properties") + + # Determine if index is from the time before multiple timelines per + # index. This is used in the UI to support both modes. + is_legacy = bool("__ts_timeline_id" not in properties) + indices_metadata[index_name]["is_legacy"] = is_legacy for field, value_dict in properties.items(): mapping_dict = {} @@ -357,7 +381,15 @@ def get(self, sketch_id): # Get number of events per timeline if sketch_indices: + # Support legacy indices. + for timeline in sketch.active_timelines: + index_name = timeline.searchindex.index_name + if indices_metadata[index_name].get("is_legacy", False): + doc_count, _ = self.datastore.count(indices=index_name) + stats_per_timeline[timeline.id] = {"count": doc_count} + count_agg_spec = { + "size": 0, "aggs": { "per_timeline": { "terms": { @@ -365,11 +397,12 @@ def get(self, sketch_id): "size": len(sketch.timelines), } } - } + }, } - - count_agg = self.datastore.client.search( - index=sketch_indices, body=count_agg_spec, size=0 + count_agg = self.datastore.search( + sketch_id=sketch.id, + indices=sketch_indices, + query_dsl=count_agg_spec, ) count_per_timeline = ( @@ -419,37 +452,37 @@ def get(self, sketch_id): "updated_at": story.updated_at, } stories.append(story) - meta = dict( - aggregators=aggregators, - views=views, - stories=stories, - searchtemplates=[ + meta = { + "aggregators": aggregators, + "views": views, + "stories": stories, + "searchtemplates": [ {"name": searchtemplate.name, "id": searchtemplate.id} for searchtemplate in SearchTemplate.query.all() ], - emojis=get_emojis_as_dict(), - permissions={ + "emojis": get_emojis_as_dict(), + "permissions": { "public": bool(sketch.is_public), "read": bool(sketch.has_permission(current_user, "read")), "write": bool(sketch.has_permission(current_user, "write")), "delete": bool(sketch.has_permission(current_user, "delete")), }, - collaborators={ + "collaborators": { "users": [user.username for user in sketch.collaborators], "groups": [group.name for group in sketch.groups], }, - attributes=utils.get_sketch_attributes(sketch), - mappings=list(mappings), - indices_metadata=indices_metadata, - stats_per_timeline=stats_per_timeline, - last_activity=utils.get_sketch_last_activity(sketch), - sketch_labels=[label.label for label in sketch.labels], - filter_labels=( + "attributes": utils.get_sketch_attributes(sketch), + "mappings": list(mappings), + "indices_metadata": indices_metadata, + "stats_per_timeline": stats_per_timeline, + "last_activity": utils.get_sketch_last_activity(sketch), + "sketch_labels": [label.label for label in sketch.labels], + "filter_labels": ( self.datastore.get_filter_labels(sketch.id, sketch_indices) if sketch_indices else [] ), - ) + } return self.to_json(sketch, meta=meta) @login_required @@ -461,14 +494,14 @@ def delete(self, sketch_id): if not sketch.has_permission(current_user, "delete"): abort( HTTP_STATUS_CODE_FORBIDDEN, - ("User does not have sufficient access rights to " "delete a sketch."), + ("User does not have sufficient access rights to delete a sketch."), ) not_delete_labels = current_app.config.get("LABELS_TO_PREVENT_DELETION", []) for label in not_delete_labels: if sketch.has_label(label): abort( HTTP_STATUS_CODE_FORBIDDEN, - "Sketch with the label [{0:s}] cannot be deleted.".format(label), + f"Sketch with the label [{label:s}] cannot be deleted.", ) sketch.set_status(status="deleted") return HTTP_STATUS_CODE_OK @@ -511,7 +544,7 @@ def post(self, sketch_id): abort( HTTP_STATUS_CODE_BAD_REQUEST, 'Label actions needs to be either "add" or "remove", ' - "not [{0:s}]".format(label_action), + f"not [{label_action:s}]", ) if labels and isinstance(labels, (tuple, list)): diff --git a/timesketch/api/v1/resources/story.py b/timesketch/api/v1/resources/story.py index 2936235387..96a977d896 100644 --- a/timesketch/api/v1/resources/story.py +++ b/timesketch/api/v1/resources/story.py @@ -40,7 +40,7 @@ class StoryListResource(resources.ResourceMixin, Resource): """Resource to get all stories for a sketch or to create a new story.""" @login_required - def get(self, sketch_id): + def get(self, sketch_id: int): """Handles GET request to the resource. Args: @@ -66,7 +66,7 @@ def get(self, sketch_id): return self.to_json(stories) @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Args: @@ -104,7 +104,7 @@ class StoryResource(resources.ResourceMixin, Resource): """Resource to get a story.""" @staticmethod - def _export_story(story, sketch_id, export_format="markdown"): + def _export_story(story: Story, sketch_id: int, export_format: str = "markdown"): """Returns a story in a format as requested in export_format. Args: @@ -138,7 +138,7 @@ def _export_story(story, sketch_id, export_format="markdown"): return exporter.export_story() @login_required - def get(self, sketch_id, story_id): + def get(self, sketch_id: int, story_id: int): """Handles GET request to the resource. Args: @@ -169,21 +169,21 @@ def get(self, sketch_id, story_id): if story.sketch_id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "Sketch ID ({0:d}) does not match with the ID in " - "the story ({1:d})".format(sketch.id, story.sketch_id), + "Sketch ID ({:d}) does not match with the ID in " + "the story ({:d})".format(sketch.id, story.sketch_id), ) # Only allow editing if the current user is the author. # This is needed until we have proper collaborative editing and # locking implemented. - meta = dict(is_editable=False) + meta = {"is_editable": False} if current_user == story.user: meta["is_editable"] = True return self.to_json(story, meta=meta) @login_required - def post(self, sketch_id, story_id): + def post(self, sketch_id: int, story_id: int): """Handles POST request to the resource. Args: @@ -207,8 +207,8 @@ def post(self, sketch_id, story_id): if story.sketch_id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "Sketch ID ({0:d}) does not match with the ID in " - "the story ({1:d})".format(sketch.id, story.sketch_id), + "Sketch ID ({:d}) does not match with the ID in " + "the story ({:d})".format(sketch.id, story.sketch_id), ) if not sketch.has_permission(current_user, "write"): @@ -240,7 +240,7 @@ def post(self, sketch_id, story_id): return self.to_json(story, status_code=HTTP_STATUS_CODE_CREATED) @login_required - def delete(self, sketch_id, story_id): + def delete(self, sketch_id: int, story_id: int): """Handles DELETE request to the resource. Args: @@ -261,8 +261,8 @@ def delete(self, sketch_id, story_id): # Check that this timeline belongs to the sketch if story.sketch_id != sketch.id: msg = ( - "The sketch ID ({0:d}) does not match with the story" - "sketch ID ({1:d})".format(sketch.id, story.sketch_id) + "The sketch ID ({:d}) does not match with the story" + "sketch ID ({:d})".format(sketch.id, story.sketch_id) ) abort(HTTP_STATUS_CODE_FORBIDDEN, msg) diff --git a/timesketch/api/v1/resources/task.py b/timesketch/api/v1/resources/task.py index ed2f8d901b..0d5c488e87 100644 --- a/timesketch/api/v1/resources/task.py +++ b/timesketch/api/v1/resources/task.py @@ -15,9 +15,12 @@ import datetime -from flask import current_app, jsonify, request -from flask_login import current_user, login_required +from flask import current_app +from flask import jsonify +from flask import request from flask_restful import Resource +from flask_login import login_required +from flask_login import current_user from timesketch.api.v1 import resources from timesketch.models.sketch import SearchIndex @@ -26,22 +29,23 @@ class TaskResource(resources.ResourceMixin, Resource): """Resource to get information on celery task.""" + # pylint: disable=import-outside-toplevel def __init__(self): super().__init__() - + # pylint: disable=import-outside-toplevel from timesketch.app import create_celery_app self.celery = create_celery_app() def _get_celery_information(self, job_id): - + # pylint: disable=too-many-function-args celery_task = self.celery.AsyncResult(job_id) - task = dict( - task_id=celery_task.task_id, - state=celery_task.state, - successful=celery_task.successful(), - result=False, - ) + task = { + "task_id": celery_task.task_id, + "state": celery_task.state, + "successful": celery_task.successful(), + "result": False, + } if task.get("state", "") == "SUCCESS": task["result"] = celery_task.result diff --git a/timesketch/api/v1/resources/timeline.py b/timesketch/api/v1/resources/timeline.py index 0a42a01661..bc8cdae904 100644 --- a/timesketch/api/v1/resources/timeline.py +++ b/timesketch/api/v1/resources/timeline.py @@ -19,24 +19,29 @@ import uuid import opensearchpy -import six -from flask import abort, current_app, jsonify, request -from flask_login import current_user, login_required +from flask import jsonify +from flask import request +from flask import abort +from flask import current_app from flask_restful import Resource +from flask_login import login_required +from flask_login import current_user -from timesketch.api.v1 import resources, utils +from timesketch.api.v1 import resources +from timesketch.api.v1 import utils from timesketch.lib import forms -from timesketch.lib.aggregators import manager as aggregator_manager -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND +from timesketch.lib.definitions import HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR from timesketch.models import db_session -from timesketch.models.sketch import SearchIndex, Sketch, Timeline +from timesketch.models.sketch import SearchIndex +from timesketch.models.sketch import Sketch +from timesketch.models.sketch import Timeline +from timesketch.lib.aggregators import manager as aggregator_manager + logger = logging.getLogger("timesketch.timeline_api") @@ -46,10 +51,25 @@ class TimelineListResource(resources.ResourceMixin, Resource): @login_required def get(self, sketch_id): - """Handles GET request to the resource. + """Handles GET requests to retrieve a list of timelines associated with + a sketch. + + This method fetches all timelines that are linked to a specific sketch. + It verifies that the sketch exists and that the current user has read + permissions for that sketch. + + Args: + sketch_id (int): The ID of the sketch for which to retrieve timelines. Returns: - View in JSON (instance of flask.wrappers.Response) + flask.wrappers.Response: A JSON response containing a list of timeline + objects associated with the sketch. Each timeline object includes + details such as ID, name, description, and other relevant metadata. + + Raises: + HTTP_STATUS_CODE_NOT_FOUND: If no sketch is found with the given ID. + HTTP_STATUS_CODE_FORBIDDEN: If the current user does not have read + access to the specified sketch. """ sketch = Sketch.get_with_acl(sketch_id) if not sketch: @@ -63,10 +83,48 @@ def get(self, sketch_id): @login_required def post(self, sketch_id): - """Handles POST request to the resource. + """Handles POST requests to create or associate a timeline with a sketch. + + This method either creates a new timeline and associates it with a sketch, + or associates an existing timeline (identified by its search index ID) + with a sketch. It handles the following scenarios: + + Creating a New Timeline: If a timeline with the given search index ID + does not already exist within the sketch, a new timeline is created. + The new timeline's name and description are derived from the search + index, and it is associated with the provided sketch. + Associating an Existing Timeline: If a timeline with the given + search index ID already exists within the sketch, it is associated + with the sketch. + Running Sketch Analyzers: If the `AUTO_SKETCH_ANALYZERS` config is enabled, + sketch analyzers will be run on the newly created or associated timeline. + Adding Labels: If the sketch has labels that are in the + `LABELS_TO_PREVENT_DELETION` config, those labels will be added + to the timeline and search index. + + The method ensures that: + - The sketch exists. + - The current user has write access to the sketch. + - The provided search index ID is valid and not associated with a deleted index. + + Args: + sketch_id (int): The ID of the sketch to which the timeline should be + associated. Returns: - A sketch in JSON (instance of flask.wrappers.Response) + flask.wrappers.Response: A JSON response containing the timeline object + and metadata. + - HTTP_STATUS_CODE_CREATED (201): If a new timeline was created. + - HTTP_STATUS_CODE_OK (200): If an existing timeline was associated. + The metadata indicates whether a new timeline was created or not. + + Raises: + HTTP_STATUS_CODE_NOT_FOUND: If no sketch is found with the given ID. + HTTP_STATUS_CODE_FORBIDDEN: If the user does not have write access to + the sketch. + HTTP_STATUS_CODE_BAD_REQUEST: If the request data is invalid, such as: + - The timeline (searchindex id) is not an integer. + - The search index is deleted. """ sketch = Sketch.get_with_acl(sketch_id) if not sketch: @@ -101,41 +159,52 @@ def post(self, sketch_id): "Unable to create a timeline using a deleted search index", ) - timeline_name = form.get("timeline_name", searchindex.name) - timeline = Timeline( - name=timeline_name, - description=searchindex.description, - sketch=sketch, - user=current_user, - searchindex=searchindex, - ) - sketch.timelines.append(timeline) - labels_to_prevent_deletion = current_app.config.get( - "LABELS_TO_PREVENT_DELETION", [] - ) + timeline_id = [ + t.searchindex.id + for t in sketch.timelines + if t.searchindex.id == searchindex_id + ] - for label in sketch.get_labels: - if label not in labels_to_prevent_deletion: - continue - timeline.add_label(label) - searchindex.add_label(label) + if not timeline_id: + return_code = HTTP_STATUS_CODE_CREATED + timeline_name = form.get("timeline_name", searchindex.name) + timeline = Timeline( + name=timeline_name, + description=searchindex.description, + sketch=sketch, + user=current_user, + searchindex=searchindex, + ) + sketch.timelines.append(timeline) + labels_to_prevent_deletion = current_app.config.get( + "LABELS_TO_PREVENT_DELETION", [] + ) - # Set status to ready so the timeline can be queried. - timeline.set_status("ready") + for label in sketch.get_labels: + if label not in labels_to_prevent_deletion: + continue + timeline.add_label(label) + searchindex.add_label(label) - db_session.add(timeline) - db_session.commit() - return_code = HTTP_STATUS_CODE_CREATED + # Set status to ready so the timeline can be queried. + timeline.set_status("ready") + + db_session.add(timeline) + db_session.commit() + else: + metadata["created"] = False + return_code = HTTP_STATUS_CODE_OK + timeline = Timeline.get_by_id(timeline_id) # Run sketch analyzers when timeline is added. Import here to avoid # circular imports. - + # pylint: disable=import-outside-toplevel if current_app.config.get("AUTO_SKETCH_ANALYZERS"): - + # pylint: disable=import-outside-toplevel from timesketch.lib import tasks sketch_analyzer_group, _ = tasks.build_sketch_analysis_pipeline( - sketch_id, searchindex_id, current_user.id, timeline_id=timeline.id + sketch_id, searchindex_id, current_user.id, timeline_id=timeline_id ) if sketch_analyzer_group: pipeline = ( @@ -153,35 +222,73 @@ def post(self, sketch_id): class TimelineResource(resources.ResourceMixin, Resource): """Resource to get timeline.""" - def _add_label(self, timeline, label): - """Add a label to the timeline.""" + def _add_label(self, timeline: object, label: str) -> bool: + """Adds a label to the timeline if it does not already exist. + + Args: + timeline: The timeline object to add the label to. + label: The label string to add. + + Returns: + True if the label was successfully added, False otherwise. + Returns False if the label already exists on the timeline. + """ if timeline.has_label(label): logger.warning( - "Unable to apply the label [{0:s}] to timeline {1:s}, " - "already exists.".format(label, timeline.name) + "Unable to apply the label [%s] to timeline (ID: %d), already exists.", + label, + timeline.id, ) return False timeline.add_label(label, user=current_user) return True - def _remove_label(self, timeline, label): - """Removes a label from a timeline.""" + def _remove_label(self, timeline: object, label: str) -> bool: + """Removes a label from a timeline. + + Args: + timeline: The timeline object to remove the label from. + label: The label string to remove. + + Returns: + True if the label was successfully removed, False otherwise. + Returns False if the label does not exist on the timeline. + """ if not timeline.has_label(label): logger.warning( - "Unable to remove the label [{0:s}] from timeline {1:s}, " - "label does not exist.".format(label, timeline.name) + "Unable to remove the label [%s] from timeline (ID: %d), label does " + "not exist.", + label, + timeline.id, ) return False timeline.remove_label(label) return True @login_required - def get(self, sketch_id, timeline_id): - """Handles GET request to the resource. + def get(self, sketch_id: int, timeline_id: int): + """Handles GET requests for a specific timeline within a sketch. + + This method retrieves a specific timeline by its ID within a given sketch. + It verifies that both the sketch and the timeline exist, that the timeline + belongs to the sketch, and that the current user has read permission for + the sketch. It also fetches metadata about the timeline, such as the number + of indexed events. Args: - sketch_id: Integer primary key for a sketch database model - timeline_id: Integer primary key for a timeline database model + sketch_id (int): The ID of the sketch. + timeline_id (int): The ID of the timeline to retrieve. + + Returns: + flask.wrappers.Response: A JSON response containing the timeline object + and metadata. The metadata includes the number of indexed events + in the timeline. + + Raises: + HTTP_STATUS_CODE_NOT_FOUND: If the sketch or timeline is not found, or + if the timeline does not belong to the sketch. + HTTP_STATUS_CODE_FORBIDDEN: If the user does not have read permission + on the sketch. """ sketch = Sketch.get_with_acl(sketch_id) if not sketch: @@ -202,8 +309,8 @@ def get(self, sketch_id, timeline_id): if timeline.sketch.id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "The sketch ID ({0:d}) does not match with the timeline " - "sketch ID ({1:d})".format(sketch.id, timeline.sketch.id), + f"The sketch ID ({sketch.id:d}) does not match with the timeline " + f"sketch ID ({timeline.sketch.id:d})", ) if not sketch.has_permission(user=current_user, permission="read"): @@ -222,6 +329,7 @@ def get(self, sketch_id, timeline_id): "indices": [timeline.id], "order": "asc", "chips": [], + "fields": [{"field": "message", "type": "text"}], }, query_dsl=None, indices=[timeline.searchindex.index_name], @@ -233,12 +341,39 @@ def get(self, sketch_id, timeline_id): return self.to_json(timeline, meta=meta) @login_required - def post(self, sketch_id, timeline_id): - """Handles POST request to the resource. + def post(self, sketch_id: int, timeline_id: int): + """Handles POST requests to modify an existing timeline. + + This method allows for updating the properties of a timeline, such as + its name, description, and color. It also supports adding or removing + labels from the timeline. The method verifies that the sketch and + timeline exist, that the timeline belongs to the sketch, and that the + current user has write permission on the sketch. Args: - sketch_id: Integer primary key for a sketch database model - timeline_id: Integer primary key for a timeline database model + sketch_id (int): The ID of the sketch to which the timeline belongs. + timeline_id (int): The ID of the timeline to modify. + + Returns: + flask.wrappers.Response: + - HTTP_STATUS_CODE_OK (200): If the timeline is successfully + modified. + - HTTP_STATUS_CODE_BAD_REQUEST (400): If the form data is + invalid or if there's an issue with the label action or + label format. + - HTTP_STATUS_CODE_NOT_FOUND (404): If the sketch or timeline + is not found. + - HTTP_STATUS_CODE_FORBIDDEN (403): If the user does not have + write permission on the sketch. + + Raises: + HTTP_STATUS_CODE_BAD_REQUEST: If the form data is invalid, if the + label action is not "add" or "remove", or if the label format + is incorrect. + HTTP_STATUS_CODE_NOT_FOUND: If the sketch or timeline is not found, + or if the timeline does not belong to the sketch. + HTTP_STATUS_CODE_FORBIDDEN: If the user does not have write + permission on the sketch. """ sketch = Sketch.get_with_acl(sketch_id) if not sketch: @@ -256,8 +391,8 @@ def post(self, sketch_id, timeline_id): if timeline.sketch.id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "The sketch ID ({0:d}) does not match with the timeline " - "sketch ID ({1:d})".format(sketch.id, timeline.sketch.id), + f"The sketch ID ({sketch.id:d}) does not match with the timeline " + f"sketch ID ({timeline.sketch.id:d})", ) if not sketch.has_permission(user=current_user, permission="write"): @@ -281,7 +416,7 @@ def post(self, sketch_id, timeline_id): "converts to a list of strings." ), ) - if not all([isinstance(x, str) for x in labels]): + if not all(isinstance(x, str) for x in labels): abort( HTTP_STATUS_CODE_BAD_REQUEST, ( @@ -310,9 +445,10 @@ def post(self, sketch_id, timeline_id): changed = any(changes) if not changed: + msg = ", ".join(labels) abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Label [{0:s}] not {1:s}".format(", ".join(labels), label_action), + f"Label [{msg:s}] not {label_action:s}", ) db_session.add(timeline) @@ -331,12 +467,31 @@ def post(self, sketch_id, timeline_id): return HTTP_STATUS_CODE_OK @login_required - def delete(self, sketch_id, timeline_id): - """Handles DELETE request to the resource. + def delete(self, sketch_id: int, timeline_id: int): + """Deletes a timeline from a sketch. If the timeline's search index is not + used by any other timelines or in other sketches, the search index will + also be closed and archived. Args: - sketch_id: Integer primary key for a sketch database model - timeline_id: Integer primary key for a timeline database model + sketch_id: (int) Integer primary key for a sketch database model + timeline_id: (int) Integer primary key for a timeline database model + + Raises: + HTTP_STATUS_CODE_NOT_FOUND: If the sketch or timeline is not found. + HTTP_STATUS_CODE_FORBIDDEN: If the user does not have write + permission on the sketch or if the timeline has a label that + prevents deletion. + HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR: If there is an error + closing the search index. + Returns: + HTTP_STATUS_CODE_OK: If the timeline is successfully deleted. + Behavior: + - Checks if the sketch and timeline exist. + - Verifies the user has write permission on the sketch. + - Prevents deletion if the timeline has a label in the + LABELS_TO_PREVENT_DELETION config. + - Closes and archives the search index if it's not used by other + timelines in other sketches. """ sketch = Sketch.get_with_acl(sketch_id) if not sketch: @@ -367,8 +522,8 @@ def delete(self, sketch_id, timeline_id): timeline_string = str(timeline_use) msg = ( - "The sketch ID ({0:s}) does not match with the timeline " - "sketch ID ({1:s})".format(sketch_string, timeline_string) + f"The sketch ID ({sketch_string:s}) does not match with the " + f"timeline sketch ID ({timeline_string:s})" ) abort(HTTP_STATUS_CODE_NOT_FOUND, msg) @@ -383,7 +538,7 @@ def delete(self, sketch_id, timeline_id): if timeline.has_label(label): abort( HTTP_STATUS_CODE_FORBIDDEN, - "Timelines with label [{0:s}] cannot be deleted.".format(label), + f"Timelines with label [{label:s}] cannot be deleted.", ) # Check if this searchindex is used in other sketches. @@ -410,6 +565,23 @@ def delete(self, sketch_id, timeline_id): close_index = False break + if close_index: + try: + self.datastore.client.indices.close(index=searchindex.index_name) + except opensearchpy.NotFoundError: + logger.error( + "Unable to close index: %s - index not found", + searchindex.index_name, + ) + except opensearchpy.RequestError as e: + error_msg = ( + f"RequestError when closing index {searchindex.index_name:s}" + " - please try again in 5 min or contact your admin. " + f"Error: {e:s}" + ) + logger.error(error_msg) + abort(HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, error_msg) + searchindex.set_status(status="archived") timeline.set_status(status="archived") @@ -427,10 +599,30 @@ class TimelineCreateResource(resources.ResourceMixin, Resource): @login_required def post(self): - """Handles POST request to the resource. + """Handles POST requests to create a new timeline. + + This method processes a POST request to create a new timeline. It + validates the incoming form data, creates a new search index, and + optionally associates the timeline with an existing sketch. Returns: - A view in JSON (instance of flask.wrappers.Response) + flask.wrappers.Response: A JSON response containing the newly + created timeline or search index object. + - HTTP_STATUS_CODE_CREATED (201): If the timeline or search + index is successfully created. + - HTTP_STATUS_CODE_BAD_REQUEST (400): If the upload is not + enabled or if the form data is invalid. + - HTTP_STATUS_CODE_NOT_FOUND (404): If the specified sketch + is not found. + - HTTP_STATUS_CODE_FORBIDDEN (403): If the user does not have + write access to the sketch. + + Raises: + HTTP_STATUS_CODE_BAD_REQUEST: If the upload is not enabled or if + the form data is invalid. + HTTP_STATUS_CODE_NOT_FOUND: If the specified sketch is not found. + HTTP_STATUS_CODE_FORBIDDEN: If the user does not have write + access to the sketch. """ upload_enabled = current_app.config["UPLOAD_ENABLED"] if not upload_enabled: @@ -458,7 +650,7 @@ def post(self): # We do not need a human readable filename or # datastore index name, so we use UUIDs here. index_name = uuid.uuid4().hex - if not isinstance(index_name, six.text_type): + if not isinstance(index_name, str): index_name = codecs.decode(index_name, "utf-8") # Create the search index in the Timesketch database @@ -471,7 +663,6 @@ def post(self): searchindex.grant_permission(permission="read", user=current_user) searchindex.grant_permission(permission="write", user=current_user) searchindex.grant_permission(permission="delete", user=current_user) - searchindex.set_status("processing") db_session.add(searchindex) db_session.commit() @@ -489,7 +680,7 @@ def post(self): db_session.commit() # Return Timeline if it was created. - + # pylint: disable=no-else-return if timeline: return self.to_json(timeline, status_code=HTTP_STATUS_CODE_CREATED) diff --git a/timesketch/api/v1/resources/unfurl.py b/timesketch/api/v1/resources/unfurl.py index e4aefae10f..eb3db9b5da 100644 --- a/timesketch/api/v1/resources/unfurl.py +++ b/timesketch/api/v1/resources/unfurl.py @@ -14,16 +14,16 @@ """Unfurl API for version 1 of the Timesketch API.""" import logging - import unfurl -from flask import abort, jsonify, request -from flask_login import login_required + +from flask import jsonify +from flask import request +from flask import abort from flask_restful import Resource +from flask_login import login_required -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, -) +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR logger = logging.getLogger("timesketch.api_unfurl") @@ -55,8 +55,8 @@ def post(self): try: unfurl_result = unfurl.run(url) - except Exception as e: - logger.error("Error unfurling URL: {}".format(e)) + except Exception as e: # pylint: disable=broad-except + logger.error("Error unfurling URL: %s", str(e)) abort( HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, e, diff --git a/timesketch/api/v1/resources/upload.py b/timesketch/api/v1/resources/upload.py index 8f178d74d3..6cdeba3fbb 100644 --- a/timesketch/api/v1/resources/upload.py +++ b/timesketch/api/v1/resources/upload.py @@ -14,24 +14,32 @@ """Upload resources for version 1 of the Timesketch API.""" import codecs -import json import logging import os import uuid +import json +from typing import Optional, Dict, List -from flask import abort, current_app, jsonify, request -from flask_login import current_user, login_required +from flask import jsonify +from flask import request +from flask import abort +from flask import current_app from flask_restful import Resource - -from timesketch.api.v1 import resources, utils -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_NOT_FOUND, -) +from flask_login import login_required +from flask_login import current_user + +from timesketch.api.v1 import resources +from timesketch.api.v1 import utils +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND from timesketch.models import db_session -from timesketch.models.sketch import DataSource, SearchIndex, Sketch, Timeline +from timesketch.models.sketch import SearchIndex +from timesketch.models.sketch import Sketch +from timesketch.models.sketch import Timeline +from timesketch.models.sketch import DataSource + logger = logging.getLogger("timesketch.api_upload") @@ -40,7 +48,13 @@ class UploadFileResource(resources.ResourceMixin, Resource): """Resource that processes uploaded files.""" def _get_index( - self, name, description, sketch, index_name="", data_label="", extension="" + self, + name: str, + description: str, + sketch: Sketch, + index_name: str = "", + data_label: str = "", + extension: str = "", ): """Returns a SearchIndex object to be used for uploads. @@ -98,7 +112,6 @@ def _get_index( searchindex.grant_permission(permission="read", user=current_user) searchindex.grant_permission(permission="write", user=current_user) searchindex.grant_permission(permission="delete", user=current_user) - searchindex.set_status("processing") db_session.add(searchindex) db_session.commit() @@ -107,21 +120,22 @@ def _get_index( return searchindex + # pylint: disable=too-many-arguments def _upload_and_index( self, - file_extension, - timeline_name, - index_name, - sketch, - form, - enable_stream, - original_filename="", - data_label="", - file_path="", - events="", - meta=None, - headers_mapping=None, - delimiter=",", + file_extension: str, + timeline_name: str, + index_name: str, + sketch: Sketch, + form: Dict, + enable_stream: bool, + original_filename: str = "", + data_label: str = "", + file_path: str = "", + events: str = "", + meta: Optional[Dict] = None, + headers_mapping: Optional[List] = None, + delimiter: str = ",", ): """Creates a full pipeline for an uploaded file and returns the results. @@ -179,8 +193,8 @@ def _upload_and_index( logger.error( "There is a timeline in the sketch that has the same name " - "but is stored in a different index: name {0:s} attempting " - "index: {1:s} but found index {2:s} - retrying with a " + "but is stored in a different index: name {:s} attempting " + "index: {:s} but found index {:s} - retrying with a " "different timeline name.".format( timeline_name, searchindex.index_name, @@ -188,7 +202,7 @@ def _upload_and_index( ) ) - timeline_name = "{0:s}_{1:s}".format(timeline_name, uuid.uuid4().hex[-5:]) + timeline_name = f"{timeline_name:s}_{uuid.uuid4().hex[-5:]:s}" return self._upload_and_index( file_extension=file_extension, timeline_name=timeline_name, @@ -205,8 +219,6 @@ def _upload_and_index( delimiter=delimiter, ) - searchindex.set_status("processing") - if not timeline: timeline = Timeline.get_or_create( name=timeline_name, @@ -255,7 +267,7 @@ def _upload_and_index( sketch_id = sketch.id # Start Celery pipeline for indexing and analysis. # Import here to avoid circular imports. - + # pylint: disable=import-outside-toplevel from timesketch.lib import tasks pipeline = tasks.build_index_pipeline( @@ -309,32 +321,81 @@ def _upload_events(self, events, form, sketch, index_name, headers_mapping=None) def _upload_file( self, - file_storage, - form, - sketch, - index_name, - chunk_index_name="", - headers_mapping=None, - delimiter=",", + file_storage: object, + form: Dict, + sketch: Sketch, + index_name: str, + chunk_index_name: str = "", + headers_mapping: Optional[List] = None, + delimiter: str = ",", ): - """Upload a file. + """Uploads a file to Timesketch, handling both single files and file chunks. + + This method manages the entire file upload process, including: + - Saving the file (or file chunks) to the designated upload directory. + - Validating file properties (e.g., name, size, chunk integrity). + - Creating or retrieving a SearchIndex for the uploaded data. + - Creating a Timeline associated with the SearchIndex and Sketch. + - Initiating the indexing pipeline via Celery. + - Handling chunked uploads and ensuring all chunks are received. + - Returning appropriate responses based on the upload status. Args: - file_storage: a FileStorage object. - form: a dict with the configuration for the upload. - sketch: Instance of timesketch.models.sketch.Sketch - index_name: the OpenSearch index name for the timeline. - chunk_index_name: A unique identifier for a file if - chunks are used. - headers_mapping: list of dicts containing: - (i) target header we want to insert [key=target], - (ii) sources header we want to rename/combine [key=source], - (iii) def. value if we add a new column [key=default_value] + file_storage: A FileStorage object representing the uploaded file or chunk. + form: A dictionary containing form data from the request, including: + - name (str): The desired name for the timeline (default: filename). + - chunk_index (int, optional): The index of the current chunk + (for chunked uploads). + - chunk_byte_offset (int, optional): The byte offset of the + current chunk within the file. + - chunk_total_chunks (int, optional): The total number of + chunks in the file. + - total_file_size (int): The total size of the file in bytes. + - enable_stream (bool, optional): Whether to only index the + data without analysis. Defaults to False. + - data_label (str, optional): A label to categorize the data. + Defaults to "". + - provider (str, optional): The data provider. + Defaults to "N/A". + - context (str, optional): The data context. Defaults to "N/A". + - headersMapping (str, optional): JSON string of header mapping. + - delimiter (str, optional): delimiter to read the CSV file. + Defaults to ",". + sketch: The Sketch object to which the timeline will be added. + index_name: The name of the OpenSearch index for the timeline. + chunk_index_name: A unique identifier for the file if chunks are + used. + headers_mapping: A list of dictionaries for mapping headers. + Each dictionary should have: + - target (str): The target header name. + - source (str): The source header name to rename/combine. + - default_value (str, optional): A default value if a new + column is added. delimiter: delimiter to read the CSV file Returns: - A timeline if created otherwise a search index in JSON (instance - of flask.wrappers.Response) + A JSON response (flask.wrappers.Response) indicating the status + of the upload. + - For successful single file uploads or the final chunk of a + chunked upload: + Returns a JSON representation of the created Timeline with a 201 + Created status code. + - For intermediate chunks of a chunked upload: + Returns a JSON response with metadata about the upload progress + and a 201 Created status code. + + Raises: + HTTP_STATUS_CODE_BAD_REQUEST: + - If the timeline name is empty or exceeds 255 characters. + - If the file is empty. + - If the index name is invalid. + - If there's an error writing data to the file. + - If the file size is inconsistent after a chunked upload. + - If the upload is not enabled. + - If the file is not provided. + HTTP_STATUS_CODE_NOT_FOUND: If the sketch is not found. + HTTP_STATUS_CODE_FORBIDDEN: If the user does not have + write access to the sketch. """ _filename, _extension = os.path.splitext(file_storage.filename) file_extension = _extension.lstrip(".") @@ -419,7 +480,7 @@ def _upload_file( except OSError as e: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "Unable to write data with error: {0!s}.".format(e), + f"Unable to write data with error: {e!s}.", ) if (chunk_index + 1) != chunk_total_chunks: @@ -441,7 +502,7 @@ def _upload_file( abort( HTTP_STATUS_CODE_BAD_REQUEST, "Unable to save file correctly, inconsistent file size " - "({0:d} but should have been {1:d})".format( + "({:d} but should have been {:d})".format( os.path.getsize(file_path), file_size ), ) diff --git a/timesketch/api/v1/resources/user.py b/timesketch/api/v1/resources/user.py index 2eaa542f86..25dbac52ec 100644 --- a/timesketch/api/v1/resources/user.py +++ b/timesketch/api/v1/resources/user.py @@ -16,6 +16,7 @@ import logging from flask import abort +from flask import current_app from flask import jsonify from flask import request from flask_restful import Resource @@ -170,6 +171,14 @@ def get(self): """ profile = UserProfile.get_or_create(user=current_user) settings = json.loads(profile.settings) + + # If the value of SEARCH_PROCESSING_TIMELINES changes to false while the user + # had the option enabled, it remains enabled without functioning. + # Therefore, if SEARCH_PROCESSING_TIMELINES changes to false, we disable the + # showProcessingTimelineEvents option in the user's settings for display + # consistency. + if not current_app.config.get("SEARCH_PROCESSING_TIMELINES", False): + settings["showProcessingTimelineEvents"] = False schema = {"objects": [settings], "meta": {}} return jsonify(schema) @@ -196,7 +205,7 @@ class CollaboratorResource(resources.ResourceMixin, Resource): """Resource to update sketch collaborators.""" @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Args: @@ -227,9 +236,8 @@ def post(self, sketch_id): if not sketch.has_permission(user=current_user, permission=permission): abort( HTTP_STATUS_CODE_FORBIDDEN, - "The user does not have {0:s} permission on the sketch " - "and therefore can't grant it to " - "others".format(permission), + f"The user does not have {permission:s} permission on the " + "sketch and therefore can't grant it to others", ) for username in form.get("users", []): @@ -251,7 +259,7 @@ def post(self, sketch_id): group = Group.query.filter_by(name=group_name).first() if not group: - logger.error("Group: {0:s} not found".format(group_name)) + logger.error("Group: %s not found", group_name) continue # Only add groups publicly visible or owned by the current user @@ -264,7 +272,7 @@ def post(self, sketch_id): for username in form.get("remove_users", []): user = User.query.filter_by(username=username).first() permission_list = permissions or all_permissions.get( - "user/{0:s}".format(username), [] + f"user/{username:s}", [] ) for permission in permission_list: sketch.revoke_permission(permission=permission, user=user) @@ -272,7 +280,7 @@ def post(self, sketch_id): for group_name in form.get("remove_groups", []): group = Group.query.filter_by(name=group_name).first() permission_list = permissions or all_permissions.get( - "group/{0:s}".format(group_name), [] + f"group/{group_name:s}", [] ) for permission in permission_list: sketch.revoke_permission(permission=permission, group=group) diff --git a/timesketch/api/v1/resources/view.py b/timesketch/api/v1/resources/view.py index 91c2ce62e7..f79a826a18 100644 --- a/timesketch/api/v1/resources/view.py +++ b/timesketch/api/v1/resources/view.py @@ -40,7 +40,7 @@ class ViewListResource(resources.ResourceMixin, Resource): """Resource to create a View.""" @staticmethod - def create_view_from_form(sketch, form): + def create_view_from_form(sketch: Sketch, form: forms.SaveViewForm): """Creates a view from form data. Args: @@ -122,7 +122,7 @@ def create_view_from_form(sketch, form): return view @login_required - def get(self, sketch_id): + def get(self, sketch_id: int): """Handles GET request to the resource. Args: @@ -142,7 +142,7 @@ def get(self, sketch_id): return self.to_json(sketch.get_named_views) @login_required - def post(self, sketch_id): + def post(self, sketch_id: int): """Handles POST request to the resource. Args: @@ -153,10 +153,11 @@ def post(self, sketch_id): """ form = forms.SaveViewForm.build(request) if not form.validate_on_submit(): - error_message = "Unable to save view, not able to validate form data: " - for error in form.errors.values(): - error_message += f"{error}, " - abort(HTTP_STATUS_CODE_BAD_REQUEST, error_message[:-2]) + error_message = ( + "Unable to save view, not able to validate form data: " + + ", ".join(form.errors.values()) + ) + abort(HTTP_STATUS_CODE_BAD_REQUEST, error_message) sketch = Sketch.get_with_acl(sketch_id) if not sketch: @@ -180,7 +181,7 @@ class ViewResource(resources.ResourceMixin, Resource): """Resource to get a view.""" @login_required - def get(self, sketch_id, view_id): + def get(self, sketch_id: int, view_id: int): """Handles GET request to the resource. Args: @@ -205,8 +206,8 @@ def get(self, sketch_id, view_id): if view.sketch_id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "Sketch ID ({0:d}) does not match with the sketch ID " - "that is defined in the view ({1:d})".format(view.sketch_id, sketch.id), + "Sketch ID ({:d}) does not match with the sketch ID " + "that is defined in the view ({:d})".format(view.sketch_id, sketch.id), ) # If this is a user state view, check that it @@ -214,13 +215,13 @@ def get(self, sketch_id, view_id): if view.name == "" and view.user != current_user: abort( HTTP_STATUS_CODE_FORBIDDEN, - "Unable to view a state view that belongs to a " "different user.", + "Unable to view a state view that belongs to a different user.", ) # Check if view has been deleted if view.get_status.status == "deleted": - meta = dict(deleted=True, name=view.name) - schema = dict(meta=meta, objects=[]) + meta = {"deleted": True, "name": view.name} + schema = {"meta": meta, "objects": []} return jsonify(schema) # Make sure we have all expected attributes in the query filter. @@ -231,7 +232,7 @@ def get(self, sketch_id, view_id): return self.to_json(view) @login_required - def delete(self, sketch_id, view_id): + def delete(self, sketch_id: int, view_id: int): """Handles DELETE request to the resource. Args: @@ -255,8 +256,8 @@ def delete(self, sketch_id, view_id): if view.sketch_id != sketch.id: abort( HTTP_STATUS_CODE_NOT_FOUND, - "The view does not belong to the sketch ({0:d} vs " - "{1:d})".format(view.sketch_id, sketch.id), + "The view does not belong to the sketch ({:d} vs " + "{:d})".format(view.sketch_id, sketch.id), ) if not sketch.has_permission(user=current_user, permission="write"): @@ -273,7 +274,7 @@ def delete(self, sketch_id, view_id): return HTTP_STATUS_CODE_OK @login_required - def post(self, sketch_id, view_id): + def post(self, sketch_id: int, view_id: int): """Handles POST request to the resource. Args: diff --git a/timesketch/api/v1/resources_test.py b/timesketch/api/v1/resources_test.py index 4ceddb6c70..67e38d8fde 100644 --- a/timesketch/api/v1/resources_test.py +++ b/timesketch/api/v1/resources_test.py @@ -12,32 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. """Tests for v1 of the Timesketch API.""" -from __future__ import print_function, unicode_literals import json - -import mock -import pandas as pd - -from timesketch.api.v1.resources import ResourceMixin -from timesketch.lib.definitions import ( - HTTP_STATUS_CODE_BAD_REQUEST, - HTTP_STATUS_CODE_CREATED, - HTTP_STATUS_CODE_FORBIDDEN, - HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, - HTTP_STATUS_CODE_NOT_FOUND, - HTTP_STATUS_CODE_OK, -) +from unittest import mock + +from timesketch.lib.definitions import HTTP_STATUS_CODE_BAD_REQUEST +from timesketch.lib.definitions import HTTP_STATUS_CODE_CREATED +from timesketch.lib.definitions import HTTP_STATUS_CODE_NOT_FOUND +from timesketch.lib.definitions import HTTP_STATUS_CODE_OK +from timesketch.lib.definitions import HTTP_STATUS_CODE_FORBIDDEN +from timesketch.lib.testlib import BaseTest +from timesketch.lib.testlib import MockDataStore from timesketch.lib.dfiq import DFIQ -from timesketch.lib.testlib import BaseTest, MockDataStore -from timesketch.models.sketch import ( - Facet, - InvestigativeQuestion, - InvestigativeQuestionApproach, - Scenario, -) - -from timesketch.api.v1.resources import scenarios as Scenarios # fmt: skip +from timesketch.api.v1.resources import scenarios +from timesketch.models.sketch import Scenario +from timesketch.models.sketch import InvestigativeQuestion +from timesketch.models.sketch import InvestigativeQuestionApproach +from timesketch.models.sketch import Facet +from timesketch.api.v1.resources import ResourceMixin class ResourceMixinTest(BaseTest): @@ -45,7 +37,6 @@ class ResourceMixinTest(BaseTest): def test_to_json_empty_list(self): """Behavior of to_json when given an empty list.""" - response = ResourceMixin().to_json([]) self.assertEqual( response.json, @@ -85,7 +76,7 @@ def test_sketch_list_resource(self): def test_sketch_post_resource(self): """Authenticated request to create a sketch.""" self.login() - data = dict(name="test", description="test") + data = {"name": "test", "description": "test"} response = self.client.post( self.resource_url, data=json.dumps(data, ensure_ascii=False), @@ -119,6 +110,177 @@ def test_sketch_acl(self): response = self.client.get("/api/v1/sketches/2/") self.assert403(response) + def test_create_a_sketch(self): + """Authenticated request to create a sketch.""" + self.login() + data = {"name": "test_create_a_sketch", "description": "test_create_a_sketch"} + response = self.client.post( + "/api/v1/sketches/", + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + self.assertEqual(HTTP_STATUS_CODE_CREATED, response.status_code) + + # check the created sketch + + response = self.client.get("/api/v1/sketches/") + self.assertEqual(len(response.json["objects"]), 3) + self.assertIn(b"test_create_a_sketch", response.data) + self.assert200(response) + + def test_append_label_to_sketch(self): + """Authenticated request to append a label to a sketch.""" + self.login() + + data = {"labels": ["test_append_label_to_sketch"], "label_action": "add"} + + response = self.client.post( + "/api/v1/sketches/3/", + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + + self.assertEqual(response.status_code, HTTP_STATUS_CODE_CREATED) + + # check the result in content + response = self.client.get("/api/v1/sketches/3/") + self.assertEqual(len(response.json["objects"]), 1) + self.assertEqual(response.json["objects"][0]["name"], "Test 3") + self.assertIn( + "test_append_label_to_sketch", response.json["objects"][0]["label_string"] + ) + self.assert200(response) + + def test_archive_sketch(self): + """Authenticated request to archive a sketch.""" + self.login() + + # Create sketch to test with + data = {"name": "test_archive_sketch", "description": "test_archive_sketch"} + response = self.client.post( + "/api/v1/sketches/", + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + created_id = response.json["objects"][0]["id"] + + self.assertEqual(HTTP_STATUS_CODE_CREATED, response.status_code) + + # Pull sketch + response = self.client.get(f"/api/v1/sketches/{created_id}/") + self.assertEqual(HTTP_STATUS_CODE_OK, response.status_code) + self.assertEqual(len(response.json["objects"]), 1) + self.assertEqual(response.json["objects"][0]["name"], "test_archive_sketch") + + # Archive sketch + resource_url = f"/api/v1/sketches/{created_id}/archive/" + data = {"action": "archive"} + response = self.client.post( + resource_url, + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + self.assert200(response) + + # Pull the sketch again to get the status + response = self.client.get(f"/api/v1/sketches/{created_id}/") + self.assertEqual( + response.json["objects"][0]["name"], + "test_archive_sketch", + ) + self.assert200(response) + self.assertIn("archived", response.json["objects"][0]["status"][0]["status"]) + + def test_sketch_delete_not_existant_sketch(self): + """Authenticated request to delete a sketch that does not exist.""" + self.login() + response = self.client.delete("/api/v1/sketches/99/") + self.assert404(response) + + def test_sketch_delete_no_acl(self): + """Authenticated request to delete a sketch that the User has no read + permission on. + """ + self.login() + response = self.client.delete("/api/v1/sketches/2/") + self.assert403(response) + + def test_attempt_to_delete_protected_sketch(self): + """Authenticated request to delete a protected sketch.""" + self.login() + data = { + "name": "test_attempt_to_delete_protected_sketch", + "description": "test_attempt_to_delete_protected_sketch", + } + response = self.client.post( + "/api/v1/sketches/", + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + self.assertEqual(HTTP_STATUS_CODE_CREATED, response.status_code) + data = {"labels": ["protected"], "label_action": "add"} + response = self.client.post( + "/api/v1/sketches/4/", + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + + self.assertEqual( + response.json["objects"][0]["name"], + "test_attempt_to_delete_protected_sketch", + ) + self.assertIn("protected", response.json["objects"][0]["label_string"]) + + response = self.client.delete("/api/v1/sketches/4/") + self.assert403(response) + + def test_attempt_to_delete_archived_sketch(self): + """Authenticated request to archive a sketch.""" + self.login() + + # Create sketch to test with + data = { + "name": "test_delete_archive_sketch", + "description": "test_delete_archive_sketch", + } + response = self.client.post( + "/api/v1/sketches/", + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + created_id = response.json["objects"][0]["id"] + + self.assertEqual(HTTP_STATUS_CODE_CREATED, response.status_code) + response = self.client.get(f"/api/v1/sketches/{created_id}/") + self.assertEqual(len(response.json["objects"]), 1) + self.assertEqual( + response.json["objects"][0]["name"], "test_delete_archive_sketch" + ) + self.assertEqual(200, response.status_code) + + # Archive sketch + resource_url = f"/api/v1/sketches/{created_id}/archive/" + data = {"action": "archive"} + response = self.client.post( + resource_url, + data=json.dumps(data, ensure_ascii=False), + content_type="application/json", + ) + self.assert200(response) + + # Pull the sketch again to get the status + response = self.client.get(f"/api/v1/sketches/{created_id}/") + self.assertEqual( + response.json["objects"][0]["name"], + "test_delete_archive_sketch", + ) + self.assert200(response) + self.assertIn("archived", response.json["objects"][0]["status"][0]["status"]) + + # delete an archived sketch at the moment returns a 200 + response = self.client.delete(f"/api/v1/sketches/{created_id}/") + self.assertEqual(200, response.status_code) + class ViewListResourceTest(BaseTest): """Test ViewListResource.""" @@ -128,13 +290,13 @@ class ViewListResourceTest(BaseTest): def test_post_view_list_resource(self): """Authenticated request to create a view.""" self.login() - data = dict( - name="test", - new_searchtemplate=False, - query="test", - filter={}, - dsl={}, - ) + data = { + "name": "test", + "new_searchtemplate": False, + "query": "test", + "filter": {}, + "dsl": {}, + } response = self.client.post( self.resource_url, data=json.dumps(data, ensure_ascii=False), @@ -168,7 +330,7 @@ def test_view_resource(self): def test_post_view_resource(self): """Authenticated request to update a view.""" self.login() - data = dict(name="test", query="test", filter="{}") + data = {"name": "test", "query": "test", "filter": "{}"} response = self.client.post( self.resource_url, data=json.dumps(data, ensure_ascii=False), @@ -264,7 +426,7 @@ class ExploreResourceTest(BaseTest): def test_search(self): """Authenticated request to query the datastore.""" self.login() - data = dict(query="test", filter={}) + data = {"query": "test", "filter": {}} response = self.client.post( self.resource_url, data=json.dumps(data, ensure_ascii=False), @@ -287,7 +449,7 @@ class AggregationExploreResourceTest(BaseTest): def test_heatmap_aggregation(self): """Authenticated request to get aggregation requests.""" self.login() - data = dict(aggregation_dsl="test") + data = {"aggregation_dsl": "test"} response = self.client.post( self.resource_url, data=json.dumps(data, ensure_ascii=False), @@ -325,7 +487,7 @@ def test_get_event(self): ) response_json = response.json del response_json["meta"] - self.assertDictContainsSubset(self.expected_response, response_json) + self.assertEqual(response.json, response.json | self.expected_response) self.assert200(response) @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) @@ -595,7 +757,7 @@ def test_add_invalid_attributes_underscore(self): }, ) self.assertIn( - "Attribute '_invalid' for event_id '1' invalid, cannot start with " "'_'", + "Attribute '_invalid' for event_id '1' invalid, cannot start with '_'", response.json["meta"]["last_10_errors"], ) @@ -634,11 +796,11 @@ def test_post_annotate_resource(self): self.login() for annotation_type in ["comment", "label"]: event = {"_type": "test_event", "_index": "test", "_id": "test"} - data = dict( - annotation="test", - annotation_type=annotation_type, - events=[event], - ) + data = { + "annotation": "test", + "annotation_type": annotation_type, + "events": [event], + } response = self.client.post( self.resource_url, data=json.dumps(data), @@ -647,18 +809,17 @@ def test_post_annotate_resource(self): self.assertIsInstance(response.json, dict) self.assertEqual(response.status_code, HTTP_STATUS_CODE_CREATED) - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) def test_post_annotate_invalid_index_resource(self): """ Authenticated request to create an annotation, but in the wrong index. """ self.login() - event = {"_type": "test_event", "_index": "invalid_searchindex", "_id": "test"} - data = dict( - annotation="test", - annotation_type="comment", - events=[event], - ) + data = { + "annotation": "test", + "annotation_type": "comment", + "event_id": "test", + "searchindex_id": "invalid_searchindex", + } response = self.client.post( self.resource_url, data=json.dumps(data), @@ -676,7 +837,7 @@ class SearchIndexResourceTest(BaseTest): def test_post_create_searchindex(self): """Authenticated request to create a searchindex.""" self.login() - data = dict(searchindex_name="test3", es_index_name="test3", public=False) + data = {"searchindex_name": "test3", "es_index_name": "test3", "public": False} response = self.client.post( self.resource_url, data=json.dumps(data), @@ -694,18 +855,18 @@ class TimelineListResourceTest(BaseTest): def test_add_existing_timeline_resource(self): """Authenticated request to add a timeline to a sketch.""" self.login() - data = dict(timeline=1) + data = {"timeline": 1} response = self.client.post( self.resource_url, data=json.dumps(data, ensure_ascii=False), content_type="application/json", ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_CREATED) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_OK) def test_add_new_timeline_resource(self): """Authenticated request to add a timeline to a sketch.""" self.login() - data = dict(timeline=2) + data = {"timeline": 2} response = self.client.post( self.resource_url, data=json.dumps(data, ensure_ascii=False), @@ -754,12 +915,12 @@ def test_post_sigma_resource(self): self.login() - sigma = dict( - rule_uuid="5266a592-b793-11ea-b3de-bbbbbb", - title="Suspicious Installation of bbbbbb", - description="Detects suspicious installation of bbbbbb", - rule_yaml=MOCK_SIGMA_RULE, - ) + sigma = { + "rule_uuid": "5266a592-b793-11ea-b3de-bbbbbb", + "title": "Suspicious Installation of bbbbbb", + "description": "Detects suspicious installation of bbbbbb", + "rule_yaml": MOCK_SIGMA_RULE, + } # Create a first rule response = self.client.post( @@ -810,11 +971,11 @@ def test_put_sigma_rule(self): """Authenticated request to update sigma rule.""" self.login() - sigma = dict( - rule_uuid="5266a592-b793-11ea-b3de-bbbbbb", - title="Suspicious Installation of bbbbbb", - description="Detects suspicious installation of bbbbbb", - rule_yaml=""" + sigma = { + "rule_uuid": "5266a592-b793-11ea-b3de-bbbbbb", + "title": "Suspicious Installation of bbbbbb", + "description": "Detects suspicious installation of bbbbbb", + "rule_yaml": """ title: Suspicious Installation of bbbbbb id: 5266a592-b793-11ea-b3de-bbbbbb description: Detects suspicious installation of bbbbbb @@ -835,7 +996,7 @@ def test_put_sigma_rule(self): - Unknown level: high """, - ) + } # Create a first rule response = self.client.post( @@ -856,11 +1017,11 @@ def test_put_sigma_rule(self): response = self.client.put( "/api/v1/sigmarules/5266a592-b793-11ea-b3de-bbbbbb/", data=json.dumps( - dict( - rule_uuid="5266a592-b793-11ea-b3de-bbbbbb", - title="Suspicious Installation of cccccc", - description="Detects suspicious installation of cccccc", - rule_yaml=""" + { + "rule_uuid": "5266a592-b793-11ea-b3de-bbbbbb", + "title": "Suspicious Installation of cccccc", + "description": "Detects suspicious installation of cccccc", + "rule_yaml": """ title: Suspicious Installation of cccccc id: 5266a592-b793-11ea-b3de-bbbbbb description: Detects suspicious installation of cccccc @@ -881,7 +1042,7 @@ def test_put_sigma_rule(self): - Unknown level: high """, - ) + } ), content_type="application/json", ) @@ -964,7 +1125,7 @@ class SigmaRuleByTextResourceTest(BaseTest): }, "falsepositives": ["Unknown"], "level": "high", - "search_query": '(data_type:("shell:zsh:history" OR "bash:history:command" OR "apt:history:line" OR "selinux:line") AND "apt-get install foobar")', + "search_query": '(data_type:("shell:zsh:history" OR "bash:history:command" OR "apt:history:line" OR "selinux:line") AND "apt-get install foobar")', # pylint: disable=line-too-long "file_name": "N/A", } ], @@ -974,7 +1135,7 @@ def test_get_sigma_rule(self): """Authenticated request to get an sigma rule by text.""" self.login() - data = dict(content=self.correct_rule) + data = {"content": self.correct_rule} response = self.client.post( "/api/v1/sigmarules/text/", data=json.dumps(data, ensure_ascii=False), @@ -982,14 +1143,14 @@ def test_get_sigma_rule(self): ) self.assertIsNotNone(response) self.assertEqual(response.status_code, HTTP_STATUS_CODE_OK) - self.assertDictContainsSubset(self.expected_response, response.json) + self.assertEqual(response.json, response.json | self.expected_response) self.assert200(response) def test_get_non_existing_rule_by_text(self): """Authenticated request to get an sigma rule by text with non parseable yaml text.""" self.login() - data = dict(content="foobar: asd") + data = {"content": "foobar: asd"} response = self.client.post( "/api/v1/sigmarules/text/", data=json.dumps(data, ensure_ascii=False), @@ -1006,7 +1167,7 @@ def test_get_rule_by_text_no_form_data(self): self.login() response = self.client.post( "/api/v1/sigmarules/text/", - data=json.dumps(dict(action="post")), + data=json.dumps({"action": "post"}), content_type="application/json", ) data = json.loads(response.get_data(as_text=True)) @@ -1135,7 +1296,7 @@ def test_user_post_resource_admin(self): """Authenticated request (admin user) to create another user.""" self.login_admin() - data = dict(username="testuser", password="testpassword") + data = {"username": "testuser", "password": "testpassword"} response = self.client.post( "/api/v1/users/", data=json.dumps(data), @@ -1148,7 +1309,7 @@ def test_user_post_resource_without_admin(self): which should not work.""" self.login() - data = dict(username="testuser", password="testpassword") + data = {"username": "testuser", "password": "testpassword"} response = self.client.post( "/api/v1/users/", data=json.dumps(data), @@ -1162,7 +1323,7 @@ def test_user_post_resource_missing_username(self): but with missing username, which should not work.""" self.login_admin() - data = dict(username="", password="testpassword") + data = {"username": "", "password": "testpassword"} response = self.client.post( "/api/v1/users/", data=json.dumps(data), @@ -1176,7 +1337,7 @@ def test_user_post_resource_missing_password(self): but with missing password, which should not work.""" self.login_admin() - data = dict(username="testuser", password="") + data = {"username": "testuser", "password": ""} response = self.client.post( "/api/v1/users/", data=json.dumps(data), @@ -1198,222 +1359,6 @@ def test_user_get_resource_admin(self): self.assertEqual(data["objects"][0]["username"], "test1") -class TestNl2qResource(BaseTest): - """Test Nl2qResource.""" - - resource_url = "/api/v1/sketches/1/nl2q/" - - @mock.patch("timesketch.lib.llms.manager.LLMManager.create_provider") - @mock.patch("timesketch.api.v1.utils.run_aggregator") - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_prompt(self, mock_aggregator, mock_create_provider): - """Test the prompt is created correctly.""" - - self.login() - data = dict(question="Question for LLM?") - mock_AggregationResult = mock.MagicMock() - mock_AggregationResult.values = [ - {"data_type": "test:data_type:1"}, - {"data_type": "test:data_type:2"}, - ] - mock_aggregator.return_value = (mock_AggregationResult, {}) - mock_llm = mock.Mock() - mock_llm.generate.return_value = "LLM generated query" - mock_create_provider.return_value = mock_llm - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - expected_input = ( - "Examples:\n" - "example 1\n" - "\n" - "example 2\n" - "Types:\n" - '* "test:data_type:1" -> "field_test_1", "field_test_2"\n' - '* "test:data_type:2" -> "field_test_3", "field_test_4"\n' - "Question:\n" - "Question for LLM?" - ) - mock_llm.generate.assert_called_once_with(expected_input) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_OK) - self.assertDictEqual( - response.json, - { - "name": "AI generated search query", - "query_string": "LLM generated query", - "error": None, - }, - ) - - @mock.patch("timesketch.api.v1.utils.run_aggregator") - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_no_prompt(self, mock_aggregator): - """Test error when the prompt file is missing or not configured.""" - - self.app.config["PROMPT_NL2Q"] = "/file_does_not_exist.txt" - self.login() - data = dict(question="Question for LLM?") - mock_AggregationResult = mock.MagicMock() - mock_AggregationResult.values = [ - {"data_type": "test:data_type:1"}, - {"data_type": "test:data_type:2"}, - ] - mock_aggregator.return_value = (mock_AggregationResult, {}) - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR) - - del self.app.config["PROMPT_NL2Q"] - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR) - # data = json.loads(response.get_data(as_text=True)) - # self.assertIsNotNone(data.get("error")) - - @mock.patch("timesketch.api.v1.utils.run_aggregator") - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_no_examples(self, mock_aggregator): - """Test error when the prompt file is missing or not configured.""" - - self.app.config["EXAMPLES_NL2Q"] = "/file_does_not_exist.txt" - self.login() - data = dict(question="Question for LLM?") - mock_AggregationResult = mock.MagicMock() - mock_AggregationResult.values = [ - {"data_type": "test:data_type:1"}, - {"data_type": "test:data_type:2"}, - ] - mock_aggregator.return_value = (mock_AggregationResult, {}) - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR) - - del self.app.config["EXAMPLES_NL2Q"] - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR) - - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_no_question(self): - """Test nl2q without submitting a question.""" - - self.login() - data = dict() - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_BAD_REQUEST) - - @mock.patch("timesketch.api.v1.utils.run_aggregator") - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_wrong_llm_provider(self, mock_aggregator): - """Test nl2q with llm provider that does not exist.""" - - self.app.config["LLM_PROVIDER_CONFIGS"] = {"default": {"DoesNotExists": {}}} - self.login() - self.login() - data = dict(question="Question for LLM?") - mock_AggregationResult = mock.MagicMock() - mock_AggregationResult.values = [ - {"data_type": "test:data_type:1"}, - {"data_type": "test:data_type:2"}, - ] - mock_aggregator.return_value = (mock_AggregationResult, {}) - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_OK) - data = json.loads(response.get_data(as_text=True)) - self.assertIsNotNone(data.get("error")) - - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_no_llm_provider(self): - """Test nl2q with no LLM provider configured.""" - - if "LLM_PROVIDER_CONFIGS" in self.app.config: - del self.app.config["LLM_PROVIDER_CONFIGS"] - self.login() - data = dict(question="Question for LLM?") - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR) - - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_no_sketch(self): - """Test the nl2q with non existing sketch.""" - - self.login() - data = dict(question="Question for LLM?") - response = self.client.post( - "/api/v1/sketches/9999/nl2q/", - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_NOT_FOUND) - - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_no_permission(self): - """Test the nl2q with no permission on the sketch.""" - - self.login() - data = dict(question="Question for LLM?") - response = self.client.post( - "/api/v1/sketches/2/nl2q/", - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual(response.status_code, HTTP_STATUS_CODE_FORBIDDEN) - - @mock.patch("timesketch.lib.llms.manager.LLMManager.create_provider") - @mock.patch("timesketch.api.v1.utils.run_aggregator") - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_nl2q_llm_error(self, mock_aggregator, mock_create_provider): - """Test nl2q with llm error.""" - - self.login() - data = dict(question="Question for LLM?") - mock_AggregationResult = mock.MagicMock() - mock_AggregationResult.values = [ - {"data_type": "test:data_type:1"}, - {"data_type": "test:data_type:2"}, - ] - mock_aggregator.return_value = (mock_AggregationResult, {}) - mock_llm = mock.Mock() - mock_llm.generate.side_effect = Exception("Test exception") - mock_create_provider.return_value = mock_llm - response = self.client.post( - self.resource_url, - data=json.dumps(data), - content_type="application/json", - ) - self.assertEqual( - response.status_code, HTTP_STATUS_CODE_OK - ) # Still expect 200 OK with error in JSON - data = json.loads(response.get_data(as_text=True)) - self.assertIsNotNone(data.get("error")) - - class SystemSettingsResourceTest(BaseTest): """Test system settings resource.""" @@ -1423,11 +1368,28 @@ def test_system_settings_resource(self): """Authenticated request to get system settings.""" self.app.config["LLM_PROVIDER_CONFIGS"] = {"default": {"test": {}}} self.app.config["DFIQ_ENABLED"] = False + self.login() + response = self.client.get(self.resource_url) + self.assertEqual(response.json["DFIQ_ENABLED"], False) + self.assertEqual(response.json["SEARCH_PROCESSING_TIMELINES"], False) + + self.assertIn("LLM_FEATURES_AVAILABLE", response.json) + self.assertIn("default", response.json["LLM_FEATURES_AVAILABLE"]) + + def test_system_settings_invalid_llm_config(self): + """Test with invalid LLM configuration.""" + self.app.config["LLM_PROVIDER_CONFIGS"] = "invalid_config" self.login() response = self.client.get(self.resource_url) - expected_response = {"DFIQ_ENABLED": False, "LLM_PROVIDER": "test"} - self.assertEqual(response.json, expected_response) + + expected_response = { + "DFIQ_ENABLED": False, + "SEARCH_PROCESSING_TIMELINES": False, + "LLM_FEATURES_AVAILABLE": {"default": False}, + } + + self.assertDictEqual(response.json, expected_response) class ScenariosResourceTest(BaseTest): @@ -1499,13 +1461,13 @@ def test_check_and_run_dfiq_analysis_steps(self, mock_analyzer_manager): self._commit_to_database(scenario_sql) # Test without analysis step - result = Scenarios.check_and_run_dfiq_analysis_steps(scenario_sql, test_sketch) + result = scenarios.check_and_run_dfiq_analysis_steps(scenario_sql, test_sketch) self.assertFalse(result) - result = Scenarios.check_and_run_dfiq_analysis_steps(facet_sql, test_sketch) + result = scenarios.check_and_run_dfiq_analysis_steps(facet_sql, test_sketch) self.assertFalse(result) - result = Scenarios.check_and_run_dfiq_analysis_steps(approach_sql, test_sketch) + result = scenarios.check_and_run_dfiq_analysis_steps(approach_sql, test_sketch) self.assertFalse(result) # Add analysis step to approach @@ -1524,7 +1486,7 @@ def test_check_and_run_dfiq_analysis_steps(self, mock_analyzer_manager): ] # Test with analysis step - result = Scenarios.check_and_run_dfiq_analysis_steps( + result = scenarios.check_and_run_dfiq_analysis_steps( scenario_sql, test_sketch, mock_analyzer_manager ) self.assertEqual(result, [mock.ANY, mock.ANY]) @@ -1532,7 +1494,7 @@ def test_check_and_run_dfiq_analysis_steps(self, mock_analyzer_manager): approach=approach_sql ) - result = Scenarios.check_and_run_dfiq_analysis_steps( + result = scenarios.check_and_run_dfiq_analysis_steps( facet_sql, test_sketch, mock_analyzer_manager ) self.assertEqual(result, [mock.ANY]) @@ -1540,7 +1502,7 @@ def test_check_and_run_dfiq_analysis_steps(self, mock_analyzer_manager): approach=approach_sql ) - result = Scenarios.check_and_run_dfiq_analysis_steps( + result = scenarios.check_and_run_dfiq_analysis_steps( question_sql, test_sketch, mock_analyzer_manager ) self.assertEqual(result, [mock.ANY]) @@ -1549,70 +1511,218 @@ def test_check_and_run_dfiq_analysis_steps(self, mock_analyzer_manager): ) # Test with invalid object - result = Scenarios.check_and_run_dfiq_analysis_steps("invalid", test_sketch) + result = scenarios.check_and_run_dfiq_analysis_steps("invalid", test_sketch) self.assertFalse(result) -class MockLLM: - """Mock LLM class for testing.""" +@mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) +class LLMResourceTest(BaseTest): + """Test LLMResource.""" + + resource_url = "/api/v1/sketches/1/llm/" + + @mock.patch("timesketch.models.sketch.Sketch.get_with_acl") + @mock.patch( + "timesketch.lib.llms.features.manager.FeatureManager.get_feature_instance" + ) + @mock.patch("timesketch.lib.utils.get_validated_indices") + @mock.patch("timesketch.api.v1.resources.llm.LLMResource._execute_llm_call") + def test_post_success( + self, + mock_execute_llm, + mock_get_validated_indices, + mock_get_feature, + mock_get_with_acl, + ): + """Test a successful POST request to the LLM endpoint.""" + mock_sketch = mock.MagicMock() + mock_sketch.has_permission.return_value = True + mock_sketch.id = 1 + mock_get_with_acl.return_value = mock_sketch + + mock_feature = mock.MagicMock() + mock_feature.NAME = "test_feature" + mock_feature.generate_prompt.return_value = "test prompt" + mock_feature.process_response.return_value = {"result": "test result"} + mock_get_feature.return_value = mock_feature + + mock_get_validated_indices.return_value = (["index1"], [1]) + mock_execute_llm.return_value = {"response": "mock response"} - def generate(self): - return {"summary": "Mock summary from LLM"} + self.login() + response = self.client.post( + self.resource_url, + data=json.dumps({"feature": "test_feature", "filter": {}}), + content_type="application/json", + ) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_OK) + response_data = json.loads(response.get_data(as_text=True)) + self.assertEqual(response_data, {"result": "test result"}) + def test_post_missing_data(self): + """Test POST request with missing data.""" + self.login() + response = self.client.post( + self.resource_url, + data=json.dumps({"some_param": "some_value"}), + content_type="application/json", + ) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_BAD_REQUEST) + response_data = json.loads(response.get_data(as_text=True)) + self.assertIn("The 'feature' parameter is required", response_data["message"]) -class TestLLMSummarizeResource(BaseTest): - """Test LLMSummarizeResource.""" + @mock.patch("timesketch.models.sketch.Sketch.get_with_acl") + def test_post_missing_feature(self, mock_get_with_acl): + """Test POST request with no feature parameter.""" + mock_sketch = mock.MagicMock() + mock_sketch.has_permission.return_value = True + mock_get_with_acl.return_value = mock_sketch - resource_url = "/api/v1/sketches/1/events/summary/" + self.login() + response = self.client.post( + self.resource_url, + data=json.dumps({"filter": {}}), # No 'feature' key + content_type="application/json", + ) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_BAD_REQUEST) + response_data = json.loads(response.get_data(as_text=True)) + self.assertIn("The 'feature' parameter is required", response_data["message"]) + + @mock.patch("timesketch.models.sketch.Sketch.get_with_acl") + def test_post_invalid_sketch(self, mock_get_with_acl): + """Test POST request with an invalid sketch ID.""" + mock_get_with_acl.return_value = None - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - def test_llm_summarize_no_events(self): - """Test LLM summarizer when no events are returned from the Timesketch query.""" self.login() - self.app.config["PROMPT_LLM_SUMMARIZATION"] = "data/llm_summarize/prompt.txt" + response = self.client.post( + self.resource_url, + data=json.dumps({"feature": "test_feature", "filter": {}}), + content_type="application/json", + ) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_NOT_FOUND) + response_data = json.loads(response.get_data(as_text=True)) + self.assertIn("No sketch found with this ID", response_data["message"]) - with mock.patch( - "timesketch.api.v1.resources.llm_summarize.LLMSummarizeResource._run_timesketch_query", - return_value=pd.DataFrame(), - ), mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore): - response = self.client.post( - self.resource_url, - data=json.dumps({"query": "*"}), - content_type="application/json", - ) + @mock.patch("timesketch.models.sketch.Sketch.get_with_acl") + def test_post_no_permission(self, mock_get_with_acl): + """Test POST request when user lacks read permission.""" + mock_sketch = mock.MagicMock() + mock_sketch.has_permission.return_value = False + mock_get_with_acl.return_value = mock_sketch - self.assertEqual(response.status_code, 200) + self.login() + response = self.client.post( + self.resource_url, + data=json.dumps({"feature": "test_feature", "filter": {}}), + content_type="application/json", + ) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_FORBIDDEN) response_data = json.loads(response.get_data(as_text=True)) - self.assertEqual( - response_data.get("summary"), - "No events to summarize based on the current filter.", + self.assertIn( + "User does not have read access to the sketch", response_data["message"] ) - @mock.patch("timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore) - @mock.patch("timesketch.lib.llms.manager.LLMManager.create_provider") - def test_llm_summarize_with_events(self, mock_create_provider): - """Test LLM summarizer with events returned and mock LLM.""" + @mock.patch("timesketch.models.sketch.Sketch.get_with_acl") + @mock.patch( + "timesketch.lib.llms.features.manager.FeatureManager.get_feature_instance" + ) + def test_post_invalid_feature(self, mock_get_feature, mock_get_with_acl): + """Test POST request with an invalid feature name.""" + mock_sketch = mock.MagicMock() + mock_sketch.has_permission.return_value = True + mock_get_with_acl.return_value = mock_sketch + + mock_get_feature.side_effect = KeyError("Invalid feature") + self.login() - self.app.config["PROMPT_LLM_SUMMARIZATION"] = "data/llm_summarize/prompt.txt" - mock_create_provider.return_value = MockLLM() - - sample_events = pd.DataFrame([{"message": "Test event message"}]) - - with mock.patch( - "timesketch.api.v1.resources.llm_summarize.LLMSummarizeResource._run_timesketch_query", - return_value=sample_events, - ), mock.patch( - "timesketch.api.v1.resources.llm_summarize.LLMSummarizeResource._get_content", - return_value={"summary": "Mock summary from LLM"}, - ), mock.patch( - "timesketch.api.v1.resources.OpenSearchDataStore", MockDataStore - ): - response = self.client.post( - self.resource_url, - data=json.dumps({"query": "*"}), - content_type="application/json", - ) + response = self.client.post( + self.resource_url, + data=json.dumps({"feature": "invalid_feature", "filter": {}}), + content_type="application/json", + ) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_BAD_REQUEST) + response_data = json.loads(response.get_data(as_text=True)) + self.assertIn("Invalid LLM feature: invalid_feature", response_data["message"]) + + @mock.patch("timesketch.models.sketch.Sketch.get_with_acl") + @mock.patch( + "timesketch.lib.llms.features.manager.FeatureManager.get_feature_instance" + ) + @mock.patch("timesketch.lib.utils.get_validated_indices") + def test_post_prompt_generation_error( + self, + mock_get_validated_indices, + mock_get_feature, + mock_get_with_acl, + ): + """Test handling of errors during prompt generation.""" + mock_sketch = mock.MagicMock() + mock_sketch.has_permission.return_value = True + mock_sketch.id = 1 + mock_get_with_acl.return_value = mock_sketch + + mock_feature = mock.MagicMock() + mock_feature.NAME = "test_feature" + mock_feature.generate_prompt.side_effect = ValueError( + "Prompt generation failed" + ) + mock_get_feature.return_value = mock_feature + + mock_get_validated_indices.return_value = (["index1"], [1]) + + self.login() + response = self.client.post( + self.resource_url, + data=json.dumps({"feature": "test_feature", "filter": {}}), + content_type="application/json", + ) - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, HTTP_STATUS_CODE_BAD_REQUEST) response_data = json.loads(response.get_data(as_text=True)) - self.assertEqual(response_data.get("summary"), "Mock summary from LLM") + self.assertIn("Prompt generation failed", response_data["message"]) + + mock_feature.generate_prompt.assert_called_once() + + @mock.patch("timesketch.models.sketch.Sketch.get_with_acl") + @mock.patch( + "timesketch.lib.llms.features.manager.FeatureManager.get_feature_instance" + ) + @mock.patch("timesketch.lib.utils.get_validated_indices") + @mock.patch("multiprocessing.Process") + def test_post_llm_execution_timeout( + self, + mock_process, + mock_get_validated_indices, + mock_get_feature, + mock_get_with_acl, + ): + """Test handling of LLM execution timeouts.""" + # Setup mocks + mock_sketch = mock.MagicMock() + mock_sketch.has_permission.return_value = True + mock_sketch.id = 1 + mock_get_with_acl.return_value = mock_sketch + + mock_feature = mock.MagicMock() + mock_feature.NAME = "test_feature" + mock_feature.generate_prompt.return_value = "test prompt" + mock_get_feature.return_value = mock_feature + + mock_get_validated_indices.return_value = (["index1"], [1]) + + process_instance = mock.MagicMock() + process_instance.is_alive.return_value = True + mock_process.return_value = process_instance + + self.login() + response = self.client.post( + self.resource_url, + data=json.dumps({"feature": "test_feature", "filter": {}}), + content_type="application/json", + ) + + self.assertEqual(response.status_code, HTTP_STATUS_CODE_BAD_REQUEST) + response_data = json.loads(response.get_data(as_text=True)) + self.assertIn("LLM call timed out", response_data["message"]) + + process_instance.terminate.assert_called_once() diff --git a/timesketch/api/v1/routes.py b/timesketch/api/v1/routes.py index 7fa517b49a..c7b01a8e8a 100644 --- a/timesketch/api/v1/routes.py +++ b/timesketch/api/v1/routes.py @@ -13,104 +13,89 @@ # limitations under the License. """URL routes for API resources.""" -from __future__ import unicode_literals -from .resources.aggregation import ( - AggregationExploreResource, - AggregationGroupListResource, - AggregationGroupResource, - AggregationInfoResource, - AggregationListResource, - AggregationResource, -) -from .resources.analysis import ( - AnalysisResource, - AnalyzerRunResource, - AnalyzerSessionActiveListResource, - AnalyzerSessionResource, -) -from .resources.archive import SketchArchiveResource +from .resources.aggregation import AggregationGroupResource +from .resources.aggregation import AggregationGroupListResource +from .resources.aggregation import AggregationListResource +from .resources.aggregation import AggregationExploreResource +from .resources.aggregation import AggregationInfoResource +from .resources.aggregation import AggregationResource +from .resources.analysis import AnalysisResource +from .resources.analysis import AnalyzerRunResource +from .resources.analysis import AnalyzerSessionActiveListResource +from .resources.analysis import AnalyzerSessionResource from .resources.attribute import AttributeResource -from .resources.contextlinks import ContextLinkConfigResource +from .resources.explore import ExploreResource +from .resources.explore import SearchHistoryResource +from .resources.explore import SearchHistoryTreeResource from .resources.datafinder import DataFinderResource -from .resources.datasource import DataSourceListResource, DataSourceResource -from .resources.event import ( - CountEventsResource, - EventAddAttributeResource, - EventAnnotationResource, - EventCreateResource, - EventResource, - EventTaggingResource, - EventUnTagResource, - MarkEventsWithTimelineIdentifier, -) -from .resources.explore import ( - ExploreResource, - QueryResource, - SearchHistoryResource, - SearchHistoryTreeResource, -) -from .resources.graph import ( - GraphCacheResource, - GraphListResource, - GraphPluginListResource, - GraphResource, -) +from .resources.datasource import DataSourceResource +from .resources.datasource import DataSourceListResource +from .resources.event import EventResource +from .resources.event import EventAnnotationResource +from .resources.event import EventCreateResource +from .resources.event import EventTaggingResource +from .resources.event import EventUnTagResource +from .resources.event import EventAddAttributeResource +from .resources.event import CountEventsResource +from .resources.event import MarkEventsWithTimelineIdentifier +from .resources.sketch import SketchResource +from .resources.sketch import SketchListResource +from .resources.archive import SketchArchiveResource from .resources.information import VersionResource -from .resources.intelligence import TagMetadataResource -from .resources.llm_summarize import LLMSummarizeResource -from .resources.nl2q import Nl2qResource -from .resources.scenarios import ( - FacetListResource, - QuestionConclusionListResource, - QuestionConclusionResource, - QuestionListResource, - QuestionOrphanListResource, - QuestionResource, - QuestionTemplateListResource, - QuestionWithFacetListResource, - QuestionWithScenarioListResource, - ScenarioListResource, - ScenarioResource, - ScenarioStatusResource, - ScenarioTemplateListResource, -) -from .resources.searchindex import SearchIndexListResource, SearchIndexResource -from .resources.searchtemplate import ( - SearchTemplateListResource, - SearchTemplateParseResource, - SearchTemplateResource, -) -from .resources.session import SessionResource -from .resources.settings import SystemSettingsResource -from .resources.sigma import ( - SigmaRuleByTextResource, - SigmaRuleListResource, - SigmaRuleResource, -) -from .resources.sketch import SketchListResource, SketchResource -from .resources.story import StoryListResource, StoryResource +from .resources.view import ViewResource +from .resources.view import ViewListResource +from .resources.searchtemplate import SearchTemplateResource +from .resources.searchtemplate import SearchTemplateParseResource +from .resources.searchtemplate import SearchTemplateListResource +from .resources.upload import UploadFileResource from .resources.task import TaskResource -from .resources.timeline import ( - TimelineFieldsResource, - TimelineListResource, - TimelineResource, -) +from .resources.story import StoryListResource +from .resources.story import StoryResource +from .resources.explore import QueryResource +from .resources.timeline import TimelineResource +from .resources.timeline import TimelineListResource +from .resources.timeline import TimelineFieldsResource +from .resources.searchindex import SearchIndexListResource +from .resources.searchindex import SearchIndexResource +from .resources.session import SessionResource +from .resources.user import UserListResource +from .resources.user import UserResource +from .resources.user import UserSettingsResource +from .resources.user import GroupListResource +from .resources.user import CollaboratorResource +from .resources.user import LoggedInUserResource +from .resources.sigma import SigmaRuleResource +from .resources.sigma import SigmaRuleListResource +from .resources.sigma import SigmaRuleByTextResource +from .resources.graph import GraphListResource +from .resources.graph import GraphResource +from .resources.graph import GraphPluginListResource +from .resources.graph import GraphCacheResource +from .resources.intelligence import TagMetadataResource +from .resources.contextlinks import ContextLinkConfigResource from .resources.unfurl import UnfurlResource -from .resources.upload import UploadFileResource -from .resources.user import ( - CollaboratorResource, - GroupListResource, - LoggedInUserResource, - UserListResource, - UserResource, - UserSettingsResource, -) -from .resources.view import ViewListResource, ViewResource +from .resources.llm import LLMResource +from .resources.settings import SystemSettingsResource + +from .resources.scenarios import ScenarioTemplateListResource +from .resources.scenarios import ScenarioListResource +from .resources.scenarios import ScenarioResource +from .resources.scenarios import ScenarioStatusResource +from .resources.scenarios import FacetListResource +from .resources.scenarios import QuestionOrphanListResource +from .resources.scenarios import QuestionWithScenarioListResource +from .resources.scenarios import QuestionWithFacetListResource +from .resources.scenarios import QuestionTemplateListResource +from .resources.scenarios import QuestionListResource +from .resources.scenarios import QuestionResource +from .resources.scenarios import QuestionConclusionListResource +from .resources.scenarios import QuestionConclusionResource + # Disable error for long line. Readability is more important than line # length in this case. - +# pylint: disable=line-too-long API_ROUTES = [ (SketchListResource, "/sketches/"), (SketchResource, "/sketches//"), @@ -215,8 +200,7 @@ (TagMetadataResource, "/intelligence/tagmetadata/"), (ContextLinkConfigResource, "/contextlinks/"), (UnfurlResource, "/unfurl/"), - (Nl2qResource, "/sketches//nl2q/"), - (LLMSummarizeResource, "/sketches//events/summary/"), + (LLMResource, "/sketches//llm/"), (SystemSettingsResource, "/settings/"), # Scenario templates (ScenarioTemplateListResource, "/scenarios/"), diff --git a/timesketch/api/v1/utils.py b/timesketch/api/v1/utils.py index a8d7e4ec79..7d268bfe26 100644 --- a/timesketch/api/v1/utils.py +++ b/timesketch/api/v1/utils.py @@ -189,7 +189,7 @@ def run_aggregator_group(group, sketch_id): if aggregator.sketch_id != group.sketch_id: abort( HTTP_STATUS_CODE_BAD_REQUEST, - "All aggregations in a group must belong to the group " "sketch", + "All aggregations in a group must belong to the group sketch", ) if aggregator.parameters: @@ -238,7 +238,7 @@ def run_aggregator_group(group, sketch_id): meta = { "method": "aggregator_group", - "chart_type": "compound: {0:s}".format(orientation), + "chart_type": f"compound: {orientation:s}", "name": group.name, "description": group.description, "es_time": time_after - time_before, @@ -261,17 +261,14 @@ def load_yaml_config(config_parameter_name): yaml_path = current_app.config.get(config_parameter_name, "") if not yaml_path: logger.error( - "The path to the YAML file isn't defined in the " "main configuration file" + "The path to the YAML file isn't defined in the main configuration file" ) return {} if not os.path.isfile(yaml_path): - logger.error( - "Unable to read the config, file: " - "[{0:s}] does not exist".format(yaml_path) - ) + logger.error("Unable to read the config, file: [%s] does not exist", yaml_path) return {} - with open(yaml_path, "r") as fh: + with open(yaml_path, encoding="utf-8") as fh: return yaml.safe_load(fh) @@ -287,14 +284,11 @@ def load_csv_file(config_parametre_name): csv_file = current_app.config.get(config_parametre_name, "") if not csv_file: logger.error( - "The path to the CSV file isn't defined in the " "main configuration file" + "The path to the CSV file isn't defined in the main configuration file" ) return {} if not os.path.isfile(csv_file): - logger.error( - "Unable to read the config, file: " - "[{0:s}] does not exist".format(csv_file) - ) + logger.error("Unable to read the config, file: [%s] does not exist", csv_file) return {} return pd.read_csv(csv_file) diff --git a/timesketch/app.py b/timesketch/app.py index 9a43d4b222..f7afacd403 100644 --- a/timesketch/app.py +++ b/timesketch/app.py @@ -13,34 +13,39 @@ # limitations under the License. """Entry point for the application.""" -from __future__ import unicode_literals import logging import os import sys +from typing import Optional, Union + -import six -from celery import Celery from flask import Flask -from flask_login import LoginManager, login_required +from celery import Celery + +from flask_login import LoginManager +from flask_login import login_required from flask_migrate import Migrate from flask_restful import Api from flask_wtf import CSRFProtect from timesketch.api.v1.routes import API_ROUTES as V1_API_ROUTES from timesketch.lib.errors import ApiHTTPError -from timesketch.models import configure_engine, init_db +from timesketch.models import configure_engine +from timesketch.models import init_db from timesketch.models.user import User from timesketch.views.auth import auth_views from timesketch.views.spa import spa_views -def create_app(config=None): +def create_app(config: Optional[Union[str, object]] = None, legacy_ui: bool = False): """Create the Flask app instance that is used throughout the application. Args: - config: Path to configuration file as a string or an object with config - directives. + config: (str or object, optional) Path to configuration file as a string + or an object with config directives. + legacy_ui: (bool, optional) Temporary flag to indicate to serve the old UI. + TODO: Remove this when the old UI has been removed. Returns: Application object (instance of flask.Flask). @@ -48,6 +53,11 @@ def create_app(config=None): template_folder = "frontend-ng/dist" static_folder = "frontend-ng/dist" + # Serve the old UI. + if legacy_ui: + template_folder = "frontend/dist" + static_folder = "frontend/dist" + app = Flask(__name__, template_folder=template_folder, static_folder=static_folder) if not config: @@ -60,7 +70,7 @@ def create_app(config=None): else: config = legacy_path - if isinstance(config, six.text_type): + if isinstance(config, str): os.environ["TIMESKETCH_SETTINGS"] = config try: app.config.from_envvar("TIMESKETCH_SETTINGS") @@ -70,8 +80,8 @@ def create_app(config=None): "Warning, EMAIL_USER_WHITELIST has been deprecated. " "Please update timesketch.conf." ) - except IOError: - sys.stderr.write("Config file {0} does not exist.\n".format(config)) + except OSError: + sys.stderr.write(f"Config file {config} does not exist.\n") sys.exit() else: app.config.from_object(config) @@ -109,7 +119,7 @@ def create_app(config=None): # Plaso version that we support if app.config["UPLOAD_ENABLED"]: try: - + # pylint: disable=import-outside-toplevel from plaso import __version__ as plaso_version app.config["PLASO_VERSION"] = plaso_version @@ -137,6 +147,7 @@ def create_app(config=None): api_v1.add_resource(*route) # Returns 404 for invalid api routes + # pylint: disable=unused-variable @app.route("/api/v1/") @login_required def handle_invalid_api_route(path): @@ -152,7 +163,7 @@ def handle_invalid_api_route(path): ) # Register error handlers - + # pylint: disable=unused-variable @app.errorhandler(ApiHTTPError) def handle_api_http_error(error): """Error handler for API HTTP errors. @@ -168,7 +179,7 @@ def handle_api_http_error(error): login_manager.login_view = "user_views.login" # This is used by the flask_login extension. - + # pylint: disable=unused-variable @login_manager.user_loader def load_user(user_id): """Based on a user_id (database primary key for a user) this function diff --git a/timesketch/frontend-ng/dist/css/index.c0639a89.css b/timesketch/frontend-ng/dist/css/index.c0639a89.css new file mode 100644 index 0000000000..ad3846dbc0 --- /dev/null +++ b/timesketch/frontend-ng/dist/css/index.c0639a89.css @@ -0,0 +1 @@ +.active[data-v-a080baf6]{background-color:#4285f4;color:#fff}.star[data-v-a080baf6]{background-color:#fee9a8;color:#333}.dimmed[data-v-a080baf6]{opacity:.5}.query-string[data-v-a080baf6]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:150px;word-wrap:break-word;color:var(--font-color-dark)}.query-string-active[data-v-a080baf6]{color:var(--font-color-light)}.button[data-v-5fd1791a]{border:none;background:transparent}.button[disabled][data-v-5fd1791a]{background:transparent}.light[data-v-5922e267]::-webkit-scrollbar{width:10px}.light[data-v-5922e267]::-webkit-scrollbar-thumb{background:#b0b0b0;border-radius:7px}.light[data-v-5922e267]::-webkit-scrollbar-thumb:hover{background:#333}.dark[data-v-5922e267]::-webkit-scrollbar{width:10px}.dark[data-v-5922e267]::-webkit-scrollbar-thumb{background:#3e3e3e;border-radius:7px}.dark[data-v-5922e267]::-webkit-scrollbar-thumb:hover{background:#4e4e4e}.timeline-chip .right[data-v-a4e723d8]{margin-left:auto}.timeline-chip .chip-content[data-v-a4e723d8]{margin:0;padding:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:300px}.v-chip.timeline-chip.failed[data-v-a4e723d8]{cursor:auto}.v-chip.timeline-chip.failed[data-v-a4e723d8]:hover:before{opacity:0}.events-count[data-v-a4e723d8]{font-size:.8em}.disabled[data-v-a4e723d8]{text-decoration:line-through}.timeline-chip .right[data-v-1bcea98a]{margin-left:auto}.timeline-chip .chip-content[data-v-1bcea98a]{margin:0;padding:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:300px}.v-chip.timeline-chip.failed[data-v-1bcea98a]{cursor:auto}.v-chip.timeline-chip.failed[data-v-1bcea98a]:hover:before{opacity:0}.events-count[data-v-1bcea98a]{font-size:.8em}.disabled[data-v-1bcea98a]{text-decoration:line-through}.timeline-chip[data-v-3e509ce6]{display:inline-block}.iconWrapper[data-v-405cbb74]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:absolute}.flexcard,.iconWrapper[data-v-405cbb74]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ts-event-field-container{position:relative;max-width:100%;padding:0!important;display:-moz-flex;display:-webkit-box;display:-ms-flexbox;display:flex;vertical-align:text-bottom!important}.ts-event-field-ellipsis{position:absolute;white-space:nowrap;overflow-y:visible;overflow-x:hidden;text-overflow:ellipsis;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;max-width:100%;min-width:0;width:100%;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);left:0}.ts-event-field-highlight{font-weight:700;color:red}.v-data-table__expanded.v-data-table__expanded__content{-webkit-box-shadow:none!important;box-shadow:none!important}.ts-time-bubble{width:120px;height:25px;border-radius:20px;position:relative;margin:0 0 0 136px;text-align:center;font-size:var(--font-size-small)}.ts-time-bubble-text{font-size:.8em;padding-top:4px}.ts-time-bubble-vertical-line{width:2px;height:15px;margin:0 0 0 194px;background-color:#f5f5f5}.datetime-table-cell{height:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.v-data-table td,th{padding:0 10px 0 0!important}.v-data-table td:last-child,th:last-child{padding:0!important}.v-data-table td:first-child,th:first-child{padding:0 0 0 10px!important}.ts-ai-summary-card{border:1px solid transparent!important;border-radius:8px;background-color:#fafafa;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#fff)),-webkit-gradient(linear,left top,right top,from(#8ab4f8),color-stop(20%,#81c995),color-stop(40%,#f8c665),color-stop(60%,#ec7764),color-stop(80%,#b39ddb),to(#8ab4f8));background-image:linear-gradient(#fff,#fff),linear-gradient(90deg,#8ab4f8,#81c995 20%,#f8c665 40%,#ec7764 60%,#b39ddb 80%,#8ab4f8);background-origin:border-box;background-clip:content-box,border-box;background-size:300% 100%;-webkit-animation:borderBeamIridescent-subtle 6s linear infinite;animation:borderBeamIridescent-subtle 6s linear infinite;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.08);box-shadow:0 2px 5px rgba(0,0,0,.08);display:block;margin-bottom:20px}.v-data-table{display:block}@-webkit-keyframes borderBeamIridescent-subtle{0%{background-position:0 50%}to{background-position:100% 50%}}@keyframes borderBeamIridescent-subtle{0%{background-position:0 50%}to{background-position:100% 50%}}.theme--dark.ts-ai-summary-card{background-color:#1e1e1e;border-color:hsla(0,0%,100%,.12)!important;background-image:-webkit-gradient(linear,left top,left bottom,from(#1e1e1e),to(#1e1e1e)),-webkit-gradient(linear,left top,right top,from(#8ab4f8),color-stop(20%,#81c995),color-stop(40%,#f8c665),color-stop(60%,#ec7764),color-stop(80%,#b39ddb),to(#8ab4f8));background-image:linear-gradient(#1e1e1e,#1e1e1e),linear-gradient(90deg,#8ab4f8,#81c995 20%,#f8c665 40%,#ec7764 60%,#b39ddb 80%,#8ab4f8);-webkit-box-shadow:0 2px 5px hsla(0,0%,100%,.08);box-shadow:0 2px 5px hsla(0,0%,100%,.08);display:block;margin-bottom:20px}.ts-ai-summary-text{white-space:pre-line;word-wrap:break-word;overflow-wrap:anywhere;margin-top:-10px;padding-left:10px;padding-right:10px}.ts-ai-summary-card .v-btn--icon{cursor:pointer}.ts-ai-summary-card .v-btn--icon:hover{opacity:.8}.ts-summary-placeholder-line{height:1em;background-color:#e0e0e0;margin-bottom:.5em;border-radius:4px;width:100%}.ts-summary-placeholder-line.short{width:60%}.ts-summary-placeholder-line.long{width:80%}.shimmer{background:-webkit-gradient(linear,left top,right top,color-stop(8%,#e0e0e0),color-stop(18%,#f0f0f0),color-stop(33%,#e0e0e0));background:linear-gradient(90deg,#e0e0e0 8%,#f0f0f0 18%,#e0e0e0 33%);background-size:800px 100%;-webkit-animation:shimmer-animation 1.5s linear infinite forwards;animation:shimmer-animation 1.5s linear infinite forwards}@-webkit-keyframes shimmer-animation{0%{background-position:-468px 0}to{background-position:468px 0}}@keyframes shimmer-animation{0%{background-position:-468px 0}to{background-position:468px 0}}.ts-event-list-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;gap:20px}::v-deep .no-transition{-webkit-transition:none!important;transition:none!important}.ts-ai-summary-card-title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.ts-ai-summary-title{margin-right:8px;font-weight:400}.ts-ai-summary-subtitle{font-size:.7em;color:grey;vertical-align:middle;display:inline-block}.chip-disabled{text-decoration:line-through;opacity:.5}.chip-operator-label{margin-right:7px;font-size:.7em;cursor:default}.no-scrollbars::-webkit-scrollbar{display:none}.no-scrollbars{-ms-overflow-style:none;scrollbar-width:none}.filter-chip-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:400px}.expanded .timeline-header .v-icon.open-indicator{display:inline}.expanded .timeline-header .v-icon.closed-indicator{display:none}.timeline-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.timeline-header .v-icon.open-indicator{display:none}.editSigmaRule[data-v-9d5365e0]{font-family:monospace;font-size:13px}.truncate-with-ellipsis[data-v-3453ec85]{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.enabled[data-v-3453ec85]{cursor:pointer}.icon{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.header{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.custom-placeholder-light-theme ::-webkit-input-placeholder{opacity:.7;color:#1976d2!important}.custom-placeholder-light-theme ::-moz-placeholder{opacity:.7;color:#1976d2!important}.custom-placeholder-light-theme :-ms-input-placeholder{opacity:.7;color:#1976d2!important}.custom-placeholder-light-theme ::-ms-input-placeholder{opacity:.7;color:#1976d2!important}.custom-placeholder-light-theme ::placeholder{opacity:.7;color:#1976d2!important}.custom-placeholder-light-theme label{opacity:1;color:#1976d2!important}.custom-placeholder-light-theme input{color:#1976d2!important}.custom-placeholder-dark-theme ::-webkit-input-placeholder{opacity:.7;color:#fff!important}.custom-placeholder-dark-theme ::-moz-placeholder{opacity:.7;color:#fff!important}.custom-placeholder-dark-theme :-ms-input-placeholder{opacity:.7;color:#fff!important}.custom-placeholder-dark-theme ::-ms-input-placeholder{opacity:.7;color:#fff!important}.custom-placeholder-dark-theme ::placeholder{opacity:.7;color:#fff!important}.custom-placeholder-dark-theme label{opacity:1;color:#fff!important}.truncate-with-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.context-card-light-grey-background{background-color:#fafafa!important}.context-card-light-blue-background{background-color:#e3eef9!important}.context-card-dark-blue-background{background-color:rgba(0,67,99,.3764705882352941)!important}.textfield-light-background{background-color:#fff!important}.btn-gradient{background:radial-gradient(circle at 100% 0,#a0d9f2,#a7d9f5,#add9f7,#b3dafa,#b9dafb,#bfdafd,#c5dbfe,#cadbff)}.skeleton-gradient{color:radial-gradient(circle at 100% 0,#a0d9f2,#a7d9f5,#add9f7,#b3dafa,#b9dafb,#bfdafd,#c5dbfe,#cadbff)}.markdown-body{-webkit-box-sizing:border-box;box-sizing:border-box;min-width:200px;max-width:980px;margin:0 auto}.hidden{visibility:hidden}.theme--dark.v-application code,.theme--light.v-application code{background-color:transparent!important}.timeline-chip .chip-content[data-v-20923ce0]{margin:0;padding:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:300px}.timeline-chip .timeline-name-ellipsis[data-v-20923ce0]{width:300px}.v-text-field--enclosed .v-input__append-inner[data-v-c1388c6c]{margin-top:auto!important;margin-bottom:auto!important}.chart-options-trigger{display:-webkit-box;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.v-text-field[data-v-08f08855] input,.v-text-field[data-v-08f08855] label,.v-text-field[data-v-d76a8c36] input,.v-text-field[data-v-d76a8c36] label{font-size:.9em}.SigmaRuleTitle[data-v-1c6cc184]{cursor:pointer;font-size:.9em}.v-text-field[data-v-16a86a92] input,.v-text-field[data-v-16a86a92] label{font-size:.9em}.v-text-field>.v-input__control>.v-input__slot:after,.v-text-field>.v-input__control>.v-input__slot:before{border-style:none}.dark-bg[data-v-595e8247]{background-color:#303030}.light-bg[data-v-595e8247]{background-color:#f6f6f6}.borderless td[data-v-595e8247]{border:none!important}.v-progress-circular[data-v-69ba5af1]{font-size:12px}.chip-content[data-v-3fb0c4da]{-webkit-box-flex:1;-ms-flex:1;flex:1;margin:0;padding-left:10px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:340px}.timeline-name.disabled[data-v-3fb0c4da]{text-decoration:line-through}.right[data-v-3fb0c4da]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;margin-left:auto;max-width:50%}.timeline-name-ellipsis[data-v-3fb0c4da]{width:50%}html{overflow-y:auto}.tree{color:#333;list-style:none}.tree,.tree *{margin:0;padding:0}.tree li{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-top:.5vh;padding-bottom:.5vh;position:relative;padding-left:1vw}.tree li:before{top:50%;border-top:1px solid #d4d4d4;width:1vw}.tree li:after,.tree li:before{content:"";position:absolute;left:0}.tree li:after{border-left:1px solid #d4d4d4}.tree li:only-child:after{border-left:0}.tree li:last-of-type:after{height:50%;top:0}.tree li:first-of-type:after{height:50%;bottom:0}.tree li:not(:first-of-type):not(:last-of-type):after,.tree ol:not(:first-of-type):not(:last-of-type):after,.tree ul:not(:first-of-type):not(:last-of-type):after{height:100%}.tree ol,.tree ul{padding-left:1vw;position:relative}.tree ol:before,.tree ul:before{content:"";position:absolute;left:0;top:50%;border-top:1px solid #d4d4d4;width:1vw}.tree span{background-color:#ddd;text-align:center;padding:.33em .66em;border-radius:4px;cursor:pointer;min-width:100px}.tree>li{padding-left:0}.tree>li:after,.tree>li:before{display:none}.menu-with-gap{margin-top:10px}.search-dropdown{margin-top:15px}.light-font{color:#333}.dark-font{color:#fff}.light-hover:hover{background-color:#f5f5f5}.dark-hover:hover{background-color:#303030}.light-hover-on-highlight:hover{background-color:#e6e6e6}.dark-hover-on-highlight:hover{background-color:#393838}.light-highlight{background-color:#f5f5f5}.light-highlight-selected{background-color:#e6e6e6}.dark-highlight{background-color:#303030}.dark-highlight-selected{background-color:#383838}.light-info-card{background-color:#e7f4fe;color:#333;border-radius:6px}.dark-info-card{background-color:#131f29;color:#fff;border-radius:6px;border:1px solid #174366}.light-info-accordion{background-color:#e7f4fe;color:#333}.dark-info-accordion{background-color:#131f29;color:#fff}.timeline-name-ellipsis{width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.theme--dark.v-navigation-drawer{background-color:#1e1e1e}.theme--dark.v-data-table tbody tr:hover:not(.v-data-table__expanded__content){background:#303030!important}.v-card--link:before{background:none}.notransition{-webkit-transition:none!important;transition:none!important}[data-theme=dark]{color-scheme:dark;--color-prettylights-syntax-comment:#8b949e;--color-prettylights-syntax-constant:#79c0ff;--color-prettylights-syntax-entity:#d2a8ff;--color-prettylights-syntax-storage-modifier-import:#c9d1d9;--color-prettylights-syntax-entity-tag:#7ee787;--color-prettylights-syntax-keyword:#ff7b72;--color-prettylights-syntax-string:#a5d6ff;--color-prettylights-syntax-variable:#ffa657;--color-prettylights-syntax-brackethighlighter-unmatched:#f85149;--color-prettylights-syntax-invalid-illegal-text:#f0f6fc;--color-prettylights-syntax-invalid-illegal-bg:#8e1519;--color-prettylights-syntax-carriage-return-text:#f0f6fc;--color-prettylights-syntax-carriage-return-bg:#b62324;--color-prettylights-syntax-string-regexp:#7ee787;--color-prettylights-syntax-markup-list:#f2cc60;--color-prettylights-syntax-markup-heading:#1f6feb;--color-prettylights-syntax-markup-italic:#c9d1d9;--color-prettylights-syntax-markup-bold:#c9d1d9;--color-prettylights-syntax-markup-deleted-text:#ffdcd7;--color-prettylights-syntax-markup-deleted-bg:#67060c;--color-prettylights-syntax-markup-inserted-text:#aff5b4;--color-prettylights-syntax-markup-inserted-bg:#033a16;--color-prettylights-syntax-markup-changed-text:#ffdfb6;--color-prettylights-syntax-markup-changed-bg:#5a1e02;--color-prettylights-syntax-markup-ignored-text:#c9d1d9;--color-prettylights-syntax-markup-ignored-bg:#1158c7;--color-prettylights-syntax-meta-diff-range:#d2a8ff;--color-prettylights-syntax-brackethighlighter-angle:#8b949e;--color-prettylights-syntax-sublimelinter-gutter-mark:#484f58;--color-prettylights-syntax-constant-other-reference-link:#a5d6ff;--color-fg-default:#c9d1d9;--color-fg-muted:#8b949e;--color-fg-subtle:#6e7681;--color-canvas-default:#0d1117;--color-canvas-subtle:#161b22;--color-border-default:#30363d;--color-border-muted:#21262d;--color-neutral-muted:rgba(110,118,129,0.4);--color-accent-fg:#58a6ff;--color-accent-emphasis:#1f6feb;--color-attention-subtle:rgba(187,128,9,0.15);--color-danger-fg:#f85149}[data-theme=light]{color-scheme:light;--color-prettylights-syntax-comment:#6e7781;--color-prettylights-syntax-constant:#0550ae;--color-prettylights-syntax-entity:#8250df;--color-prettylights-syntax-storage-modifier-import:#24292f;--color-prettylights-syntax-entity-tag:#116329;--color-prettylights-syntax-keyword:#cf222e;--color-prettylights-syntax-string:#0a3069;--color-prettylights-syntax-variable:#953800;--color-prettylights-syntax-brackethighlighter-unmatched:#82071e;--color-prettylights-syntax-invalid-illegal-text:#f6f8fa;--color-prettylights-syntax-invalid-illegal-bg:#82071e;--color-prettylights-syntax-carriage-return-text:#f6f8fa;--color-prettylights-syntax-carriage-return-bg:#cf222e;--color-prettylights-syntax-string-regexp:#116329;--color-prettylights-syntax-markup-list:#3b2300;--color-prettylights-syntax-markup-heading:#0550ae;--color-prettylights-syntax-markup-italic:#24292f;--color-prettylights-syntax-markup-bold:#24292f;--color-prettylights-syntax-markup-deleted-text:#82071e;--color-prettylights-syntax-markup-deleted-bg:#ffebe9;--color-prettylights-syntax-markup-inserted-text:#116329;--color-prettylights-syntax-markup-inserted-bg:#dafbe1;--color-prettylights-syntax-markup-changed-text:#953800;--color-prettylights-syntax-markup-changed-bg:#ffd8b5;--color-prettylights-syntax-markup-ignored-text:#eaeef2;--color-prettylights-syntax-markup-ignored-bg:#0550ae;--color-prettylights-syntax-meta-diff-range:#8250df;--color-prettylights-syntax-brackethighlighter-angle:#57606a;--color-prettylights-syntax-sublimelinter-gutter-mark:#8c959f;--color-prettylights-syntax-constant-other-reference-link:#0a3069;--color-fg-default:#24292f;--color-fg-muted:#57606a;--color-fg-subtle:#6e7781;--color-canvas-default:#fff;--color-canvas-subtle:#f6f8fa;--color-border-default:#d0d7de;--color-border-muted:#d8dee4;--color-neutral-muted:rgba(175,184,193,0.2);--color-accent-fg:#0969da;--color-accent-emphasis:#0969da;--color-attention-subtle:#fff8c5;--color-danger-fg:#cf222e}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;margin:0;color:var(--color-fg-default);background-color:var(--color-canvas-default);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Noto Sans,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body details,.markdown-body figcaption,.markdown-body figure{display:block}.markdown-body summary{display:list-item}.markdown-body [hidden]{display:none!important}.markdown-body a{background-color:transparent;color:var(--color-accent-fg);text-decoration:none}.markdown-body abbr[title]{border-bottom:none;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.markdown-body b,.markdown-body strong{font-weight:var(--base-text-weight-semibold,600)}.markdown-body dfn{font-style:italic}.markdown-body h1{margin:.67em 0;font-weight:var(--base-text-weight-semibold,600);padding-bottom:.3em;font-size:2em;border-bottom:1px solid var(--color-border-muted)}.markdown-body mark{background-color:var(--color-attention-subtle);color:var(--color-fg-default)}.markdown-body small{font-size:90%}.markdown-body sub,.markdown-body sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.markdown-body sub{bottom:-.25em}.markdown-body sup{top:-.5em}.markdown-body img{border-style:none;max-width:100%;-webkit-box-sizing:content-box;box-sizing:content-box;background-color:var(--color-canvas-default)}.markdown-body code,.markdown-body kbd,.markdown-body pre,.markdown-body samp{font-family:monospace;font-size:1em}.markdown-body figure{margin:1em 40px}.markdown-body hr{-webkit-box-sizing:content-box;box-sizing:content-box;overflow:hidden;background:transparent;border-bottom:1px solid var(--color-border-muted);height:.25em;padding:0;margin:24px 0;background-color:var(--color-border-default);border:0}.markdown-body input{font:inherit;margin:0;overflow:visible;font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body [type=button],.markdown-body [type=reset],.markdown-body [type=submit]{-webkit-appearance:button}.markdown-body [type=checkbox],.markdown-body [type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}.markdown-body [type=number]::-webkit-inner-spin-button,.markdown-body [type=number]::-webkit-outer-spin-button{height:auto}.markdown-body [type=search]::-webkit-search-cancel-button,.markdown-body [type=search]::-webkit-search-decoration{-webkit-appearance:none}.markdown-body ::-webkit-input-placeholder{color:inherit;opacity:.54}.markdown-body ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.markdown-body a:hover{text-decoration:underline}.markdown-body ::-webkit-input-placeholder{color:var(--color-fg-subtle);opacity:1}.markdown-body ::-moz-placeholder{color:var(--color-fg-subtle);opacity:1}.markdown-body :-ms-input-placeholder{color:var(--color-fg-subtle);opacity:1}.markdown-body ::-ms-input-placeholder{color:var(--color-fg-subtle);opacity:1}.markdown-body ::placeholder{color:var(--color-fg-subtle);opacity:1}.markdown-body hr:after,.markdown-body hr:before{display:table;content:""}.markdown-body hr:after{clear:both}.markdown-body table{border-spacing:0;border-collapse:collapse;display:block;width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;overflow:auto}.markdown-body td,.markdown-body th{padding:0}.markdown-body details summary{cursor:pointer}.markdown-body details:not([open])>:not(summary){display:none!important}.markdown-body [role=button]:focus,.markdown-body a:focus,.markdown-body input[type=checkbox]:focus,.markdown-body input[type=radio]:focus{outline:2px solid var(--color-accent-fg);outline-offset:-2px;-webkit-box-shadow:none;box-shadow:none}.markdown-body [role=button]:focus:not(:focus-visible),.markdown-body a:focus:not(:focus-visible),.markdown-body input[type=checkbox]:focus:not(:focus-visible),.markdown-body input[type=radio]:focus:not(:focus-visible){outline:1px solid transparent}.markdown-body [role=button]:focus-visible,.markdown-body a:focus-visible,.markdown-body input[type=checkbox]:focus-visible,.markdown-body input[type=radio]:focus-visible{outline:2px solid var(--color-accent-fg);outline-offset:-2px;-webkit-box-shadow:none;box-shadow:none}.markdown-body a:not([class]):focus,.markdown-body a:not([class]):focus-visible,.markdown-body input[type=checkbox]:focus,.markdown-body input[type=checkbox]:focus-visible,.markdown-body input[type=radio]:focus,.markdown-body input[type=radio]:focus-visible{outline-offset:0}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;line-height:10px;color:var(--color-fg-default);vertical-align:middle;background-color:var(--color-canvas-subtle);border:solid 1px var(--color-neutral-muted);border-bottom-color:var(--color-neutral-muted);border-radius:6px;-webkit-box-shadow:inset 0 -1px 0 var(--color-neutral-muted);box-shadow:inset 0 -1px 0 var(--color-neutral-muted)}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:var(--base-text-weight-semibold,600);line-height:1.25}.markdown-body h2{padding-bottom:.3em;font-size:1.5em;border-bottom:1px solid var(--color-border-muted)}.markdown-body h2,.markdown-body h3{font-weight:var(--base-text-weight-semibold,600)}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h4,.markdown-body h5{font-weight:var(--base-text-weight-semibold,600)}.markdown-body h5{font-size:.875em}.markdown-body h6{font-weight:var(--base-text-weight-semibold,600);font-size:.85em;color:var(--color-fg-muted)}.markdown-body p{margin-top:0;margin-bottom:10px}.markdown-body blockquote{margin:0;padding:0 1em;color:var(--color-fg-muted);border-left:.25em solid var(--color-border-default)}.markdown-body ol,.markdown-body ul{margin-top:0;margin-bottom:0;padding-left:2em}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code,.markdown-body pre,.markdown-body samp,.markdown-body tt{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0;word-wrap:normal}.markdown-body input::-webkit-inner-spin-button,.markdown-body input::-webkit-outer-spin-button{margin:0;-webkit-appearance:none;appearance:none}.markdown-body:after,.markdown-body:before{display:table;content:""}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .absent{color:var(--color-danger-fg)}.markdown-body .anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:none}.markdown-body blockquote,.markdown-body details,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1 code,.markdown-body h1 tt,.markdown-body h2 code,.markdown-body h2 tt,.markdown-body h3 code,.markdown-body h3 tt,.markdown-body h4 code,.markdown-body h4 tt,.markdown-body h5 code,.markdown-body h5 tt,.markdown-body h6 code,.markdown-body h6 tt{padding:0 .2em;font-size:inherit}.markdown-body summary h1,.markdown-body summary h2,.markdown-body summary h3,.markdown-body summary h4,.markdown-body summary h5,.markdown-body summary h6{display:inline-block}.markdown-body summary h1 .anchor,.markdown-body summary h2 .anchor,.markdown-body summary h3 .anchor,.markdown-body summary h4 .anchor,.markdown-body summary h5 .anchor,.markdown-body summary h6 .anchor{margin-left:-40px}.markdown-body summary h1,.markdown-body summary h2{padding-bottom:0;border-bottom:0}.markdown-body ol.no-list,.markdown-body ul.no-list{padding:0;list-style-type:none}.markdown-body ol[type=a]{list-style-type:lower-alpha}.markdown-body ol[type=A]{list-style-type:upper-alpha}.markdown-body ol[type=i]{list-style-type:lower-roman}.markdown-body ol[type=I]{list-style-type:upper-roman}.markdown-body div>ol:not([type]),.markdown-body ol[type="1"]{list-style-type:decimal}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:var(--base-text-weight-semibold,600)}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table th{font-weight:var(--base-text-weight-semibold,600)}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid var(--color-border-default)}.markdown-body table tr{background-color:var(--color-canvas-default);border-top:1px solid var(--color-border-muted)}.markdown-body table tr:nth-child(2n){background-color:var(--color-canvas-subtle)}.markdown-body table img{background-color:transparent}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body .emoji{max-width:none;vertical-align:text-top;background-color:transparent}.markdown-body span.frame{display:block;overflow:hidden}.markdown-body span.frame>span{display:block;float:left;width:auto;padding:7px;margin:13px 0 0;overflow:hidden;border:1px solid var(--color-border-default)}.markdown-body span.frame span img{display:block;float:left}.markdown-body span.frame span span{display:block;padding:5px 0 0;clear:both;color:var(--color-fg-default)}.markdown-body span.align-center{display:block;overflow:hidden;clear:both}.markdown-body span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown-body span.align-center span img{margin:0 auto;text-align:center}.markdown-body span.align-right{display:block;overflow:hidden;clear:both}.markdown-body span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown-body span.align-right span img{margin:0;text-align:right}.markdown-body span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown-body span.float-left span{margin:13px 0 0}.markdown-body span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown-body span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown-body code,.markdown-body tt{padding:.2em .4em;margin:0;font-size:85%;white-space:break-spaces;background-color:var(--color-neutral-muted);border-radius:6px}.markdown-body code br,.markdown-body tt br{display:none}.markdown-body del code{text-decoration:inherit}.markdown-body samp{font-size:85%}.markdown-body pre code{font-size:100%}.markdown-body pre>code{padding:0;margin:0;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:var(--color-canvas-subtle);border-radius:6px}.markdown-body pre code,.markdown-body pre tt{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body .csv-data td,.markdown-body .csv-data th{padding:5px;overflow:hidden;font-size:12px;line-height:1;text-align:left;white-space:nowrap}.markdown-body .csv-data .blob-num{padding:10px 8px 9px;text-align:right;background:var(--color-canvas-default);border:0}.markdown-body .csv-data tr{border-top:0}.markdown-body .csv-data th{font-weight:var(--base-text-weight-semibold,600);background:var(--color-canvas-subtle);border-top:0}.markdown-body [data-footnote-ref]:before{content:"["}.markdown-body [data-footnote-ref]:after{content:"]"}.markdown-body .footnotes{font-size:12px;color:var(--color-fg-muted);border-top:1px solid var(--color-border-default)}.markdown-body .footnotes ol{padding-left:16px}.markdown-body .footnotes ol ul{display:inline-block;padding-left:16px;margin-top:16px}.markdown-body .footnotes li{position:relative}.markdown-body .footnotes li:target:before{position:absolute;top:-8px;right:-8px;bottom:-8px;left:-24px;pointer-events:none;content:"";border:2px solid var(--color-accent-emphasis);border-radius:6px}.markdown-body .footnotes li:target{color:var(--color-fg-default)}.markdown-body .pl-c{color:var(--color-prettylights-syntax-comment)}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:var(--color-prettylights-syntax-constant)}.markdown-body .pl-e,.markdown-body .pl-en{color:var(--color-prettylights-syntax-entity)}.markdown-body .pl-s .pl-s1,.markdown-body .pl-smi{color:var(--color-prettylights-syntax-storage-modifier-import)}.markdown-body .pl-ent{color:var(--color-prettylights-syntax-entity-tag)}.markdown-body .pl-k{color:var(--color-prettylights-syntax-keyword)}.markdown-body .pl-pds,.markdown-body .pl-s,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre{color:var(--color-prettylights-syntax-string)}.markdown-body .pl-smw,.markdown-body .pl-v{color:var(--color-prettylights-syntax-variable)}.markdown-body .pl-bu{color:var(--color-prettylights-syntax-brackethighlighter-unmatched)}.markdown-body .pl-ii{color:var(--color-prettylights-syntax-invalid-illegal-text);background-color:var(--color-prettylights-syntax-invalid-illegal-bg)}.markdown-body .pl-c2{color:var(--color-prettylights-syntax-carriage-return-text);background-color:var(--color-prettylights-syntax-carriage-return-bg)}.markdown-body .pl-sr .pl-cce{font-weight:700;color:var(--color-prettylights-syntax-string-regexp)}.markdown-body .pl-ml{color:var(--color-prettylights-syntax-markup-list)}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{font-weight:700;color:var(--color-prettylights-syntax-markup-heading)}.markdown-body .pl-mi{font-style:italic;color:var(--color-prettylights-syntax-markup-italic)}.markdown-body .pl-mb{font-weight:700;color:var(--color-prettylights-syntax-markup-bold)}.markdown-body .pl-md{color:var(--color-prettylights-syntax-markup-deleted-text);background-color:var(--color-prettylights-syntax-markup-deleted-bg)}.markdown-body .pl-mi1{color:var(--color-prettylights-syntax-markup-inserted-text);background-color:var(--color-prettylights-syntax-markup-inserted-bg)}.markdown-body .pl-mc{color:var(--color-prettylights-syntax-markup-changed-text);background-color:var(--color-prettylights-syntax-markup-changed-bg)}.markdown-body .pl-mi2{color:var(--color-prettylights-syntax-markup-ignored-text);background-color:var(--color-prettylights-syntax-markup-ignored-bg)}.markdown-body .pl-mdr{font-weight:700;color:var(--color-prettylights-syntax-meta-diff-range)}.markdown-body .pl-ba{color:var(--color-prettylights-syntax-brackethighlighter-angle)}.markdown-body .pl-sg{color:var(--color-prettylights-syntax-sublimelinter-gutter-mark)}.markdown-body .pl-corl{text-decoration:underline;color:var(--color-prettylights-syntax-constant-other-reference-link)}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item label{font-weight:var(--base-text-weight-normal,400)}.markdown-body .task-list-item.enabled label{cursor:pointer}.markdown-body .task-list-item+.task-list-item{margin-top:4px}.markdown-body .task-list-item .handle{display:none}.markdown-body .task-list-item-checkbox{margin:0 .2em .25em -1.4em;vertical-align:middle}.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox{margin:0 -1.6em .25em .2em}.markdown-body .contains-task-list{position:relative}.markdown-body .contains-task-list:focus-within .task-list-item-convert-container,.markdown-body .contains-task-list:hover .task-list-item-convert-container{display:block;width:auto;height:24px;overflow:visible;clip:auto}.markdown-body ::-webkit-calendar-picker-indicator{-webkit-filter:invert(50%);filter:invert(50%)} \ No newline at end of file diff --git a/timesketch/frontend-ng/dist/index.html b/timesketch/frontend-ng/dist/index.html index 0e583374c4..f04281a21f 100644 --- a/timesketch/frontend-ng/dist/index.html +++ b/timesketch/frontend-ng/dist/index.html @@ -1 +1 @@ -Timesketch
\ No newline at end of file +Timesketch
\ No newline at end of file diff --git a/timesketch/frontend-ng/dist/js/chunk-vendors.87bc6782.js b/timesketch/frontend-ng/dist/js/chunk-vendors.87bc6782.js new file mode 100644 index 0000000000..c88cdd3fad --- /dev/null +++ b/timesketch/frontend-ng/dist/js/chunk-vendors.87bc6782.js @@ -0,0 +1,1987 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-vendors"],{"004e":function(t,e,n){var r=n("76e9"),i=n("8d20"),a=n("cd9d");function o(t){return t&&t.length?r(t,a,i):void 0}t.exports=o},"00fd":function(t,e,n){var r=n("9e69"),i=Object.prototype,a=i.hasOwnProperty,o=i.toString,s=r?r.toStringTag:void 0;function l(t){var e=a.call(t,s),n=t[s];try{t[s]=void 0;var r=!0}catch(l){}var i=o.call(t);return r&&(e?t[s]=n:delete t[s]),i}t.exports=l},"014b":function(t,e,n){"use strict";var r=n("e53d"),i=n("07e3"),a=n("8e60"),o=n("63b6"),s=n("9138"),l=n("ebfd").KEY,c=n("294c"),u=n("dbdb"),h=n("45f2"),d=n("62a0"),f=n("5168"),p=n("ccb9"),v=n("6718"),g=n("47ee"),m=n("9003"),y=n("e4ae"),b=n("f772"),x=n("241e"),w=n("36c3"),k=n("1bc3"),S=n("aebd"),C=n("a159"),A=n("0395"),_=n("bf0b"),D=n("9aa9"),T=n("d9f6"),E=n("c3a1"),O=_.f,P=T.f,I=A.f,M=r.Symbol,V=r.JSON,L=V&&V.stringify,j="prototype",B=f("_hidden"),R=f("toPrimitive"),F={}.propertyIsEnumerable,N=u("symbol-registry"),z=u("symbols"),$=u("op-symbols"),Y=Object[j],H="function"==typeof M&&!!D.f,W=r.QObject,X=!W||!W[j]||!W[j].findChild,G=a&&c((function(){return 7!=C(P({},"a",{get:function(){return P(this,"a",{value:7}).a}})).a}))?function(t,e,n){var r=O(Y,e);r&&delete Y[e],P(t,e,n),r&&t!==Y&&P(Y,e,r)}:P,U=function(t){var e=z[t]=C(M[j]);return e._k=t,e},q=H&&"symbol"==typeof M.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof M},Z=function(t,e,n){return t===Y&&Z($,e,n),y(t),e=k(e,!0),y(n),i(z,e)?(n.enumerable?(i(t,B)&&t[B][e]&&(t[B][e]=!1),n=C(n,{enumerable:S(0,!1)})):(i(t,B)||P(t,B,S(1,{})),t[B][e]=!0),G(t,e,n)):P(t,e,n)},K=function(t,e){y(t);var n,r=g(e=w(e)),i=0,a=r.length;while(a>i)Z(t,n=r[i++],e[n]);return t},J=function(t,e){return void 0===e?C(t):K(C(t),e)},Q=function(t){var e=F.call(this,t=k(t,!0));return!(this===Y&&i(z,t)&&!i($,t))&&(!(e||!i(this,t)||!i(z,t)||i(this,B)&&this[B][t])||e)},tt=function(t,e){if(t=w(t),e=k(e,!0),t!==Y||!i(z,e)||i($,e)){var n=O(t,e);return!n||!i(z,e)||i(t,B)&&t[B][e]||(n.enumerable=!0),n}},et=function(t){var e,n=I(w(t)),r=[],a=0;while(n.length>a)i(z,e=n[a++])||e==B||e==l||r.push(e);return r},nt=function(t){var e,n=t===Y,r=I(n?$:w(t)),a=[],o=0;while(r.length>o)!i(z,e=r[o++])||n&&!i(Y,e)||a.push(z[e]);return a};H||(M=function(){if(this instanceof M)throw TypeError("Symbol is not a constructor!");var t=d(arguments.length>0?arguments[0]:void 0),e=function(n){this===Y&&e.call($,n),i(this,B)&&i(this[B],t)&&(this[B][t]=!1),G(this,t,S(1,n))};return a&&X&&G(Y,t,{configurable:!0,set:e}),U(t)},s(M[j],"toString",(function(){return this._k})),_.f=tt,T.f=Z,n("6abf").f=A.f=et,n("355d").f=Q,D.f=nt,a&&!n("b8e3")&&s(Y,"propertyIsEnumerable",Q,!0),p.f=function(t){return U(f(t))}),o(o.G+o.W+o.F*!H,{Symbol:M});for(var rt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),it=0;rt.length>it;)f(rt[it++]);for(var at=E(f.store),ot=0;at.length>ot;)v(at[ot++]);o(o.S+o.F*!H,"Symbol",{for:function(t){return i(N,t+="")?N[t]:N[t]=M(t)},keyFor:function(t){if(!q(t))throw TypeError(t+" is not a symbol!");for(var e in N)if(N[e]===t)return e},useSetter:function(){X=!0},useSimple:function(){X=!1}}),o(o.S+o.F*!H,"Object",{create:J,defineProperty:Z,defineProperties:K,getOwnPropertyDescriptor:tt,getOwnPropertyNames:et,getOwnPropertySymbols:nt});var st=c((function(){D.f(1)}));o(o.S+o.F*st,"Object",{getOwnPropertySymbols:function(t){return D.f(x(t))}}),V&&o(o.S+o.F*(!H||c((function(){var t=M();return"[null]"!=L([t])||"{}"!=L({a:t})||"{}"!=L(Object(t))}))),"JSON",{stringify:function(t){var e,n,r=[t],i=1;while(arguments.length>i)r.push(arguments[i++]);if(n=e=r[1],(b(e)||void 0!==t)&&!q(t))return m(e)||(e=function(t,e){if("function"==typeof n&&(e=n.call(this,t,e)),!q(e))return e}),r[1]=e,L.apply(V,r)}}),M[j][R]||n("35e8")(M[j],R,M[j].valueOf),h(M,"Symbol"),h(Math,"Math",!0),h(r.JSON,"JSON",!0)},"01ce":function(t,e,n){t.exports={Graph:n("9671"),version:n("c3cd")}},"01eb":function(t,e,n){var r=n("33de");function i(){this._arr=[],this._keyIndices={}}t.exports=i,i.prototype.size=function(){return this._arr.length},i.prototype.keys=function(){return this._arr.map((function(t){return t.key}))},i.prototype.has=function(t){return r.has(this._keyIndices,t)},i.prototype.priority=function(t){var e=this._keyIndices[t];if(void 0!==e)return this._arr[e].priority},i.prototype.min=function(){if(0===this.size())throw new Error("Queue underflow");return this._arr[0].key},i.prototype.add=function(t,e){var n=this._keyIndices;if(t=String(t),!r.has(n,t)){var i=this._arr,a=i.length;return n[t]=a,i.push({key:t,priority:e}),this._decrease(a),!0}return!1},i.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var t=this._arr.pop();return delete this._keyIndices[t.key],this._heapify(0),t.key},i.prototype.decrease=function(t,e){var n=this._keyIndices[t];if(e>this._arr[n].priority)throw new Error("New priority is greater than current priority. Key: "+t+" Old: "+this._arr[n].priority+" New: "+e);this._arr[n].priority=e,this._decrease(n)},i.prototype._heapify=function(t){var e=this._arr,n=2*t,r=n+1,i=t;n>1,n[e].priority=c?t?"":void 0:(a=s.charCodeAt(l),a<55296||a>56319||l+1===c||(o=s.charCodeAt(l+1))<56320||o>57343?t?s.charAt(l):a:t?s.slice(l,l+2):o-56320+(a-55296<<10)+65536)}}},"0390":function(t,e,n){"use strict";var r=n("02f4")(!0);t.exports=function(t,e,n){return e+(n?r(t,e).length:1)}},"0395":function(t,e,n){var r=n("36c3"),i=n("6abf").f,a={}.toString,o="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return i(t)}catch(e){return o.slice()}};t.exports.f=function(t){return o&&"[object Window]"==a.call(t)?s(t):i(r(t))}},"03dd":function(t,e,n){var r=n("eac5"),i=n("57a5"),a=Object.prototype,o=a.hasOwnProperty;function s(t){if(!r(t))return i(t);var e=[];for(var n in Object(t))o.call(t,n)&&"constructor"!=n&&e.push(n);return e}t.exports=s},"0621":function(t,e,n){var r=n("9e69"),i=n("d370"),a=n("6747"),o=r?r.isConcatSpreadable:void 0;function s(t){return a(t)||i(t)||!!(o&&t&&t[o])}t.exports=s},"0644":function(t,e,n){var r=n("3818"),i=1,a=4;function o(t){return r(t,i|a)}t.exports=o},"07c7":function(t,e){function n(){return!1}t.exports=n},"07e3":function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},"087d":function(t,e){function n(t,e){var n=-1,r=e.length,i=t.length;while(++nw;w++)if((d||w in y)&&(v=y[w],g=b(v,w,m),t))if(n)k[w]=g;else if(g)switch(t){case 3:return!0;case 5:return v;case 6:return w;case 2:k.push(v)}else if(u)return!1;return h?-1:c||u?u:k}}},"0b07":function(t,e,n){var r=n("34ac"),i=n("3698");function a(t,e){var n=i(t,e);return r(n)?n:void 0}t.exports=a},"0b8b":function(t,e,n){"use strict";var r=n("e849"),i=r.longestPath,a=n("1845"),o=n("74e8");function s(t){switch(t.graph().ranker){case"network-simplex":u(t);break;case"tight-tree":c(t);break;case"longest-path":l(t);break;default:u(t)}}t.exports=s;var l=i;function c(t){i(t),a(t)}function u(t){o(t)}},"0bfb":function(t,e,n){"use strict";var r=n("cb7c");t.exports=function(){var t=r(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},"0d24":function(t,e,n){(function(t){var r=n("2b3e"),i=n("07c7"),a=e&&!e.nodeType&&e,o=a&&"object"==typeof t&&t&&!t.nodeType&&t,s=o&&o.exports===a,l=s?r.Buffer:void 0,c=l?l.isBuffer:void 0,u=c||i;t.exports=u}).call(this,n("62e4")(t))},"0d58":function(t,e,n){var r=n("ce10"),i=n("e11e");t.exports=Object.keys||function(t){return r(t,i)}},"0ecf":function(t,e,n){!function(e,n){t.exports=n()}(0,(function(){"use strict";var t="minute",e=/[+-]\d\d(?::?\d\d)?/g,n=/([+-]|\d\d)/g;return function(r,i,a){var o=i.prototype;a.utc=function(t){var e={date:t,utc:!0,args:arguments};return new i(e)},o.utc=function(e){var n=a(this.toDate(),{locale:this.$L,utc:!0});return e?n.add(this.utcOffset(),t):n},o.local=function(){return a(this.toDate(),{locale:this.$L,utc:!1})};var s=o.parse;o.parse=function(t){t.utc&&(this.$u=!0),this.$utils().u(t.$offset)||(this.$offset=t.$offset),s.call(this,t)};var l=o.init;o.init=function(){if(this.$u){var t=this.$d;this.$y=t.getUTCFullYear(),this.$M=t.getUTCMonth(),this.$D=t.getUTCDate(),this.$W=t.getUTCDay(),this.$H=t.getUTCHours(),this.$m=t.getUTCMinutes(),this.$s=t.getUTCSeconds(),this.$ms=t.getUTCMilliseconds()}else l.call(this)};var c=o.utcOffset;o.utcOffset=function(r,i){var a=this.$utils().u;if(a(r))return this.$u?0:a(this.$offset)?c.call(this):this.$offset;if("string"==typeof r&&(r=function(t){void 0===t&&(t="");var r=t.match(e);if(!r)return null;var i=(""+r[0]).match(n)||["-",0,0],a=i[0],o=60*+i[1]+ +i[2];return 0===o?0:"+"===a?o:-o}(r),null===r))return this;var o=Math.abs(r)<=16?60*r:r,s=this;if(i)return s.$offset=o,s.$u=0===r,s;if(0!==r){var l=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();(s=this.local().add(o+l,t)).$offset=o,s.$x.$localOffset=l}else s=this.utc();return s};var u=o.format;o.format=function(t){var e=t||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return u.call(this,e)},o.valueOf=function(){var t=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*t},o.isUTC=function(){return!!this.$u},o.toISOString=function(){return this.toDate().toISOString()},o.toString=function(){return this.toDate().toUTCString()};var h=o.toDate;o.toDate=function(t){return"s"===t&&this.$offset?a(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():h.call(this)};var d=o.diff;o.diff=function(t,e,n){if(t&&this.$u===t.$u)return d.call(this,t,e,n);var r=this.local(),i=a(t).local();return d.call(r,i,e,n)}}}))},"0f0f":function(t,e,n){var r=n("8eeb"),i=n("9934");function a(t,e){return t&&r(e,i(e),t)}t.exports=a},"0fc9":function(t,e,n){var r=n("3a38"),i=Math.max,a=Math.min;t.exports=function(t,e){return t=r(t),t<0?i(t+e,0):a(t,e)}},"100e":function(t,e,n){var r=n("cd9d"),i=n("2286"),a=n("c1c9");function o(t,e){return a(i(t,e,r),t+"")}t.exports=o},1041:function(t,e,n){var r=n("8eeb"),i=n("a029");function a(t,e){return r(t,i(t),e)}t.exports=a},1169:function(t,e,n){var r=n("2d95");t.exports=Array.isArray||function(t){return"Array"==r(t)}},1173:function(t,e){t.exports=function(t,e,n,r){if(!(t instanceof e)||void 0!==r&&r in t)throw TypeError(n+": incorrect invocation!");return t}},"11e9":function(t,e,n){var r=n("52a7"),i=n("4630"),a=n("6821"),o=n("6a99"),s=n("69a8"),l=n("c69a"),c=Object.getOwnPropertyDescriptor;e.f=n("9e1e")?c:function(t,e){if(t=a(t),e=o(e,!0),l)try{return c(t,e)}catch(n){}if(s(t,e))return i(!r.f.call(t,e),t[e])}},1290:function(t,e){function n(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t}t.exports=n},1304:function(t,e,n){var r=n("cd9d");function i(t){return"function"==typeof t?t:r}t.exports=i},1310:function(t,e){function n(t){return null!=t&&"object"==typeof t}t.exports=n},1321:function(t,e,n){(function(e,r){t.exports=r(n("3d1e"))})(0,(function(t){"use strict";function e(t){return e="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},e(t)}function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}t=t&&t.hasOwnProperty("default")?t["default"]:t;var r={props:{options:{type:Object},type:{type:String},series:{type:Array,required:!0,default:function(){return[]}},width:{default:"100%"},height:{default:"auto"}},data:function(){return{chart:null}},beforeMount:function(){window.ApexCharts=t},mounted:function(){this.init()},created:function(){var t=this;this.$watch("options",(function(e){!t.chart&&e?t.init():t.chart.updateOptions(t.options)})),this.$watch("series",(function(e){!t.chart&&e?t.init():t.chart.updateSeries(t.series)}));var e=["type","width","height"];e.forEach((function(e){t.$watch(e,(function(){t.refresh()}))}))},beforeDestroy:function(){this.chart&&this.destroy()},render:function(t){return t("div")},methods:{init:function(){var e=this,n={chart:{type:this.type||this.options.chart.type||"line",height:this.height,width:this.width,events:{}},series:this.series};Object.keys(this.$listeners).forEach((function(t){n.chart.events[t]=e.$listeners[t]}));var r=this.extend(this.options,n);return this.chart=new t(this.$el,r),this.chart.render()},isObject:function(t){return t&&"object"===e(t)&&!Array.isArray(t)&&null!=t},extend:function(t,e){var r=this;"function"!==typeof Object.assign&&function(){Object.assign=function(t){if(void 0===t||null===t)throw new TypeError("Cannot convert undefined or null to object");for(var e=Object(t),n=1;nl)r.f(t,n=o[l++],e[n]);return t}},"159a":function(t,e,n){var r=n("32b3"),i=n("e2e4"),a=n("c098"),o=n("1a8c"),s=n("f4d6");function l(t,e,n,l){if(!o(t))return t;e=i(e,t);var c=-1,u=e.length,h=u-1,d=t;while(null!=d&&++c=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})}))},1691:function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},"17d5":function(t,e,n){var r;try{r=n("e008")}catch(i){}r||(r=window.graphlib),t.exports=r},1838:function(t,e,n){var r=n("c05f"),i=n("9b02"),a=n("8604"),o=n("f608"),s=n("08cc"),l=n("20ec"),c=n("f4d6"),u=1,h=2;function d(t,e){return o(t)&&s(e)?l(c(t),e):function(n){var o=i(n,t);return void 0===o&&o===e?a(n,t):r(e,o,u|h)}}t.exports=d},1845:function(t,e,n){"use strict";var r=n("6f9c"),i=n("17d5").Graph,a=n("e849").slack;function o(t){var e,n,r=new i({directed:!1}),o=t.nodes()[0],u=t.nodeCount();r.setNode(o,{});while(s(r,t)n)e.push(arguments[n++]);return m[++g]=function(){s("function"==typeof t?t:Function(t),e)},r(g),g},f=function(t){delete m[t]},"process"==n("2d95")(h)?r=function(t){h.nextTick(o(b,t,1))}:v&&v.now?r=function(t){v.now(o(b,t,1))}:p?(i=new p,a=i.port2,i.port1.onmessage=x,r=o(a.postMessage,a,1)):u.addEventListener&&"function"==typeof postMessage&&!u.importScripts?(r=function(t){u.postMessage(t+"","*")},u.addEventListener("message",x,!1)):r=y in c("script")?function(t){l.appendChild(c("script"))[y]=function(){l.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),t.exports={set:d,clear:f}},"19b2":function(t,e,n){var r=n("33de"),i=n("9671");function a(t){var e={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:o(t),edges:s(t)};return r.isUndefined(t.graph())||(e.value=r.clone(t.graph())),e}function o(t){return r.map(t.nodes(),(function(e){var n=t.node(e),i=t.parent(e),a={v:e};return r.isUndefined(n)||(a.value=n),r.isUndefined(i)||(a.parent=i),a}))}function s(t){return r.map(t.edges(),(function(e){var n=t.edge(e),i={v:e.v,w:e.w};return r.isUndefined(e.name)||(i.name=e.name),r.isUndefined(n)||(i.value=n),i}))}function l(t){var e=new i(t.options).setGraph(t.value);return r.each(t.nodes,(function(t){e.setNode(t.v,t.value),t.parent&&e.setParent(t.v,t.parent)})),r.each(t.edges,(function(t){e.setEdge({v:t.v,w:t.w,name:t.name},t.value)})),e}t.exports={write:a,read:l}},"1a2d":function(t,e,n){var r=n("42a2"),i=n("1310"),a="[object Map]";function o(t){return i(t)&&r(t)==a}t.exports=o},"1a8c":function(t,e){function n(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}t.exports=n},"1af6":function(t,e,n){var r=n("63b6");r(r.S,"Array",{isArray:n("9003")})},"1bac":function(t,e,n){var r=n("7d1f"),i=n("a029"),a=n("9934");function o(t){return r(t,a,i)}t.exports=o},"1bc3":function(t,e,n){var r=n("f772");t.exports=function(t,e){if(!r(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!r(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},"1c3c":function(t,e,n){var r=n("9e69"),i=n("2474"),a=n("9638"),o=n("a2be"),s=n("edfa"),l=n("ac41"),c=1,u=2,h="[object Boolean]",d="[object Date]",f="[object Error]",p="[object Map]",v="[object Number]",g="[object RegExp]",m="[object Set]",y="[object String]",b="[object Symbol]",x="[object ArrayBuffer]",w="[object DataView]",k=r?r.prototype:void 0,S=k?k.valueOf:void 0;function C(t,e,n,r,k,C,A){switch(n){case w:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case x:return!(t.byteLength!=e.byteLength||!C(new i(t),new i(e)));case h:case d:case v:return a(+t,+e);case f:return t.name==e.name&&t.message==e.message;case g:case y:return t==e+"";case p:var _=s;case m:var D=r&c;if(_||(_=l),t.size!=e.size&&!D)return!1;var T=A.get(t);if(T)return T==e;r|=u,A.set(t,e);var E=o(_(t),_(e),r,k,C,A);return A["delete"](t),E;case b:if(S)return S.call(t)==S.call(e)}return!1}t.exports=C},"1c4c":function(t,e,n){"use strict";var r=n("9b43"),i=n("5ca1"),a=n("4bf8"),o=n("1fa8"),s=n("33a4"),l=n("9def"),c=n("f1ae"),u=n("27ee");i(i.S+i.F*!n("5cc5")((function(t){Array.from(t)})),"Array",{from:function(t){var e,n,i,h,d=a(t),f="function"==typeof this?this:Array,p=arguments.length,v=p>1?arguments[1]:void 0,g=void 0!==v,m=0,y=u(d);if(g&&(v=r(v,p>2?arguments[2]:void 0,2)),void 0==y||f==Array&&s(y))for(e=l(d.length),n=new f(e);e>m;m++)c(n,m,g?v(d[m],m):d[m]);else for(h=y.call(d),n=new f;!(i=h.next()).done;m++)c(n,m,g?o(h,v,[i.value,m],!0):i.value);return n.length=m,n}})},"1cba":function(t,e,n){var r=n("4796"),i=n("9aff"),a=n("6428");function o(t){return function(e,n,o){return o&&"number"!=typeof o&&i(e,n,o)&&(n=o=void 0),e=a(e),void 0===n?(n=e,e=0):n=a(n),o=void 0===o?e0)throw new Error("Invalid string. Length must be a multiple of 4");var n=t.indexOf("=");-1===n&&(n=e);var r=n===e?0:4-n%4;return[n,r]}function u(t){var e=c(t),n=e[0],r=e[1];return 3*(n+r)/4-r}function h(t,e,n){return 3*(e+n)/4-n}function d(t){var e,n,r=c(t),o=r[0],s=r[1],l=new a(h(t,o,s)),u=0,d=s>0?o-4:o;for(n=0;n>16&255,l[u++]=e>>8&255,l[u++]=255&e;return 2===s&&(e=i[t.charCodeAt(n)]<<2|i[t.charCodeAt(n+1)]>>4,l[u++]=255&e),1===s&&(e=i[t.charCodeAt(n)]<<10|i[t.charCodeAt(n+1)]<<4|i[t.charCodeAt(n+2)]>>2,l[u++]=e>>8&255,l[u++]=255&e),l}function f(t){return r[t>>18&63]+r[t>>12&63]+r[t>>6&63]+r[63&t]}function p(t,e,n){for(var r,i=[],a=e;al?l:s+o));return 1===i?(e=t[n-1],a.push(r[e>>2]+r[e<<4&63]+"==")):2===i&&(e=(t[n-2]<<8)+t[n-1],a.push(r[e>>10]+r[e>>4&63]+r[e<<2&63]+"=")),a.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},"1fc8":function(t,e,n){var r=n("4245");function i(t,e){var n=r(this,t),i=n.size;return n.set(t,e),this.size+=n.size==i?0:1,this}t.exports=i},"20d6":function(t,e,n){"use strict";var r=n("5ca1"),i=n("0a49")(6),a="findIndex",o=!0;a in[]&&Array(1)[a]((function(){o=!1})),r(r.P+r.F*o,"Array",{findIndex:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),n("9c6c")(a)},"20ec":function(t,e){function n(t,e){return function(n){return null!=n&&(n[t]===e&&(void 0!==e||t in Object(n)))}}t.exports=n},"20fd":function(t,e,n){"use strict";var r=n("d9f6"),i=n("aebd");t.exports=function(t,e,n){e in t?r.f(t,e,i(0,n)):t[e]=n}},"214f":function(t,e,n){"use strict";n("b0c5");var r=n("2aba"),i=n("32e9"),a=n("79e5"),o=n("be13"),s=n("2b4c"),l=n("520a"),c=s("species"),u=!a((function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")})),h=function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var n="ab".split(t);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();t.exports=function(t,e,n){var d=s(t),f=!a((function(){var e={};return e[d]=function(){return 7},7!=""[t](e)})),p=f?!a((function(){var e=!1,n=/a/;return n.exec=function(){return e=!0,null},"split"===t&&(n.constructor={},n.constructor[c]=function(){return n}),n[d](""),!e})):void 0;if(!f||!p||"replace"===t&&!u||"split"===t&&!h){var v=/./[d],g=n(o,d,""[t],(function(t,e,n,r,i){return e.exec===l?f&&!i?{done:!0,value:v.call(e,n,r)}:{done:!0,value:t.call(n,e,r)}:{done:!1}})),m=g[0],y=g[1];r(String.prototype,t,m),i(RegExp.prototype,d,2==e?function(t,e){return y.call(t,this,e)}:function(t){return y.call(t,this)})}}},2164:function(t,e,n){var r=n("cae7");function i(t,e,n){var i=-1,a=t.criteria,o=e.criteria,s=a.length,l=n.length;while(++i=l)return c;var u=n[i];return c*("desc"==u?-1:1)}}return t.index-e.index}t.exports=i},"220e":function(t,e,n){var r=n("6f9c"),i=n("b50e");function a(t){function e(n){var i=t.children(n),a=t.node(n);if(i.length&&r.forEach(i,e),r.has(a,"minRank")){a.borderLeft=[],a.borderRight=[];for(var s=a.minRank,l=a.maxRank+1;sa)o(n[a++]);t._c=[],t._n=!1,e&&!t._h&&L(t)}))}},L=function(t){m.call(l,(function(){var e,n,r,i=t._v,a=j(t);if(a&&(e=x((function(){E?A.emit("unhandledRejection",i,t):(n=l.onunhandledrejection)?n({promise:t,reason:i}):(r=l.console)&&r.error&&r.error("Unhandled promise rejection",i)})),t._h=E||j(t)?2:1),t._a=void 0,a&&e.e)throw e.v}))},j=function(t){return 1!==t._h&&0===(t._a||t._c).length},B=function(t){m.call(l,(function(){var e;E?A.emit("rejectionHandled",t):(e=l.onrejectionhandled)&&e({promise:t,reason:t._v})}))},R=function(t){var e=this;e._d||(e._d=!0,e=e._w||e,e._v=t,e._s=2,e._a||(e._a=e._c.slice()),V(e,!0))},F=function(t){var e,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===t)throw C("Promise can't be resolved itself");(e=M(t))?y((function(){var r={_w:n,_d:!1};try{e.call(t,c(F,r,1),c(R,r,1))}catch(i){R.call(r,i)}})):(n._v=t,n._s=1,V(n,!1))}catch(r){R.call({_w:n,_d:!1},r)}}};I||(T=function(t){p(this,T,S,"_h"),f(t),r.call(this);try{t(c(F,this,1),c(R,this,1))}catch(e){R.call(this,e)}},r=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},r.prototype=n("5c95")(T.prototype,{then:function(t,e){var n=P(g(this,T));return n.ok="function"!=typeof t||t,n.fail="function"==typeof e&&e,n.domain=E?A.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&V(this,!1),n.promise},catch:function(t){return this.then(void 0,t)}}),a=function(){var t=new r;this.promise=t,this.resolve=c(F,t,1),this.reject=c(R,t,1)},b.f=P=function(t){return t===T||t===o?new a(t):i(t)}),h(h.G+h.W+h.F*!I,{Promise:T}),n("45f2")(T,S),n("4c95")(S),o=n("584a")[S],h(h.S+h.F*!I,S,{reject:function(t){var e=P(this),n=e.reject;return n(t),e.promise}}),h(h.S+h.F*(s||!I),S,{resolve:function(t){return k(s&&this===o?T:this,t)}}),h(h.S+h.F*!(I&&n("4ee1")((function(t){T.all(t)["catch"](O)}))),S,{all:function(t){var e=this,n=P(e),r=n.resolve,i=n.reject,a=x((function(){var n=[],a=0,o=1;v(t,!1,(function(t){var s=a++,l=!1;n.push(void 0),o++,e.resolve(t).then((function(t){l||(l=!0,n[s]=t,--o||r(n))}),i)})),--o||r(n)}));return a.e&&i(a.v),n.promise},race:function(t){var e=this,n=P(e),r=n.reject,i=x((function(){v(t,!1,(function(t){e.resolve(t).then(n.resolve,r)}))}));return i.e&&r(i.v),n.promise}})},"251a":function(t,e,n){var r=n("6f9c"),i=n("b50e");function a(t){var e=i.addDummyNode(t,"root",{},"_root"),n=s(t),a=r.max(r.values(n))-1,c=2*a+1;t.graph().nestingRoot=e,r.forEach(t.edges(),(function(e){t.edge(e).minlen*=c}));var u=l(t)+1;r.forEach(t.children(),(function(r){o(t,e,c,u,a,n,r)})),t.graph().nodeRankFactor=c}function o(t,e,n,a,s,l,c){var u=t.children(c);if(u.length){var h=i.addBorderNode(t,"_bt"),d=i.addBorderNode(t,"_bb"),f=t.node(c);t.setParent(h,c),f.borderTop=h,t.setParent(d,c),f.borderBottom=d,r.forEach(u,(function(r){o(t,e,n,a,s,l,r);var i=t.node(r),u=i.borderTop?i.borderTop:r,f=i.borderBottom?i.borderBottom:r,p=i.borderTop?a:2*a,v=u!==f?1:s-l[c]+1;t.setEdge(h,u,{weight:p,minlen:v,nestingEdge:!0}),t.setEdge(f,d,{weight:p,minlen:v,nestingEdge:!0})})),t.parent(c)||t.setEdge(e,h,{weight:0,minlen:s+l[c]})}else c!==e&&t.setEdge(e,c,{weight:0,minlen:n})}function s(t){var e={};function n(i,a){var o=t.children(i);o&&o.length&&r.forEach(o,(function(t){n(t,a+1)})),e[i]=a}return r.forEach(t.children(),(function(t){n(t,1)})),e}function l(t){return r.reduce(t.edges(),(function(e,n){return e+t.edge(n).weight}),0)}function c(t){var e=t.graph();t.removeNode(e.nestingRoot),delete e.nestingRoot,r.forEach(t.edges(),(function(e){var n=t.edge(e);n.nestingEdge&&t.removeEdge(e)}))}t.exports={run:a,cleanup:c}},2524:function(t,e,n){var r=n("6044"),i="__lodash_hash_undefined__";function a(t,e){var n=this.__data__;return this.size+=this.has(t)?0:1,n[t]=r&&void 0===e?i:e,this}t.exports=a},"253c":function(t,e,n){var r=n("3729"),i=n("1310"),a="[object Arguments]";function o(t){return i(t)&&r(t)==a}t.exports=o},2593:function(t,e,n){var r=n("15f3"),i=n("c6cf"),a=i((function(t,e){return null==t?{}:r(t,e)}));t.exports=a},"25eb":function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},2621:function(t,e){e.f=Object.getOwnPropertySymbols},"266a":function(t,e,n){var r=n("7948");function i(t,e){return r(e,(function(e){return t[e]}))}t.exports=i},"26e8":function(t,e){function n(t,e){return null!=t&&e in Object(t)}t.exports=n},2769:function(t,e,n){var r=n("5ca0"),i=n("51f5"),a=r(i);t.exports=a},"27ee":function(t,e,n){var r=n("23c6"),i=n("2b4c")("iterator"),a=n("84f2");t.exports=n("8378").getIteratorMethod=function(t){if(void 0!=t)return t[i]||t["@@iterator"]||a[r(t)]}},2877:function(t,e,n){"use strict";function r(t,e,n,r,i,a,o,s){var l,c="function"===typeof t?t.options:t;if(e&&(c.render=e,c.staticRenderFns=n,c._compiled=!0),r&&(c.functional=!0),a&&(c._scopeId="data-v-"+a),o?(l=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"===typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(o)},c._ssrRegister=l):i&&(l=s?function(){i.call(this,(c.functional?this.parent:this).$root.$options.shadowRoot)}:i),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(t,e){return l.call(e),u(t,e)}}else{var h=c.beforeCreate;c.beforeCreate=h?[].concat(h,l):[l]}return{exports:t,options:c}}n.d(e,"a",(function(){return r}))},"28a5":function(t,e,n){"use strict";var r=n("aae3"),i=n("cb7c"),a=n("ebd6"),o=n("0390"),s=n("9def"),l=n("5f1b"),c=n("520a"),u=n("79e5"),h=Math.min,d=[].push,f="split",p="length",v="lastIndex",g=4294967295,m=!u((function(){RegExp(g,"y")}));n("214f")("split",2,(function(t,e,n,u){var y;return y="c"=="abbc"[f](/(b)*/)[1]||4!="test"[f](/(?:)/,-1)[p]||2!="ab"[f](/(?:ab)*/)[p]||4!="."[f](/(.?)(.?)/)[p]||"."[f](/()()/)[p]>1||""[f](/.?/)[p]?function(t,e){var i=String(this);if(void 0===t&&0===e)return[];if(!r(t))return n.call(i,t,e);var a,o,s,l=[],u=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),h=0,f=void 0===e?g:e>>>0,m=new RegExp(t.source,u+"g");while(a=c.call(m,i)){if(o=m[v],o>h&&(l.push(i.slice(h,a.index)),a[p]>1&&a.index=f))break;m[v]===a.index&&m[v]++}return h===i[p]?!s&&m.test("")||l.push(""):l.push(i.slice(h)),l[p]>f?l.slice(0,f):l}:"0"[f](void 0,0)[p]?function(t,e){return void 0===t&&0===e?[]:n.call(this,t,e)}:n,[function(n,r){var i=t(this),a=void 0==n?void 0:n[e];return void 0!==a?a.call(n,i,r):y.call(String(i),n,r)},function(t,e){var r=u(y,t,this,e,y!==n);if(r.done)return r.value;var c=i(t),d=String(this),f=a(c,RegExp),p=c.unicode,v=(c.ignoreCase?"i":"")+(c.multiline?"m":"")+(c.unicode?"u":"")+(m?"y":"g"),b=new f(m?c:"^(?:"+c.source+")",v),x=void 0===e?g:e>>>0;if(0===x)return[];if(0===d.length)return null===l(b,d)?[d]:[];var w=0,k=0,S=[];while(k0;--s)if(r=e[s].dequeue(),r){i=i.concat(c(t,e,n,r,!0));break}}return i}function c(t,e,n,i,a){var o=a?[]:void 0;return r.forEach(t.inEdges(i.v),(function(r){var i=t.edge(r),s=t.node(r.v);a&&o.push({v:r.v,w:r.w}),s.out-=i,h(e,n,s)})),r.forEach(t.outEdges(i.v),(function(r){var i=t.edge(r),a=r.w,o=t.node(a);o["in"]-=i,h(e,n,o)})),t.removeNode(i.v),o}function u(t,e){var n=new i,o=0,s=0;r.forEach(t.nodes(),(function(t){n.setNode(t,{v:t,in:0,out:0})})),r.forEach(t.edges(),(function(t){var r=n.edge(t.v,t.w)||0,i=e(t),a=r+i;n.setEdge(t.v,t.w,a),s=Math.max(s,n.node(t.v).out+=i),o=Math.max(o,n.node(t.w)["in"]+=i)}));var l=r.range(s+o+3).map((function(){return new a})),c=o+1;return r.forEach(n.nodes(),(function(t){h(l,c,n.node(t))})),{graph:n,buckets:l,zeroIdx:c}}function h(t,e,n){n.out?n["in"]?t[n.out-n["in"]+e].enqueue(n):t[t.length-1].enqueue(n):t[0].enqueue(n)}},"29f3":function(t,e){var n=Object.prototype,r=n.toString;function i(t){return r.call(t)}t.exports=i},"2a9f":function(t,e,n){"use strict";var r=n("6f9c"),i=n("e632"),a=n("d780"),o=n("38e2"),s=n("8817"),l=n("d4f3"),c=n("17d5").Graph,u=n("b50e");function h(t){var e=u.maxRank(t),n=d(t,r.range(1,e+1),"inEdges"),o=d(t,r.range(e-1,-1,-1),"outEdges"),s=i(t);p(t,s);for(var l,c=Number.POSITIVE_INFINITY,h=0,v=0;v<4;++h,++v){f(h%2?n:o,h%4>=2),s=u.buildLayerMatrix(t);var g=a(t,s);g";e.style.display="none",n("fab2").appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(i+"script"+o+"document.F=Object"+i+"/script"+o),t.close(),c=t.F;while(r--)delete c[l][a[r]];return c()};t.exports=Object.create||function(t,e){var n;return null!==t?(s[l]=r(t),n=new s,s[l]=null,n[o]=t):n=c(),void 0===e?n:i(n,e)}},"2b03":function(t,e){function n(t,e,n,r){var i=t.length,a=n+(r?1:-1);while(r?a--:++a=0&&Math.floor(e)===e&&isFinite(t)}function g(t){return o(t)&&"function"===typeof t.then&&"function"===typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||f(t)&&t.toString===d?JSON.stringify(t,y,2):String(t)}function y(t,e){return e&&e.__v_isRef?e.value:e}function b(t){var e=parseFloat(t);return isNaN(e)?t:e}function x(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i-1)return t.splice(r,1)}}var S=Object.prototype.hasOwnProperty;function C(t,e){return S.call(t,e)}function A(t){var e=Object.create(null);return function(n){var r=e[n];return r||(e[n]=t(n))}}var _=/-(\w)/g,D=A((function(t){return t.replace(_,(function(t,e){return e?e.toUpperCase():""}))})),T=A((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),E=/\B([A-Z])/g,O=A((function(t){return t.replace(E,"-$1").toLowerCase()}));function P(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function I(t,e){return t.bind(e)}var M=Function.prototype.bind?I:P;function V(t,e){e=e||0;var n=t.length-e,r=new Array(n);while(n--)r[n]=t[n+e];return r}function L(t,e){for(var n in e)t[n]=e[n];return t}function j(t){for(var e={},n=0;n0,it=et&&et.indexOf("edge/")>0;et&&et.indexOf("android");var at=et&&/iphone|ipad|ipod|ios/.test(et);et&&/chrome\/\d+/.test(et),et&&/phantomjs/.test(et);var ot,st=et&&et.match(/firefox\/(\d+)/),lt={}.watch,ct=!1;if(tt)try{var ut={};Object.defineProperty(ut,"passive",{get:function(){ct=!0}}),window.addEventListener("test-passive",null,ut)}catch(al){}var ht=function(){return void 0===ot&&(ot=!tt&&"undefined"!==typeof t&&(t["process"]&&"server"===t["process"].env.VUE_ENV)),ot},dt=tt&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ft(t){return"function"===typeof t&&/native code/.test(t.toString())}var pt,vt="undefined"!==typeof Symbol&&ft(Symbol)&&"undefined"!==typeof Reflect&&ft(Reflect.ownKeys);pt="undefined"!==typeof Set&&ft(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var gt=null;function mt(){return gt&&{proxy:gt}}function yt(t){void 0===t&&(t=null),t||gt&>._scope.off(),gt=t,t&&t._scope.on()}var bt=function(){function t(t,e,n,r,i,a,o,s){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=i,this.ns=void 0,this.context=a,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=o,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),xt=function(t){void 0===t&&(t="");var e=new bt;return e.text=t,e.isComment=!0,e};function wt(t){return new bt(void 0,void 0,void 0,String(t))}function kt(t){var e=new bt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}"function"===typeof SuppressedError&&SuppressedError;var St=0,Ct=[],At=function(){for(var t=0;t1)return n&&u(e)?e.call(r):e}else 0}var Be=A((function(t){var e="&"===t.charAt(0);t=e?t.slice(1):t;var n="~"===t.charAt(0);t=n?t.slice(1):t;var r="!"===t.charAt(0);return t=r?t.slice(1):t,{name:t,once:n,capture:r,passive:e}}));function Re(t,e){function n(){var t=n.fns;if(!i(t))return zn(t,null,arguments,e,"v-on handler");for(var r=t.slice(),a=0;a0&&(r=Xe(r,"".concat(e||"","_").concat(n)),We(r[0])&&We(u)&&(h[l]=wt(u.text+r[0].text),r.shift()),h.push.apply(h,r)):c(r)?We(u)?h[l]=wt(u.text+r):""!==r&&h.push(wt(r)):We(r)&&We(u)?h[l]=wt(u.text+r.text):(s(t._isVList)&&o(r.tag)&&a(r.key)&&o(e)&&(r.key="__vlist".concat(e,"_").concat(n,"__")),h.push(r)));return h}function Ge(t,e){var n,r,a,s,l=null;if(i(t)||"string"===typeof t)for(l=new Array(t.length),n=0,r=t.length;n0,s=e?!!e.$stable:!o,l=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(s&&i&&i!==r&&l===i.$key&&!o&&!i.$hasNormal)return i;for(var c in a={},e)e[c]&&"$"!==c[0]&&(a[c]=fn(t,n,c,e[c]))}else a={};for(var u in n)u in a||(a[u]=pn(n,u));return e&&Object.isExtensible(e)&&(e._normalized=a),Z(a,"$stable",s),Z(a,"$key",l),Z(a,"$hasNormal",o),a}function fn(t,e,n,r){var a=function(){var e=gt;yt(t);var n=arguments.length?r.apply(null,arguments):r({});n=n&&"object"===typeof n&&!i(n)?[n]:He(n);var a=n&&n[0];return yt(e),n&&(!a||1===n.length&&a.isComment&&!hn(a))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:a,enumerable:!0,configurable:!0}),a}function pn(t,e){return function(){return t[e]}}function vn(t){var e=t.$options,n=e.setup;if(n){var r=t._setupContext=gn(t);yt(t),Tt();var i=zn(n,null,[t._props||Wt({}),r],t,"setup");if(Et(),yt(),u(i))e.render=i;else if(h(i))if(t._setupState=i,i.__sfc){var a=t._setupProxy={};for(var o in i)"__sfc"!==o&&se(a,i,o)}else for(var o in i)q(o)||se(t,i,o);else 0}}function gn(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};Z(e,"_v_attr_proxy",!0),mn(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){if(!t._listenersProxy){var e=t._listenersProxy={};mn(e,t.$listeners,r,t,"$listeners")}return t._listenersProxy},get slots(){return bn(t)},emit:M(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return se(t,e,n)}))}}}function mn(t,e,n,r,i){var a=!1;for(var o in e)o in t?e[o]!==n[o]&&(a=!0):(a=!0,yn(t,o,r,i));for(var o in t)o in e||(a=!0,delete t[o]);return a}function yn(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function bn(t){return t._slotsProxy||xn(t._slotsProxy={},t.$scopedSlots),t._slotsProxy}function xn(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}function wn(){return Cn().slots}function kn(){return Cn().attrs}function Sn(){return Cn().listeners}function Cn(){var t=gt;return t._setupContext||(t._setupContext=gn(t))}function An(t,e){var n=i(t)?t.reduce((function(t,e){return t[e]={},t}),{}):t;for(var r in e){var a=n[r];a?i(a)||u(a)?n[r]={type:a,default:e[r]}:a.default=e[r]:null===a&&(n[r]={default:e[r]})}return n}function _n(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,i=n&&n.context;t.$slots=cn(e._renderChildren,i),t.$scopedSlots=n?dn(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,i){return Ln(t,e,n,r,i,!1)},t.$createElement=function(e,n,r,i){return Ln(t,e,n,r,i,!0)};var a=n&&n.data;Nt(t,"$attrs",a&&a.attrs||r,null,!0),Nt(t,"$listeners",e._parentListeners||r,null,!0)}var Dn=null;function Tn(t){ln(t.prototype),t.prototype.$nextTick=function(t){return Qn(t,this)},t.prototype._render=function(){var t=this,e=t.$options,n=e.render,r=e._parentVnode;r&&t._isMounted&&(t.$scopedSlots=dn(t.$parent,r.data.scopedSlots,t.$slots,t.$scopedSlots),t._slotsProxy&&xn(t._slotsProxy,t.$scopedSlots)),t.$vnode=r;var a,o=gt,s=Dn;try{yt(t),Dn=t,a=n.call(t._renderProxy,t.$createElement)}catch(al){Nn(al,t,"render"),a=t._vnode}finally{Dn=s,yt(o)}return i(a)&&1===a.length&&(a=a[0]),a instanceof bt||(a=xt()),a.parent=r,a}}function En(t,e){return(t.__esModule||vt&&"Module"===t[Symbol.toStringTag])&&(t=t.default),h(t)?e.extend(t):t}function On(t,e,n,r,i){var a=xt();return a.asyncFactory=t,a.asyncMeta={data:e,context:n,children:r,tag:i},a}function Pn(t,e){if(s(t.error)&&o(t.errorComp))return t.errorComp;if(o(t.resolved))return t.resolved;var n=Dn;if(n&&o(t.owners)&&-1===t.owners.indexOf(n)&&t.owners.push(n),s(t.loading)&&o(t.loadingComp))return t.loadingComp;if(n&&!o(t.owners)){var r=t.owners=[n],i=!0,l=null,c=null;n.$on("hook:destroyed",(function(){return k(r,n)}));var u=function(t){for(var e=0,n=r.length;e1?V(n):n;for(var r=V(arguments,1),i='event handler for "'.concat(t,'"'),a=0,o=n.length;adocument.createEvent("Event").timeStamp&&(Zr=function(){return Kr.now()})}var Jr=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function Qr(){var t,e;for(qr=Zr(),Xr=!0,$r.sort(Jr),Gr=0;Gr<$r.length;Gr++)t=$r[Gr],t.before&&t.before(),e=t.id,Hr[e]=null,t.run();var n=Yr.slice(),r=$r.slice();Ur(),ni(n),ti(r),At(),dt&&G.devtools&&dt.emit("flush")}function ti(t){var e=t.length;while(e--){var n=t[e],r=n.vm;r&&r._watcher===n&&r._isMounted&&!r._isDestroyed&&zr(r,"updated")}}function ei(t){t._inactive=!1,Yr.push(t)}function ni(t){for(var e=0;eGr&&$r[n].id>t.id)n--;$r.splice(n+1,0,t)}else $r.push(t);Wr||(Wr=!0,Qn(Qr))}}function ii(t){var e=t.$options.provide;if(e){var n=u(e)?e.call(t):e;if(!h(n))return;for(var r=Le(t),i=vt?Reflect.ownKeys(n):Object.keys(n),a=0;a-1)if(a&&!C(i,"default"))o=!1;else if(""===o||o===O(t)){var l=Bi(String,i.type);(l<0||s-1)return this;var n=V(arguments,1);return n.unshift(this),u(t.install)?t.install.apply(t,n):u(t)&&t.apply(null,n),e.push(t),this}}function oa(t){t.mixin=function(t){return this.options=Oi(this.options,t),this}}function sa(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,i=t._Ctor||(t._Ctor={});if(i[r])return i[r];var a=hi(t)||hi(n.options);var o=function(t){this._init(t)};return o.prototype=Object.create(n.prototype),o.prototype.constructor=o,o.cid=e++,o.options=Oi(n.options,t),o["super"]=n,o.options.props&&la(o),o.options.computed&&ca(o),o.extend=n.extend,o.mixin=n.mixin,o.use=n.use,W.forEach((function(t){o[t]=n[t]})),a&&(o.options.components[a]=o),o.superOptions=n.options,o.extendOptions=t,o.sealedOptions=L({},o.options),i[r]=o,o}}function la(t){var e=t.options.props;for(var n in e)Fi(t.prototype,"_props",n)}function ca(t){var e=t.options.computed;for(var n in e)Xi(t.prototype,n,e[n])}function ua(t){W.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&f(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&u(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}function ha(t){return t&&(hi(t.Ctor.options)||t.tag)}function da(t,e){return i(t)?t.indexOf(e)>-1:"string"===typeof t?t.split(",").indexOf(e)>-1:!!p(t)&&t.test(e)}function fa(t,e){var n=t.cache,r=t.keys,i=t._vnode,a=t.$vnode;for(var o in n){var s=n[o];if(s){var l=s.name;l&&!e(l)&&pa(n,o,r,i)}}a.componentOptions.children=void 0}function pa(t,e,n,r){var i=t[e];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),t[e]=null,k(n,e)}ta(ia),Ji(ia),Pr(ia),Lr(ia),Tn(ia);var va=[String,RegExp,Array],ga={name:"keep-alive",abstract:!0,props:{include:va,exclude:va,max:[String,Number]},methods:{cacheVNode:function(){var t=this,e=t.cache,n=t.keys,r=t.vnodeToCache,i=t.keyToCache;if(r){var a=r.tag,o=r.componentInstance,s=r.componentOptions;e[i]={name:ha(s),tag:a,componentInstance:o},n.push(i),this.max&&n.length>parseInt(this.max)&&pa(e,n[0],n,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)pa(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){fa(t,(function(t){return da(e,t)}))})),this.$watch("exclude",(function(e){fa(t,(function(t){return!da(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=In(t),n=e&&e.componentOptions;if(n){var r=ha(n),i=this,a=i.include,o=i.exclude;if(a&&(!r||!da(a,r))||o&&r&&da(o,r))return e;var s=this,l=s.cache,c=s.keys,u=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;l[u]?(e.componentInstance=l[u].componentInstance,k(c,u),c.push(u)):(this.vnodeToCache=e,this.keyToCache=u),e.data.keepAlive=!0}return e||t&&t[0]}},ma={KeepAlive:ga};function ya(t){var e={get:function(){return G}};Object.defineProperty(t,"config",e),t.util={warn:bi,extend:L,mergeOptions:Oi,defineReactive:Nt},t.set=zt,t.delete=$t,t.nextTick=Qn,t.observable=function(t){return Ft(t),t},t.options=Object.create(null),W.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,L(t.options.components,ma),aa(t),oa(t),sa(t),ua(t)}ya(ia),Object.defineProperty(ia.prototype,"$isServer",{get:ht}),Object.defineProperty(ia.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(ia,"FunctionalRenderContext",{value:si}),ia.version=yr;var ba=x("style,class"),xa=x("input,textarea,option,select,progress"),wa=function(t,e,n){return"value"===n&&xa(t)&&"button"!==e||"selected"===n&&"option"===t||"checked"===n&&"input"===t||"muted"===n&&"video"===t},ka=x("contenteditable,draggable,spellcheck"),Sa=x("events,caret,typing,plaintext-only"),Ca=function(t,e){return Ea(e)||"false"===e?"false":"contenteditable"===t&&Sa(e)?e:"true"},Aa=x("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),_a="http://www.w3.org/1999/xlink",Da=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},Ta=function(t){return Da(t)?t.slice(6,t.length):""},Ea=function(t){return null==t||!1===t};function Oa(t){var e=t.data,n=t,r=t;while(o(r.componentInstance))r=r.componentInstance._vnode,r&&r.data&&(e=Pa(r.data,e));while(o(n=n.parent))n&&n.data&&(e=Pa(e,n.data));return Ia(e.staticClass,e.class)}function Pa(t,e){return{staticClass:Ma(t.staticClass,e.staticClass),class:o(t.class)?[t.class,e.class]:e.class}}function Ia(t,e){return o(t)||o(e)?Ma(t,Va(e)):""}function Ma(t,e){return t?e?t+" "+e:t:e||""}function Va(t){return Array.isArray(t)?La(t):h(t)?ja(t):"string"===typeof t?t:""}function La(t){for(var e,n="",r=0,i=t.length;r-1?$a[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:$a[t]=/HTMLUnknownElement/.test(e.toString())}var Ha=x("text,number,password,search,email,tel,url");function Wa(t){if("string"===typeof t){var e=document.querySelector(t);return e||document.createElement("div")}return t}function Xa(t,e){var n=document.createElement(t);return"select"!==t||e.data&&e.data.attrs&&void 0!==e.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n}function Ga(t,e){return document.createElementNS(Ba[t],e)}function Ua(t){return document.createTextNode(t)}function qa(t){return document.createComment(t)}function Za(t,e,n){t.insertBefore(e,n)}function Ka(t,e){t.removeChild(e)}function Ja(t,e){t.appendChild(e)}function Qa(t){return t.parentNode}function to(t){return t.nextSibling}function eo(t){return t.tagName}function no(t,e){t.textContent=e}function ro(t,e){t.setAttribute(e,"")}var io=Object.freeze({__proto__:null,createElement:Xa,createElementNS:Ga,createTextNode:Ua,createComment:qa,insertBefore:Za,removeChild:Ka,appendChild:Ja,parentNode:Qa,nextSibling:to,tagName:eo,setTextContent:no,setStyleScope:ro}),ao={create:function(t,e){oo(e)},update:function(t,e){t.data.ref!==e.data.ref&&(oo(t,!0),oo(e))},destroy:function(t){oo(t,!0)}};function oo(t,e){var n=t.data.ref;if(o(n)){var r=t.context,a=t.componentInstance||t.elm,s=e?null:a,l=e?void 0:a;if(u(n))zn(n,r,[s],r,"template ref function");else{var c=t.data.refInFor,h="string"===typeof n||"number"===typeof n,d=te(n),f=r.$refs;if(h||d)if(c){var p=h?f[n]:n.value;e?i(p)&&k(p,a):i(p)?p.includes(a)||p.push(a):h?(f[n]=[a],so(r,n,f[n])):n.value=[a]}else if(h){if(e&&f[n]!==a)return;f[n]=l,so(r,n,s)}else if(d){if(e&&n.value!==a)return;n.value=s}else 0}}}function so(t,e,n){var r=t._setupState;r&&C(r,e)&&(te(r[e])?r[e].value=n:r[e]=n)}var lo=new bt("",{},[]),co=["create","activate","update","remove","destroy"];function uo(t,e){return t.key===e.key&&t.asyncFactory===e.asyncFactory&&(t.tag===e.tag&&t.isComment===e.isComment&&o(t.data)===o(e.data)&&ho(t,e)||s(t.isAsyncPlaceholder)&&a(e.asyncFactory.error))}function ho(t,e){if("input"!==t.tag)return!0;var n,r=o(n=t.data)&&o(n=n.attrs)&&n.type,i=o(n=e.data)&&o(n=n.attrs)&&n.type;return r===i||Ha(r)&&Ha(i)}function fo(t,e,n){var r,i,a={};for(r=e;r<=n;++r)i=t[r].key,o(i)&&(a[i]=r);return a}function po(t){var e,n,r={},l=t.modules,u=t.nodeOps;for(e=0;ev?(h=a(n[y+1])?null:n[y+1].elm,C(t,h,n,f,y,r)):f>y&&_(e,d,v)}function E(t,e,n,r){for(var i=n;i-1?Ao(t,e,n):Aa(e)?Ea(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):ka(e)?t.setAttribute(e,Ca(e,n)):Da(e)?Ea(n)?t.removeAttributeNS(_a,Ta(e)):t.setAttributeNS(_a,e,n):Ao(t,e,n)}function Ao(t,e,n){if(Ea(n))t.removeAttribute(e);else{if(nt&&!rt&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var _o={create:So,update:So};function Do(t,e){var n=e.elm,r=e.data,i=t.data;if(!(a(r.staticClass)&&a(r.class)&&(a(i)||a(i.staticClass)&&a(i.class)))){var s=Oa(e),l=n._transitionClasses;o(l)&&(s=Ma(s,Va(l))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var To,Eo={create:Do,update:Do},Oo="__r",Po="__c";function Io(t){if(o(t[Oo])){var e=nt?"change":"input";t[e]=[].concat(t[Oo],t[e]||[]),delete t[Oo]}o(t[Po])&&(t.change=[].concat(t[Po],t.change||[]),delete t[Po])}function Mo(t,e,n){var r=To;return function i(){var a=e.apply(null,arguments);null!==a&&jo(t,i,n,r)}}var Vo=Wn&&!(st&&Number(st[1])<=53);function Lo(t,e,n,r){if(Vo){var i=qr,a=e;e=a._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=i||t.timeStamp<=0||t.target.ownerDocument!==document)return a.apply(this,arguments)}}To.addEventListener(t,e,ct?{capture:n,passive:r}:n)}function jo(t,e,n,r){(r||To).removeEventListener(t,e._wrapper||e,n)}function Bo(t,e){if(!a(t.data.on)||!a(e.data.on)){var n=e.data.on||{},r=t.data.on||{};To=e.elm||t.elm,Io(n),Fe(n,r,Lo,jo,Mo,e.context),To=void 0}}var Ro,Fo={create:Bo,update:Bo,destroy:function(t){return Bo(t,lo)}};function No(t,e){if(!a(t.data.domProps)||!a(e.data.domProps)){var n,r,i=e.elm,l=t.data.domProps||{},c=e.data.domProps||{};for(n in(o(c.__ob__)||s(c._v_attr_proxy))&&(c=e.data.domProps=L({},c)),l)n in c||(i[n]="");for(n in c){if(r=c[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===l[n])continue;1===i.childNodes.length&&i.removeChild(i.childNodes[0])}if("value"===n&&"PROGRESS"!==i.tagName){i._value=r;var u=a(r)?"":String(r);zo(i,u)&&(i.value=u)}else if("innerHTML"===n&&Fa(i.tagName)&&a(i.innerHTML)){Ro=Ro||document.createElement("div"),Ro.innerHTML="".concat(r,"");var h=Ro.firstChild;while(i.firstChild)i.removeChild(i.firstChild);while(h.firstChild)i.appendChild(h.firstChild)}else if(r!==l[n])try{i[n]=r}catch(al){}}}}function zo(t,e){return!t.composing&&("OPTION"===t.tagName||$o(t,e)||Yo(t,e))}function $o(t,e){var n=!0;try{n=document.activeElement!==t}catch(al){}return n&&t.value!==e}function Yo(t,e){var n=t.value,r=t._vModifiers;if(o(r)){if(r.number)return b(n)!==b(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}var Ho={create:No,update:No},Wo=A((function(t){var e={},n=/;(?![^(]*\))/g,r=/:(.+)/;return t.split(n).forEach((function(t){if(t){var n=t.split(r);n.length>1&&(e[n[0].trim()]=n[1].trim())}})),e}));function Xo(t){var e=Go(t.style);return t.staticStyle?L(t.staticStyle,e):e}function Go(t){return Array.isArray(t)?j(t):"string"===typeof t?Wo(t):t}function Uo(t,e){var n,r={};if(e){var i=t;while(i.componentInstance)i=i.componentInstance._vnode,i&&i.data&&(n=Xo(i.data))&&L(r,n)}(n=Xo(t.data))&&L(r,n);var a=t;while(a=a.parent)a.data&&(n=Xo(a.data))&&L(r,n);return r}var qo,Zo=/^--/,Ko=/\s*!important$/,Jo=function(t,e,n){if(Zo.test(e))t.style.setProperty(e,n);else if(Ko.test(n))t.style.setProperty(O(e),n.replace(Ko,""),"important");else{var r=ts(e);if(Array.isArray(n))for(var i=0,a=n.length;i-1?e.split(rs).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function as(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(rs).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";while(n.indexOf(r)>=0)n=n.replace(r," ");n=n.trim(),n?t.setAttribute("class",n):t.removeAttribute("class")}}function os(t){if(t){if("object"===typeof t){var e={};return!1!==t.css&&L(e,ss(t.name||"v")),L(e,t),e}return"string"===typeof t?ss(t):void 0}}var ss=A((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),ls=tt&&!rt,cs="transition",us="animation",hs="transition",ds="transitionend",fs="animation",ps="animationend";ls&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(hs="WebkitTransition",ds="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(fs="WebkitAnimation",ps="webkitAnimationEnd"));var vs=tt?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function gs(t){vs((function(){vs(t)}))}function ms(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),is(t,e))}function ys(t,e){t._transitionClasses&&k(t._transitionClasses,e),as(t,e)}function bs(t,e,n){var r=ws(t,e),i=r.type,a=r.timeout,o=r.propCount;if(!i)return n();var s=i===cs?ds:ps,l=0,c=function(){t.removeEventListener(s,u),n()},u=function(e){e.target===t&&++l>=o&&c()};setTimeout((function(){l0&&(n=cs,u=o,h=a.length):e===us?c>0&&(n=us,u=c,h=l.length):(u=Math.max(o,c),n=u>0?o>c?cs:us:null,h=n?n===cs?a.length:l.length:0);var d=n===cs&&xs.test(r[hs+"Property"]);return{type:n,timeout:u,propCount:h,hasTransform:d}}function ks(t,e){while(t.length1}function Ts(t,e){!0!==e.data.show&&Cs(e)}var Es=tt?{create:Ts,activate:Ts,remove:function(t,e){!0!==t.data.show?As(t,e):e()}}:{},Os=[_o,Eo,Fo,Ho,ns,Es],Ps=Os.concat(ko),Is=po({nodeOps:io,modules:Ps});rt&&document.addEventListener("selectionchange",(function(){var t=document.activeElement;t&&t.vmodel&&Ns(t,"input")}));var Ms={inserted:function(t,e,n,r){"select"===n.tag?(r.elm&&!r.elm._vOptions?Ne(n,"postpatch",(function(){Ms.componentUpdated(t,e,n)})):Vs(t,e,n.context),t._vOptions=[].map.call(t.options,Bs)):("textarea"===n.tag||Ha(t.type))&&(t._vModifiers=e.modifiers,e.modifiers.lazy||(t.addEventListener("compositionstart",Rs),t.addEventListener("compositionend",Fs),t.addEventListener("change",Fs),rt&&(t.vmodel=!0)))},componentUpdated:function(t,e,n){if("select"===n.tag){Vs(t,e,n.context);var r=t._vOptions,i=t._vOptions=[].map.call(t.options,Bs);if(i.some((function(t,e){return!N(t,r[e])}))){var a=t.multiple?e.value.some((function(t){return js(t,i)})):e.value!==e.oldValue&&js(e.value,i);a&&Ns(t,"change")}}}};function Vs(t,e,n){Ls(t,e,n),(nt||it)&&setTimeout((function(){Ls(t,e,n)}),0)}function Ls(t,e,n){var r=e.value,i=t.multiple;if(!i||Array.isArray(r)){for(var a,o,s=0,l=t.options.length;s-1,o.selected!==a&&(o.selected=a);else if(N(Bs(o),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));i||(t.selectedIndex=-1)}}function js(t,e){return e.every((function(e){return!N(e,t)}))}function Bs(t){return"_value"in t?t._value:t.value}function Rs(t){t.target.composing=!0}function Fs(t){t.target.composing&&(t.target.composing=!1,Ns(t.target,"input"))}function Ns(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function zs(t){return!t.componentInstance||t.data&&t.data.transition?t:zs(t.componentInstance._vnode)}var $s={bind:function(t,e,n){var r=e.value;n=zs(n);var i=n.data&&n.data.transition,a=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&i?(n.data.show=!0,Cs(n,(function(){t.style.display=a}))):t.style.display=r?a:"none"},update:function(t,e,n){var r=e.value,i=e.oldValue;if(!r!==!i){n=zs(n);var a=n.data&&n.data.transition;a?(n.data.show=!0,r?Cs(n,(function(){t.style.display=t.__vOriginalDisplay})):As(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none"}},unbind:function(t,e,n,r,i){i||(t.style.display=t.__vOriginalDisplay)}},Ys={model:Ms,show:$s},Hs={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Ws(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ws(In(e.children)):t}function Xs(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var i=n._parentListeners;for(var r in i)e[D(r)]=i[r];return e}function Gs(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}function Us(t){while(t=t.parent)if(t.data.transition)return!0}function qs(t,e){return e.key===t.key&&e.tag===t.tag}var Zs=function(t){return t.tag||hn(t)},Ks=function(t){return"show"===t.name},Js={name:"transition",props:Hs,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Zs),n.length)){0;var r=this.mode;0;var i=n[0];if(Us(this.$vnode))return i;var a=Ws(i);if(!a)return i;if(this._leaving)return Gs(t,i);var o="__transition-".concat(this._uid,"-");a.key=null==a.key?a.isComment?o+"comment":o+a.tag:c(a.key)?0===String(a.key).indexOf(o)?a.key:o+a.key:a.key;var s=(a.data||(a.data={})).transition=Xs(this),l=this._vnode,u=Ws(l);if(a.data.directives&&a.data.directives.some(Ks)&&(a.data.show=!0),u&&u.data&&!qs(a,u)&&!hn(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var h=u.data.transition=L({},s);if("out-in"===r)return this._leaving=!0,Ne(h,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Gs(t,i);if("in-out"===r){if(hn(a))return l;var d,f=function(){d()};Ne(s,"afterEnter",f),Ne(s,"enterCancelled",f),Ne(h,"delayLeave",(function(t){d=t}))}}return i}}},Qs=L({tag:String,moveClass:String},Hs);delete Qs.mode;var tl={props:Qs,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var i=Mr(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,i(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,i=this.$slots.default||[],a=this.children=[],o=Xs(this),s=0;s=c){var g=e?null:s(t);if(g)return l(g);f=!1,h=o,v=new r}else v=e?[]:p;t:while(++u>>0,r=0;r0)for(n=0;n0?"future":"past"];return V(n)?n(e):n.replace(/%s/i,e)}var Z={};function K(t,e){var n=t.toLowerCase();Z[n]=Z[n+"s"]=Z[e]=t}function J(t){return"string"===typeof t?Z[t]||Z[t.toLowerCase()]:void 0}function Q(t){var e,n,r={};for(n in t)p(t,n)&&(e=J(n),e&&(r[e]=t[n]));return r}var tt={};function et(t,e){tt[t]=e}function nt(t){var e=[];for(var n in t)e.push({unit:n,priority:tt[n]});return e.sort((function(t,e){return t.priority-e.priority})),e}function rt(t,e,n){var r=""+Math.abs(t),i=e-r.length,a=t>=0;return(a?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+r}var it=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,at=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,ot={},st={};function lt(t,e,n,r){var i=r;"string"===typeof r&&(i=function(){return this[r]()}),t&&(st[t]=i),e&&(st[e[0]]=function(){return rt(i.apply(this,arguments),e[1],e[2])}),n&&(st[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),t)})}function ct(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function ut(t){var e,n,r=t.match(it);for(e=0,n=r.length;e=0&&at.test(t))t=t.replace(at,r),at.lastIndex=0,n-=1;return t}var ft=/\d/,pt=/\d\d/,vt=/\d{3}/,gt=/\d{4}/,mt=/[+-]?\d{6}/,yt=/\d\d?/,bt=/\d\d\d\d?/,xt=/\d\d\d\d\d\d?/,wt=/\d{1,3}/,kt=/\d{1,4}/,St=/[+-]?\d{1,6}/,Ct=/\d+/,At=/[+-]?\d+/,_t=/Z|[+-]\d\d:?\d\d/gi,Dt=/Z|[+-]\d\d(?::?\d\d)?/gi,Tt=/[+-]?\d+(\.\d{1,3})?/,Et=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,Ot={};function Pt(t,e,n){Ot[t]=V(e)?e:function(t,r){return t&&n?n:e}}function It(t,e){return p(Ot,t)?Ot[t](e._strict,e._locale):new RegExp(Mt(t))}function Mt(t){return Vt(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(t,e,n,r,i){return e||n||r||i})))}function Vt(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var Lt={};function jt(t,e){var n,r=e;for("string"===typeof t&&(t=[t]),h(e)&&(r=function(t,n){n[e]=D(t)}),n=0;n68?1900:2e3)};var Zt,Kt=Qt("FullYear",!0);function Jt(){return qt(this.year())}function Qt(t,e){return function(n){return null!=n?(ee(this,t,n),a.updateOffset(this,e),this):te(this,t)}}function te(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function ee(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&qt(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),ae(n,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](n))}function ne(t){return t=J(t),V(this[t])?this[t]():this}function re(t,e){if("object"===("undefined"===typeof t?"undefined":i(t))){t=Q(t);for(var n=nt(t),r=0;r=0?(s=new Date(t+400,e,n,r,i,a,o),isFinite(s.getFullYear())&&s.setFullYear(t)):s=new Date(t,e,n,r,i,a,o),s}function ke(t){var e;if(t<100&&t>=0){var n=Array.prototype.slice.call(arguments);n[0]=t+400,e=new Date(Date.UTC.apply(null,n)),isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t)}else e=new Date(Date.UTC.apply(null,arguments));return e}function Se(t,e,n){var r=7+e-n,i=(7+ke(t,0,r).getUTCDay()-e)%7;return-i+r-1}function Ce(t,e,n,r,i){var a,o,s=(7+n-r)%7,l=Se(t,r,i),c=1+7*(e-1)+s+l;return c<=0?(a=t-1,o=Ut(a)+c):c>Ut(t)?(a=t+1,o=c-Ut(t)):(a=t,o=c),{year:a,dayOfYear:o}}function Ae(t,e,n){var r,i,a=Se(t.year(),e,n),o=Math.floor((t.dayOfYear()-a-1)/7)+1;return o<1?(i=t.year()-1,r=o+_e(i,e,n)):o>_e(t.year(),e,n)?(r=o-_e(t.year(),e,n),i=t.year()+1):(i=t.year(),r=o),{week:r,year:i}}function _e(t,e,n){var r=Se(t,e,n),i=Se(t+1,e,n);return(Ut(t)-r+i)/7}function De(t){return Ae(t,this._week.dow,this._week.doy).week}lt("w",["ww",2],"wo","week"),lt("W",["WW",2],"Wo","isoWeek"),K("week","w"),K("isoWeek","W"),et("week",5),et("isoWeek",5),Pt("w",yt),Pt("ww",yt,pt),Pt("W",yt),Pt("WW",yt,pt),Bt(["w","ww","W","WW"],(function(t,e,n,r){e[r.substr(0,1)]=D(t)}));var Te={dow:0,doy:6};function Ee(){return this._week.dow}function Oe(){return this._week.doy}function Pe(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")}function Ie(t){var e=Ae(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")}function Me(t,e){return"string"!==typeof t?t:isNaN(t)?(t=e.weekdaysParse(t),"number"===typeof t?t:null):parseInt(t,10)}function Ve(t,e){return"string"===typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}function Le(t,e){return t.slice(e,7).concat(t.slice(0,e))}lt("d",0,"do","day"),lt("dd",0,0,(function(t){return this.localeData().weekdaysMin(this,t)})),lt("ddd",0,0,(function(t){return this.localeData().weekdaysShort(this,t)})),lt("dddd",0,0,(function(t){return this.localeData().weekdays(this,t)})),lt("e",0,0,"weekday"),lt("E",0,0,"isoWeekday"),K("day","d"),K("weekday","e"),K("isoWeekday","E"),et("day",11),et("weekday",11),et("isoWeekday",11),Pt("d",yt),Pt("e",yt),Pt("E",yt),Pt("dd",(function(t,e){return e.weekdaysMinRegex(t)})),Pt("ddd",(function(t,e){return e.weekdaysShortRegex(t)})),Pt("dddd",(function(t,e){return e.weekdaysRegex(t)})),Bt(["dd","ddd","dddd"],(function(t,e,n,r){var i=n._locale.weekdaysParse(t,r,n._strict);null!=i?e.d=i:y(n).invalidWeekday=t})),Bt(["d","e","E"],(function(t,e,n,r){e[r]=D(t)}));var je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");function Be(t,e){var n=s(this._weekdays)?this._weekdays:this._weekdays[t&&!0!==t&&this._weekdays.isFormat.test(e)?"format":"standalone"];return!0===t?Le(n,this._week.dow):t?n[t.day()]:n}var Re="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");function Fe(t){return!0===t?Le(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort}var Ne="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function ze(t){return!0===t?Le(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin}function $e(t,e,n){var r,i,a,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],r=0;r<7;++r)a=g([2e3,1]).day(r),this._minWeekdaysParse[r]=this.weekdaysMin(a,"").toLocaleLowerCase(),this._shortWeekdaysParse[r]=this.weekdaysShort(a,"").toLocaleLowerCase(),this._weekdaysParse[r]=this.weekdays(a,"").toLocaleLowerCase();return n?"dddd"===e?(i=Zt.call(this._weekdaysParse,o),-1!==i?i:null):"ddd"===e?(i=Zt.call(this._shortWeekdaysParse,o),-1!==i?i:null):(i=Zt.call(this._minWeekdaysParse,o),-1!==i?i:null):"dddd"===e?(i=Zt.call(this._weekdaysParse,o),-1!==i?i:(i=Zt.call(this._shortWeekdaysParse,o),-1!==i?i:(i=Zt.call(this._minWeekdaysParse,o),-1!==i?i:null))):"ddd"===e?(i=Zt.call(this._shortWeekdaysParse,o),-1!==i?i:(i=Zt.call(this._weekdaysParse,o),-1!==i?i:(i=Zt.call(this._minWeekdaysParse,o),-1!==i?i:null))):(i=Zt.call(this._minWeekdaysParse,o),-1!==i?i:(i=Zt.call(this._weekdaysParse,o),-1!==i?i:(i=Zt.call(this._shortWeekdaysParse,o),-1!==i?i:null)))}function Ye(t,e,n){var r,i,a;if(this._weekdaysParseExact)return $e.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),r=0;r<7;r++){if(i=g([2e3,1]).day(r),n&&!this._fullWeekdaysParse[r]&&(this._fullWeekdaysParse[r]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[r]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[r]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[r]||(a="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[r]=new RegExp(a.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[r].test(t))return r;if(n&&"ddd"===e&&this._shortWeekdaysParse[r].test(t))return r;if(n&&"dd"===e&&this._minWeekdaysParse[r].test(t))return r;if(!n&&this._weekdaysParse[r].test(t))return r}}function He(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=Me(t,this.localeData()),this.add(t-e,"d")):e}function We(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")}function Xe(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=Ve(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7}var Ge=Et;function Ue(t){return this._weekdaysParseExact?(p(this,"_weekdaysRegex")||Qe.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(p(this,"_weekdaysRegex")||(this._weekdaysRegex=Ge),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)}var qe=Et;function Ze(t){return this._weekdaysParseExact?(p(this,"_weekdaysRegex")||Qe.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(p(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=qe),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}var Ke=Et;function Je(t){return this._weekdaysParseExact?(p(this,"_weekdaysRegex")||Qe.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(p(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ke),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Qe(){function t(t,e){return e.length-t.length}var e,n,r,i,a,o=[],s=[],l=[],c=[];for(e=0;e<7;e++)n=g([2e3,1]).day(e),r=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(r),s.push(i),l.push(a),c.push(r),c.push(i),c.push(a);for(o.sort(t),s.sort(t),l.sort(t),c.sort(t),e=0;e<7;e++)s[e]=Vt(s[e]),l[e]=Vt(l[e]),c[e]=Vt(c[e]);this._weekdaysRegex=new RegExp("^("+c.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function tn(){return this.hours()%12||12}function en(){return this.hours()||24}function nn(t,e){lt(t,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)}))}function rn(t,e){return e._meridiemParse}function an(t){return"p"===(t+"").toLowerCase().charAt(0)}lt("H",["HH",2],0,"hour"),lt("h",["hh",2],0,tn),lt("k",["kk",2],0,en),lt("hmm",0,0,(function(){return""+tn.apply(this)+rt(this.minutes(),2)})),lt("hmmss",0,0,(function(){return""+tn.apply(this)+rt(this.minutes(),2)+rt(this.seconds(),2)})),lt("Hmm",0,0,(function(){return""+this.hours()+rt(this.minutes(),2)})),lt("Hmmss",0,0,(function(){return""+this.hours()+rt(this.minutes(),2)+rt(this.seconds(),2)})),nn("a",!0),nn("A",!1),K("hour","h"),et("hour",13),Pt("a",rn),Pt("A",rn),Pt("H",yt),Pt("h",yt),Pt("k",yt),Pt("HH",yt,pt),Pt("hh",yt,pt),Pt("kk",yt,pt),Pt("hmm",bt),Pt("hmmss",xt),Pt("Hmm",bt),Pt("Hmmss",xt),jt(["H","HH"],$t),jt(["k","kk"],(function(t,e,n){var r=D(t);e[$t]=24===r?0:r})),jt(["a","A"],(function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t})),jt(["h","hh"],(function(t,e,n){e[$t]=D(t),y(n).bigHour=!0})),jt("hmm",(function(t,e,n){var r=t.length-2;e[$t]=D(t.substr(0,r)),e[Yt]=D(t.substr(r)),y(n).bigHour=!0})),jt("hmmss",(function(t,e,n){var r=t.length-4,i=t.length-2;e[$t]=D(t.substr(0,r)),e[Yt]=D(t.substr(r,2)),e[Ht]=D(t.substr(i)),y(n).bigHour=!0})),jt("Hmm",(function(t,e,n){var r=t.length-2;e[$t]=D(t.substr(0,r)),e[Yt]=D(t.substr(r))})),jt("Hmmss",(function(t,e,n){var r=t.length-4,i=t.length-2;e[$t]=D(t.substr(0,r)),e[Yt]=D(t.substr(r,2)),e[Ht]=D(t.substr(i))}));var on=/[ap]\.?m?\.?/i;function sn(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"}var ln,cn=Qt("Hours",!0),un={calendar:R,longDateFormat:N,invalidDate:$,ordinal:H,dayOfMonthOrdinalParse:W,relativeTime:G,months:se,monthsShort:ce,week:Te,weekdays:je,weekdaysMin:Ne,weekdaysShort:Re,meridiemParse:on},hn={},dn={};function fn(t){return t?t.toLowerCase().replace("_","-"):t}function pn(t){var e,n,r,i,a=0;while(a0){if(r=vn(i.slice(0,e).join("-")),r)return r;if(n&&n.length>=e&&T(i,n,!0)>=e-1)break;e--}a++}return ln}function vn(e){var n=null;if(!hn[e]&&t&&t.exports)try{n=ln._abbr;var i=r;i("./locale/"+e),gn(n)}catch(a){}return hn[e]}function gn(t,e){var n;return t&&(n=u(e)?bn(t):mn(t,e),n?ln=n:"undefined"!==typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),ln._abbr}function mn(t,e){if(null!==e){var n,r=un;if(e.abbr=t,null!=hn[t])M("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),r=hn[t]._config;else if(null!=e.parentLocale)if(null!=hn[e.parentLocale])r=hn[e.parentLocale]._config;else{if(n=vn(e.parentLocale),null==n)return dn[e.parentLocale]||(dn[e.parentLocale]=[]),dn[e.parentLocale].push({name:t,config:e}),null;r=n._config}return hn[t]=new B(j(r,e)),dn[t]&&dn[t].forEach((function(t){mn(t.name,t.config)})),gn(t),hn[t]}return delete hn[t],null}function yn(t,e){if(null!=e){var n,r,i=un;r=vn(t),null!=r&&(i=r._config),e=j(i,e),n=new B(e),n.parentLocale=hn[t],hn[t]=n,gn(t)}else null!=hn[t]&&(null!=hn[t].parentLocale?hn[t]=hn[t].parentLocale:null!=hn[t]&&delete hn[t]);return hn[t]}function bn(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return ln;if(!s(t)){if(e=vn(t),e)return e;t=[t]}return pn(t)}function xn(){return P(hn)}function wn(t){var e,n=t._a;return n&&-2===y(t).overflow&&(e=n[Nt]<0||n[Nt]>11?Nt:n[zt]<1||n[zt]>ae(n[Ft],n[Nt])?zt:n[$t]<0||n[$t]>24||24===n[$t]&&(0!==n[Yt]||0!==n[Ht]||0!==n[Wt])?$t:n[Yt]<0||n[Yt]>59?Yt:n[Ht]<0||n[Ht]>59?Ht:n[Wt]<0||n[Wt]>999?Wt:-1,y(t)._overflowDayOfYear&&(ezt)&&(e=zt),y(t)._overflowWeeks&&-1===e&&(e=Xt),y(t)._overflowWeekday&&-1===e&&(e=Gt),y(t).overflow=e),t}function kn(t,e,n){return null!=t?t:null!=e?e:n}function Sn(t){var e=new Date(a.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function Cn(t){var e,n,r,i,a,o=[];if(!t._d){for(r=Sn(t),t._w&&null==t._a[zt]&&null==t._a[Nt]&&An(t),null!=t._dayOfYear&&(a=kn(t._a[Ft],r[Ft]),(t._dayOfYear>Ut(a)||0===t._dayOfYear)&&(y(t)._overflowDayOfYear=!0),n=ke(a,0,t._dayOfYear),t._a[Nt]=n.getUTCMonth(),t._a[zt]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=o[e]=r[e];for(;e<7;e++)t._a[e]=o[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[$t]&&0===t._a[Yt]&&0===t._a[Ht]&&0===t._a[Wt]&&(t._nextDay=!0,t._a[$t]=0),t._d=(t._useUTC?ke:we).apply(null,o),i=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[$t]=24),t._w&&"undefined"!==typeof t._w.d&&t._w.d!==i&&(y(t).weekdayMismatch=!0)}}function An(t){var e,n,r,i,a,o,s,l;if(e=t._w,null!=e.GG||null!=e.W||null!=e.E)a=1,o=4,n=kn(e.GG,t._a[Ft],Ae(Zn(),1,4).year),r=kn(e.W,1),i=kn(e.E,1),(i<1||i>7)&&(l=!0);else{a=t._locale._week.dow,o=t._locale._week.doy;var c=Ae(Zn(),a,o);n=kn(e.gg,t._a[Ft],c.year),r=kn(e.w,c.week),null!=e.d?(i=e.d,(i<0||i>6)&&(l=!0)):null!=e.e?(i=e.e+a,(e.e<0||e.e>6)&&(l=!0)):i=a}r<1||r>_e(n,a,o)?y(t)._overflowWeeks=!0:null!=l?y(t)._overflowWeekday=!0:(s=Ce(n,r,i,a,o),t._a[Ft]=s.year,t._dayOfYear=s.dayOfYear)}var _n=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Dn=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Tn=/Z|[+-]\d\d(?::?\d\d)?/,En=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],On=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Pn=/^\/?Date\((\-?\d+)/i;function In(t){var e,n,r,i,a,o,s=t._i,l=_n.exec(s)||Dn.exec(s);if(l){for(y(t).iso=!0,e=0,n=En.length;e0&&y(t).unusedInput.push(o),s=s.slice(s.indexOf(n)+n.length),c+=n.length),st[i]?(n?y(t).empty=!1:y(t).unusedTokens.push(i),Rt(i,n,t)):t._strict&&!n&&y(t).unusedTokens.push(i);y(t).charsLeftOver=l-c,s.length>0&&y(t).unusedInput.push(s),t._a[$t]<=12&&!0===y(t).bigHour&&t._a[$t]>0&&(y(t).bigHour=void 0),y(t).parsedDateParts=t._a.slice(0),y(t).meridiem=t._meridiem,t._a[$t]=Yn(t._locale,t._a[$t],t._meridiem),Cn(t),wn(t)}else Nn(t);else In(t)}function Yn(t,e,n){var r;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?(r=t.isPM(n),r&&e<12&&(e+=12),r||12!==e||(e=0),e):e}function Hn(t){var e,n,r,i,a;if(0===t._f.length)return y(t).invalidFormat=!0,void(t._d=new Date(NaN));for(i=0;ithis?this:t:x()}));function Qn(t,e){var n,r;if(1===e.length&&s(e[0])&&(e=e[0]),!e.length)return Zn();for(n=e[0],r=1;rthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function kr(){if(!u(this._isDSTShifted))return this._isDSTShifted;var t={};if(k(t,this),t=Gn(t),t._a){var e=t._isUTC?g(t._a):Zn(t._a);this._isDSTShifted=this.isValid()&&T(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Sr(){return!!this.isValid()&&!this._isUTC}function Cr(){return!!this.isValid()&&this._isUTC}function Ar(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}a.updateOffset=function(){};var _r=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Dr=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Tr(t,e){var n,r,a,o=t,s=null;return lr(t)?o={ms:t._milliseconds,d:t._days,M:t._months}:h(t)?(o={},e?o[e]=t:o.milliseconds=t):(s=_r.exec(t))?(n="-"===s[1]?-1:1,o={y:0,d:D(s[zt])*n,h:D(s[$t])*n,m:D(s[Yt])*n,s:D(s[Ht])*n,ms:D(cr(1e3*s[Wt]))*n}):(s=Dr.exec(t))?(n="-"===s[1]?-1:1,o={y:Er(s[2],n),M:Er(s[3],n),w:Er(s[4],n),d:Er(s[5],n),h:Er(s[6],n),m:Er(s[7],n),s:Er(s[8],n)}):null==o?o={}:"object"===("undefined"===typeof o?"undefined":i(o))&&("from"in o||"to"in o)&&(a=Pr(Zn(o.from),Zn(o.to)),o={},o.ms=a.milliseconds,o.M=a.months),r=new sr(o),lr(t)&&p(t,"_locale")&&(r._locale=t._locale),r}function Er(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Or(t,e){var n={};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function Pr(t,e){var n;return t.isValid()&&e.isValid()?(e=fr(e,t),t.isBefore(e)?n=Or(t,e):(n=Or(e,t),n.milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function Ir(t,e){return function(n,r){var i,a;return null===r||isNaN(+r)||(M(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),a=n,n=r,r=a),n="string"===typeof n?+n:n,i=Tr(n,r),Mr(this,i,t),this}}function Mr(t,e,n,r){var i=e._milliseconds,o=cr(e._days),s=cr(e._months);t.isValid()&&(r=null==r||r,s&&fe(t,te(t,"Month")+s*n),o&&ee(t,"Date",te(t,"Date")+o*n),i&&t._d.setTime(t._d.valueOf()+i*n),r&&a.updateOffset(t,o||s))}Tr.fn=sr.prototype,Tr.invalid=or;var Vr=Ir(1,"add"),Lr=Ir(-1,"subtract");function jr(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"}function Br(t,e){var n=t||Zn(),r=fr(n,this).startOf("day"),i=a.calendarFormat(this,r)||"sameElse",o=e&&(V(e[i])?e[i].call(this,n):e[i]);return this.format(o||this.localeData().calendar(i,this,Zn(n)))}function Rr(){return new C(this)}function Fr(t,e){var n=A(t)?t:Zn(t);return!(!this.isValid()||!n.isValid())&&(e=J(e)||"millisecond","millisecond"===e?this.valueOf()>n.valueOf():n.valueOf()9999?ht(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):V(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",ht(n,"Z")):ht(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")}function qr(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',r=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",i="-MM-DD[T]HH:mm:ss.SSS",a=e+'[")]';return this.format(n+r+i+a)}function Zr(t){t||(t=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var e=ht(this,t);return this.localeData().postformat(e)}function Kr(t,e){return this.isValid()&&(A(t)&&t.isValid()||Zn(t).isValid())?Tr({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function Jr(t){return this.from(Zn(),t)}function Qr(t,e){return this.isValid()&&(A(t)&&t.isValid()||Zn(t).isValid())?Tr({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function ti(t){return this.to(Zn(),t)}function ei(t){var e;return void 0===t?this._locale._abbr:(e=bn(t),null!=e&&(this._locale=e),this)}a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var ni=O("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",(function(t){return void 0===t?this.localeData():this.locale(t)}));function ri(){return this._locale}var ii=1e3,ai=60*ii,oi=60*ai,si=3506328*oi;function li(t,e){return(t%e+e)%e}function ci(t,e,n){return t<100&&t>=0?new Date(t+400,e,n)-si:new Date(t,e,n).valueOf()}function ui(t,e,n){return t<100&&t>=0?Date.UTC(t+400,e,n)-si:Date.UTC(t,e,n)}function hi(t){var e;if(t=J(t),void 0===t||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?ui:ci;switch(t){case"year":e=n(this.year(),0,1);break;case"quarter":e=n(this.year(),this.month()-this.month()%3,1);break;case"month":e=n(this.year(),this.month(),1);break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":e=n(this.year(),this.month(),this.date());break;case"hour":e=this._d.valueOf(),e-=li(e+(this._isUTC?0:this.utcOffset()*ai),oi);break;case"minute":e=this._d.valueOf(),e-=li(e,ai);break;case"second":e=this._d.valueOf(),e-=li(e,ii);break}return this._d.setTime(e),a.updateOffset(this,!0),this}function di(t){var e;if(t=J(t),void 0===t||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?ui:ci;switch(t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf(),e+=oi-li(e+(this._isUTC?0:this.utcOffset()*ai),oi)-1;break;case"minute":e=this._d.valueOf(),e+=ai-li(e,ai)-1;break;case"second":e=this._d.valueOf(),e+=ii-li(e,ii)-1;break}return this._d.setTime(e),a.updateOffset(this,!0),this}function fi(){return this._d.valueOf()-6e4*(this._offset||0)}function pi(){return Math.floor(this.valueOf()/1e3)}function vi(){return new Date(this.valueOf())}function gi(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]}function mi(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}}function yi(){return this.isValid()?this.toISOString():null}function bi(){return b(this)}function xi(){return v({},y(this))}function wi(){return y(this).overflow}function ki(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Si(t,e){lt(0,[t,t.length],0,e)}function Ci(t){return Ti.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Ai(t){return Ti.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)}function _i(){return _e(this.year(),1,4)}function Di(){var t=this.localeData()._week;return _e(this.year(),t.dow,t.doy)}function Ti(t,e,n,r,i){var a;return null==t?Ae(this,r,i).year:(a=_e(t,r,i),e>a&&(e=a),Ei.call(this,t,e,n,r,i))}function Ei(t,e,n,r,i){var a=Ce(t,e,n,r,i),o=ke(a.year,0,a.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function Oi(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)}lt(0,["gg",2],0,(function(){return this.weekYear()%100})),lt(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),Si("gggg","weekYear"),Si("ggggg","weekYear"),Si("GGGG","isoWeekYear"),Si("GGGGG","isoWeekYear"),K("weekYear","gg"),K("isoWeekYear","GG"),et("weekYear",1),et("isoWeekYear",1),Pt("G",At),Pt("g",At),Pt("GG",yt,pt),Pt("gg",yt,pt),Pt("GGGG",kt,gt),Pt("gggg",kt,gt),Pt("GGGGG",St,mt),Pt("ggggg",St,mt),Bt(["gggg","ggggg","GGGG","GGGGG"],(function(t,e,n,r){e[r.substr(0,2)]=D(t)})),Bt(["gg","GG"],(function(t,e,n,r){e[r]=a.parseTwoDigitYear(t)})),lt("Q",0,"Qo","quarter"),K("quarter","Q"),et("quarter",7),Pt("Q",ft),jt("Q",(function(t,e){e[Nt]=3*(D(t)-1)})),lt("D",["DD",2],"Do","date"),K("date","D"),et("date",9),Pt("D",yt),Pt("DD",yt,pt),Pt("Do",(function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient})),jt(["D","DD"],zt),jt("Do",(function(t,e){e[zt]=D(t.match(yt)[0])}));var Pi=Qt("Date",!0);function Ii(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")}lt("DDD",["DDDD",3],"DDDo","dayOfYear"),K("dayOfYear","DDD"),et("dayOfYear",4),Pt("DDD",wt),Pt("DDDD",vt),jt(["DDD","DDDD"],(function(t,e,n){n._dayOfYear=D(t)})),lt("m",["mm",2],0,"minute"),K("minute","m"),et("minute",14),Pt("m",yt),Pt("mm",yt,pt),jt(["m","mm"],Yt);var Mi=Qt("Minutes",!1);lt("s",["ss",2],0,"second"),K("second","s"),et("second",15),Pt("s",yt),Pt("ss",yt,pt),jt(["s","ss"],Ht);var Vi,Li=Qt("Seconds",!1);for(lt("S",0,0,(function(){return~~(this.millisecond()/100)})),lt(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),lt(0,["SSS",3],0,"millisecond"),lt(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),lt(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),lt(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),lt(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),lt(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),lt(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),K("millisecond","ms"),et("millisecond",16),Pt("S",wt,ft),Pt("SS",wt,pt),Pt("SSS",wt,vt),Vi="SSSS";Vi.length<=9;Vi+="S")Pt(Vi,Ct);function ji(t,e){e[Wt]=D(1e3*("0."+t))}for(Vi="S";Vi.length<=9;Vi+="S")jt(Vi,ji);var Bi=Qt("Milliseconds",!1);function Ri(){return this._isUTC?"UTC":""}function Fi(){return this._isUTC?"Coordinated Universal Time":""}lt("z",0,0,"zoneAbbr"),lt("zz",0,0,"zoneName");var Ni=C.prototype;function zi(t){return Zn(1e3*t)}function $i(){return Zn.apply(null,arguments).parseZone()}function Yi(t){return t}Ni.add=Vr,Ni.calendar=Br,Ni.clone=Rr,Ni.diff=Wr,Ni.endOf=di,Ni.format=Zr,Ni.from=Kr,Ni.fromNow=Jr,Ni.to=Qr,Ni.toNow=ti,Ni.get=ne,Ni.invalidAt=wi,Ni.isAfter=Fr,Ni.isBefore=Nr,Ni.isBetween=zr,Ni.isSame=$r,Ni.isSameOrAfter=Yr,Ni.isSameOrBefore=Hr,Ni.isValid=bi,Ni.lang=ni,Ni.locale=ei,Ni.localeData=ri,Ni.max=Jn,Ni.min=Kn,Ni.parsingFlags=xi,Ni.set=re,Ni.startOf=hi,Ni.subtract=Lr,Ni.toArray=gi,Ni.toObject=mi,Ni.toDate=vi,Ni.toISOString=Ur,Ni.inspect=qr,Ni.toJSON=yi,Ni.toString=Gr,Ni.unix=pi,Ni.valueOf=fi,Ni.creationData=ki,Ni.year=Kt,Ni.isLeapYear=Jt,Ni.weekYear=Ci,Ni.isoWeekYear=Ai,Ni.quarter=Ni.quarters=Oi,Ni.month=pe,Ni.daysInMonth=ve,Ni.week=Ni.weeks=Pe,Ni.isoWeek=Ni.isoWeeks=Ie,Ni.weeksInYear=Di,Ni.isoWeeksInYear=_i,Ni.date=Pi,Ni.day=Ni.days=He,Ni.weekday=We,Ni.isoWeekday=Xe,Ni.dayOfYear=Ii,Ni.hour=Ni.hours=cn,Ni.minute=Ni.minutes=Mi,Ni.second=Ni.seconds=Li,Ni.millisecond=Ni.milliseconds=Bi,Ni.utcOffset=vr,Ni.utc=mr,Ni.local=yr,Ni.parseZone=br,Ni.hasAlignedHourOffset=xr,Ni.isDST=wr,Ni.isLocal=Sr,Ni.isUtcOffset=Cr,Ni.isUtc=Ar,Ni.isUTC=Ar,Ni.zoneAbbr=Ri,Ni.zoneName=Fi,Ni.dates=O("dates accessor is deprecated. Use date instead.",Pi),Ni.months=O("months accessor is deprecated. Use month instead",pe),Ni.years=O("years accessor is deprecated. Use year instead",Kt),Ni.zone=O("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",gr),Ni.isDSTShifted=O("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",kr);var Hi=B.prototype;function Wi(t,e,n,r){var i=bn(),a=g().set(r,e);return i[n](a,t)}function Xi(t,e,n){if(h(t)&&(e=t,t=void 0),t=t||"",null!=e)return Wi(t,e,n,"month");var r,i=[];for(r=0;r<12;r++)i[r]=Wi(t,r,n,"month");return i}function Gi(t,e,n,r){"boolean"===typeof t?(h(e)&&(n=e,e=void 0),e=e||""):(e=t,n=e,t=!1,h(e)&&(n=e,e=void 0),e=e||"");var i,a=bn(),o=t?a._week.dow:0;if(null!=n)return Wi(e,(n+o)%7,r,"day");var s=[];for(i=0;i<7;i++)s[i]=Wi(e,(i+o)%7,r,"day");return s}function Ui(t,e){return Xi(t,e,"months")}function qi(t,e){return Xi(t,e,"monthsShort")}function Zi(t,e,n){return Gi(t,e,n,"weekdays")}function Ki(t,e,n){return Gi(t,e,n,"weekdaysShort")}function Ji(t,e,n){return Gi(t,e,n,"weekdaysMin")}Hi.calendar=F,Hi.longDateFormat=z,Hi.invalidDate=Y,Hi.ordinal=X,Hi.preparse=Yi,Hi.postformat=Yi,Hi.relativeTime=U,Hi.pastFuture=q,Hi.set=L,Hi.months=le,Hi.monthsShort=ue,Hi.monthsParse=de,Hi.monthsRegex=be,Hi.monthsShortRegex=me,Hi.week=De,Hi.firstDayOfYear=Oe,Hi.firstDayOfWeek=Ee,Hi.weekdays=Be,Hi.weekdaysMin=ze,Hi.weekdaysShort=Fe,Hi.weekdaysParse=Ye,Hi.weekdaysRegex=Ue,Hi.weekdaysShortRegex=Ze,Hi.weekdaysMinRegex=Je,Hi.isPM=an,Hi.meridiem=sn,gn("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10,n=1===D(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+n}}),a.lang=O("moment.lang is deprecated. Use moment.locale instead.",gn),a.langData=O("moment.langData is deprecated. Use moment.localeData instead.",bn);var Qi=Math.abs;function ta(){var t=this._data;return this._milliseconds=Qi(this._milliseconds),this._days=Qi(this._days),this._months=Qi(this._months),t.milliseconds=Qi(t.milliseconds),t.seconds=Qi(t.seconds),t.minutes=Qi(t.minutes),t.hours=Qi(t.hours),t.months=Qi(t.months),t.years=Qi(t.years),this}function ea(t,e,n,r){var i=Tr(e,n);return t._milliseconds+=r*i._milliseconds,t._days+=r*i._days,t._months+=r*i._months,t._bubble()}function na(t,e){return ea(this,t,e,1)}function ra(t,e){return ea(this,t,e,-1)}function ia(t){return t<0?Math.floor(t):Math.ceil(t)}function aa(){var t,e,n,r,i,a=this._milliseconds,o=this._days,s=this._months,l=this._data;return a>=0&&o>=0&&s>=0||a<=0&&o<=0&&s<=0||(a+=864e5*ia(sa(s)+o),o=0,s=0),l.milliseconds=a%1e3,t=_(a/1e3),l.seconds=t%60,e=_(t/60),l.minutes=e%60,n=_(e/60),l.hours=n%24,o+=_(n/24),i=_(oa(o)),s+=i,o-=ia(sa(i)),r=_(s/12),s%=12,l.days=o,l.months=s,l.years=r,this}function oa(t){return 4800*t/146097}function sa(t){return 146097*t/4800}function la(t){if(!this.isValid())return NaN;var e,n,r=this._milliseconds;if(t=J(t),"month"===t||"quarter"===t||"year"===t)switch(e=this._days+r/864e5,n=this._months+oa(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(sa(this._months)),t){case"week":return e/7+r/6048e5;case"day":return e+r/864e5;case"hour":return 24*e+r/36e5;case"minute":return 1440*e+r/6e4;case"second":return 86400*e+r/1e3;case"millisecond":return Math.floor(864e5*e)+r;default:throw new Error("Unknown unit "+t)}}function ca(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*D(this._months/12):NaN}function ua(t){return function(){return this.as(t)}}var ha=ua("ms"),da=ua("s"),fa=ua("m"),pa=ua("h"),va=ua("d"),ga=ua("w"),ma=ua("M"),ya=ua("Q"),ba=ua("y");function xa(){return Tr(this)}function wa(t){return t=J(t),this.isValid()?this[t+"s"]():NaN}function ka(t){return function(){return this.isValid()?this._data[t]:NaN}}var Sa=ka("milliseconds"),Ca=ka("seconds"),Aa=ka("minutes"),_a=ka("hours"),Da=ka("days"),Ta=ka("months"),Ea=ka("years");function Oa(){return _(this.days()/7)}var Pa=Math.round,Ia={ss:44,s:45,m:45,h:22,d:26,M:11};function Ma(t,e,n,r,i){return i.relativeTime(e||1,!!n,t,r)}function Va(t,e,n){var r=Tr(t).abs(),i=Pa(r.as("s")),a=Pa(r.as("m")),o=Pa(r.as("h")),s=Pa(r.as("d")),l=Pa(r.as("M")),c=Pa(r.as("y")),u=i<=Ia.ss&&["s",i]||i0,u[4]=n,Ma.apply(null,u)}function La(t){return void 0===t?Pa:"function"===typeof t&&(Pa=t,!0)}function ja(t,e){return void 0!==Ia[t]&&(void 0===e?Ia[t]:(Ia[t]=e,"s"===t&&(Ia.ss=e-1),!0))}function Ba(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=Va(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)}var Ra=Math.abs;function Fa(t){return(t>0)-(t<0)||+t}function Na(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n,r=Ra(this._milliseconds)/1e3,i=Ra(this._days),a=Ra(this._months);t=_(r/60),e=_(t/60),r%=60,t%=60,n=_(a/12),a%=12;var o=n,s=a,l=i,c=e,u=t,h=r?r.toFixed(3).replace(/\.?0+$/,""):"",d=this.asSeconds();if(!d)return"P0D";var f=d<0?"-":"",p=Fa(this._months)!==Fa(d)?"-":"",v=Fa(this._days)!==Fa(d)?"-":"",g=Fa(this._milliseconds)!==Fa(d)?"-":"";return f+"P"+(o?p+o+"Y":"")+(s?p+s+"M":"")+(l?v+l+"D":"")+(c||u||h?"T":"")+(c?g+c+"H":"")+(u?g+u+"M":"")+(h?g+h+"S":"")}var za=sr.prototype;return za.isValid=ar,za.abs=ta,za.add=na,za.subtract=ra,za.as=la,za.asMilliseconds=ha,za.asSeconds=da,za.asMinutes=fa,za.asHours=pa,za.asDays=va,za.asWeeks=ga,za.asMonths=ma,za.asQuarters=ya,za.asYears=ba,za.valueOf=ca,za._bubble=aa,za.clone=xa,za.get=wa,za.milliseconds=Sa,za.seconds=Ca,za.minutes=Aa,za.hours=_a,za.days=Da,za.weeks=Oa,za.months=Ta,za.years=Ea,za.humanize=Ba,za.toISOString=Na,za.toString=Na,za.toJSON=Na,za.locale=ei,za.localeData=ri,za.toIsoString=O("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Na),za.lang=ni,lt("X",0,0,"unix"),lt("x",0,0,"valueOf"),Pt("x",At),Pt("X",Tt),jt("X",(function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))})),jt("x",(function(t,e,n){n._d=new Date(D(t))})),a.version="2.24.0",o(Zn),a.fn=Ni,a.min=tr,a.max=er,a.now=nr,a.utc=g,a.unix=zi,a.months=Ui,a.isDate=d,a.locale=gn,a.invalid=x,a.duration=Tr,a.isMoment=A,a.weekdays=Zi,a.parseZone=$i,a.localeData=bn,a.isDuration=lr,a.monthsShort=qi,a.weekdaysMin=Ji,a.defineLocale=mn,a.updateLocale=yn,a.locales=xn,a.weekdaysShort=Ki,a.normalizeUnits=J,a.relativeTimeRounding=La,a.relativeTimeThreshold=ja,a.calendarFormat=jr,a.prototype=Ni,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},a}))})),o="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function s(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1?n[a-1]:void 0,s=a>2?n[2]:void 0;o=t.length>3&&"function"==typeof o?(a--,o):void 0,s&&i(n[0],n[1],s)&&(o=a<3?void 0:o,a=1),e=Object(e);while(++r + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */(function(){var a,o="4.17.21",s=200,l="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",c="Expected a function",u="Invalid `variable` option passed into `_.template`",h="__lodash_hash_undefined__",d=500,f="__lodash_placeholder__",p=1,v=2,g=4,m=1,y=2,b=1,x=2,w=4,k=8,S=16,C=32,A=64,_=128,D=256,T=512,E=30,O="...",P=800,I=16,M=1,V=2,L=3,j=1/0,B=9007199254740991,R=17976931348623157e292,F=NaN,N=4294967295,z=N-1,$=N>>>1,Y=[["ary",_],["bind",b],["bindKey",x],["curry",k],["curryRight",S],["flip",T],["partial",C],["partialRight",A],["rearg",D]],H="[object Arguments]",W="[object Array]",X="[object AsyncFunction]",G="[object Boolean]",U="[object Date]",q="[object DOMException]",Z="[object Error]",K="[object Function]",J="[object GeneratorFunction]",Q="[object Map]",tt="[object Number]",et="[object Null]",nt="[object Object]",rt="[object Promise]",it="[object Proxy]",at="[object RegExp]",ot="[object Set]",st="[object String]",lt="[object Symbol]",ct="[object Undefined]",ut="[object WeakMap]",ht="[object WeakSet]",dt="[object ArrayBuffer]",ft="[object DataView]",pt="[object Float32Array]",vt="[object Float64Array]",gt="[object Int8Array]",mt="[object Int16Array]",yt="[object Int32Array]",bt="[object Uint8Array]",xt="[object Uint8ClampedArray]",wt="[object Uint16Array]",kt="[object Uint32Array]",St=/\b__p \+= '';/g,Ct=/\b(__p \+=) '' \+/g,At=/(__e\(.*?\)|\b__t\)) \+\n'';/g,_t=/&(?:amp|lt|gt|quot|#39);/g,Dt=/[&<>"']/g,Tt=RegExp(_t.source),Et=RegExp(Dt.source),Ot=/<%-([\s\S]+?)%>/g,Pt=/<%([\s\S]+?)%>/g,It=/<%=([\s\S]+?)%>/g,Mt=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Vt=/^\w*$/,Lt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,jt=/[\\^$.*+?()[\]{}|]/g,Bt=RegExp(jt.source),Rt=/^\s+/,Ft=/\s/,Nt=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,zt=/\{\n\/\* \[wrapped with (.+)\] \*/,$t=/,? & /,Yt=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Ht=/[()=,{}\[\]\/\s]/,Wt=/\\(\\)?/g,Xt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Gt=/\w*$/,Ut=/^[-+]0x[0-9a-f]+$/i,qt=/^0b[01]+$/i,Zt=/^\[object .+?Constructor\]$/,Kt=/^0o[0-7]+$/i,Jt=/^(?:0|[1-9]\d*)$/,Qt=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,te=/($^)/,ee=/['\n\r\u2028\u2029\\]/g,ne="\\ud800-\\udfff",re="\\u0300-\\u036f",ie="\\ufe20-\\ufe2f",ae="\\u20d0-\\u20ff",oe=re+ie+ae,se="\\u2700-\\u27bf",le="a-z\\xdf-\\xf6\\xf8-\\xff",ce="\\xac\\xb1\\xd7\\xf7",ue="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",he="\\u2000-\\u206f",de=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",fe="A-Z\\xc0-\\xd6\\xd8-\\xde",pe="\\ufe0e\\ufe0f",ve=ce+ue+he+de,ge="['’]",me="["+ne+"]",ye="["+ve+"]",be="["+oe+"]",xe="\\d+",we="["+se+"]",ke="["+le+"]",Se="[^"+ne+ve+xe+se+le+fe+"]",Ce="\\ud83c[\\udffb-\\udfff]",Ae="(?:"+be+"|"+Ce+")",_e="[^"+ne+"]",De="(?:\\ud83c[\\udde6-\\uddff]){2}",Te="[\\ud800-\\udbff][\\udc00-\\udfff]",Ee="["+fe+"]",Oe="\\u200d",Pe="(?:"+ke+"|"+Se+")",Ie="(?:"+Ee+"|"+Se+")",Me="(?:"+ge+"(?:d|ll|m|re|s|t|ve))?",Ve="(?:"+ge+"(?:D|LL|M|RE|S|T|VE))?",Le=Ae+"?",je="["+pe+"]?",Be="(?:"+Oe+"(?:"+[_e,De,Te].join("|")+")"+je+Le+")*",Re="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",Fe="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",Ne=je+Le+Be,ze="(?:"+[we,De,Te].join("|")+")"+Ne,$e="(?:"+[_e+be+"?",be,De,Te,me].join("|")+")",Ye=RegExp(ge,"g"),He=RegExp(be,"g"),We=RegExp(Ce+"(?="+Ce+")|"+$e+Ne,"g"),Xe=RegExp([Ee+"?"+ke+"+"+Me+"(?="+[ye,Ee,"$"].join("|")+")",Ie+"+"+Ve+"(?="+[ye,Ee+Pe,"$"].join("|")+")",Ee+"?"+Pe+"+"+Me,Ee+"+"+Ve,Fe,Re,xe,ze].join("|"),"g"),Ge=RegExp("["+Oe+ne+oe+pe+"]"),Ue=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,qe=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Ze=-1,Ke={};Ke[pt]=Ke[vt]=Ke[gt]=Ke[mt]=Ke[yt]=Ke[bt]=Ke[xt]=Ke[wt]=Ke[kt]=!0,Ke[H]=Ke[W]=Ke[dt]=Ke[G]=Ke[ft]=Ke[U]=Ke[Z]=Ke[K]=Ke[Q]=Ke[tt]=Ke[nt]=Ke[at]=Ke[ot]=Ke[st]=Ke[ut]=!1;var Je={};Je[H]=Je[W]=Je[dt]=Je[ft]=Je[G]=Je[U]=Je[pt]=Je[vt]=Je[gt]=Je[mt]=Je[yt]=Je[Q]=Je[tt]=Je[nt]=Je[at]=Je[ot]=Je[st]=Je[lt]=Je[bt]=Je[xt]=Je[wt]=Je[kt]=!0,Je[Z]=Je[K]=Je[ut]=!1;var Qe={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"},tn={"&":"&","<":"<",">":">",'"':""","'":"'"},en={"&":"&","<":"<",">":">",""":'"',"'":"'"},nn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},rn=parseFloat,an=parseInt,on="object"==typeof t&&t&&t.Object===Object&&t,sn="object"==typeof self&&self&&self.Object===Object&&self,ln=on||sn||Function("return this")(),cn=e&&!e.nodeType&&e,un=cn&&"object"==typeof r&&r&&!r.nodeType&&r,hn=un&&un.exports===cn,dn=hn&&on.process,fn=function(){try{var t=un&&un.require&&un.require("util").types;return t||dn&&dn.binding&&dn.binding("util")}catch(e){}}(),pn=fn&&fn.isArrayBuffer,vn=fn&&fn.isDate,gn=fn&&fn.isMap,mn=fn&&fn.isRegExp,yn=fn&&fn.isSet,bn=fn&&fn.isTypedArray;function xn(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}function wn(t,e,n,r){var i=-1,a=null==t?0:t.length;while(++i-1}function Dn(t,e,n){var r=-1,i=null==t?0:t.length;while(++r-1);return n}function tr(t,e){var n=t.length;while(n--&&Rn(e,t[n],0)>-1);return n}function er(t,e){var n=t.length,r=0;while(n--)t[n]===e&&++r;return r}var nr=Yn(Qe),rr=Yn(tn);function ir(t){return"\\"+nn[t]}function ar(t,e){return null==t?a:t[e]}function or(t){return Ge.test(t)}function sr(t){return Ue.test(t)}function lr(t){var e,n=[];while(!(e=t.next()).done)n.push(e.value);return n}function cr(t){var e=-1,n=Array(t.size);return t.forEach((function(t,r){n[++e]=[r,t]})),n}function ur(t,e){return function(n){return t(e(n))}}function hr(t,e){var n=-1,r=t.length,i=0,a=[];while(++n-1}function $r(t,e){var n=this.__data__,r=ui(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this}function Yr(t){var e=-1,n=null==t?0:t.length;this.clear();while(++e=e?t:e)),t}function mi(t,e,n,r,i,o){var s,l=e&p,c=e&v,u=e&g;if(n&&(s=i?n(t,r,i,o):n(t)),s!==a)return s;if(!Cu(t))return t;var h=lu(t);if(h){if(s=es(t),!l)return ro(t,s)}else{var d=Ko(t),f=d==K||d==J;if(fu(t))return Ga(t,l);if(d==nt||d==H||f&&!i){if(s=c||f?{}:ns(t),!l)return c?oo(t,fi(s,t)):ao(t,di(s,t))}else{if(!Je[d])return i?t:{};s=rs(t,d,l)}}o||(o=new Jr);var m=o.get(t);if(m)return m;o.set(t,s),Bu(t)?t.forEach((function(r){s.add(mi(r,e,n,r,t,o))})):_u(t)&&t.forEach((function(r,i){s.set(i,mi(r,e,n,i,t,o))}));var y=u?c?No:Fo:c?Sh:kh,b=h?a:y(t);return kn(b||t,(function(r,i){b&&(i=r,r=t[i]),ci(s,i,mi(r,e,n,i,t,o))})),s}function yi(t){var e=kh(t);return function(n){return bi(n,t,e)}}function bi(t,e,n){var r=n.length;if(null==t)return!r;t=ne(t);while(r--){var i=n[r],o=e[i],s=t[i];if(s===a&&!(i in t)||!o(s))return!1}return!0}function xi(t,e,n){if("function"!=typeof t)throw new ae(c);return As((function(){t.apply(a,n)}),e)}function wi(t,e,n,r){var i=-1,a=_n,o=!0,l=t.length,c=[],u=e.length;if(!l)return c;n&&(e=Tn(e,Zn(n))),r?(a=Dn,o=!1):e.length>=s&&(a=Jn,o=!1,e=new qr(e));t:while(++ii?0:i+n),r=r===a||r>i?i:Uu(r),r<0&&(r+=i),r=n>r?0:qu(r);while(n0&&n(s)?e>1?Ti(s,e-1,n,r,i):En(i,s):r||(i[i.length]=s)}return i}var Ei=uo(),Oi=uo(!0);function Pi(t,e){return t&&Ei(t,e,kh)}function Ii(t,e){return t&&Oi(t,e,kh)}function Mi(t,e){return An(e,(function(e){return wu(t[e])}))}function Vi(t,e){e=Ya(e,t);var n=0,r=e.length;while(null!=t&&ne}function Ri(t,e){return null!=t&&he.call(t,e)}function Fi(t,e){return null!=t&&e in ne(t)}function Ni(t,e,n){return t>=ze(e,n)&&t=120&&d.length>=120)?new qr(l&&d):a}d=t[0];var f=-1,p=c[0];t:while(++f-1)s!==t&&Ae.call(s,l,1),Ae.call(t,l,1)}return t}function ga(t,e){var n=t?e.length:0,r=n-1;while(n--){var i=e[n];if(n==r||i!==a){var a=i;os(i)?Ae.call(t,i,1):La(t,i)}}return t}function ma(t,e){return t+Ve(Xe()*(e-t+1))}function ya(t,e,r,i){var a=-1,o=Ne(Me((e-t)/(r||1)),0),s=n(o);while(o--)s[i?o:++a]=t,t+=r;return s}function ba(t,e){var n="";if(!t||e<1||e>B)return n;do{e%2&&(n+=t),e=Ve(e/2),e&&(t+=t)}while(e);return n}function xa(t,e){return _s(xs(t,e,Od),t+"")}function wa(t){return ai(zh(t))}function ka(t,e){var n=zh(t);return Es(n,gi(e,0,n.length))}function Sa(t,e,n,r){if(!Cu(t))return t;e=Ya(e,t);var i=-1,o=e.length,s=o-1,l=t;while(null!=l&&++ia?0:a+e),r=r>a?a:r,r<0&&(r+=a),a=e>r?0:r-e>>>0,e>>>=0;var o=n(a);while(++i>>1,o=t[a];null!==o&&!Fu(o)&&(n?o<=e:o=s){var u=e?null:Eo(t);if(u)return dr(u);o=!1,i=Jn,c=new qr}else c=e?[]:l;t:while(++r=r?t:Da(t,e,n)}var Xa=Oe||function(t){return ln.clearTimeout(t)};function Ga(t,e){if(e)return t.slice();var n=t.length,r=we?we(n):new t.constructor(n);return t.copy(r),r}function Ua(t){var e=new t.constructor(t.byteLength);return new xe(e).set(new xe(t)),e}function qa(t,e){var n=e?Ua(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)}function Za(t){var e=new t.constructor(t.source,Gt.exec(t));return e.lastIndex=t.lastIndex,e}function Ka(t){return pr?ne(pr.call(t)):{}}function Ja(t,e){var n=e?Ua(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.length)}function Qa(t,e){if(t!==e){var n=t!==a,r=null===t,i=t===t,o=Fu(t),s=e!==a,l=null===e,c=e===e,u=Fu(e);if(!l&&!u&&!o&&t>e||o&&s&&c&&!l&&!u||r&&s&&c||!n&&c||!i)return 1;if(!r&&!o&&!u&&t=s)return l;var c=n[r];return l*("desc"==c?-1:1)}}return t.index-e.index}function eo(t,e,r,i){var a=-1,o=t.length,s=r.length,l=-1,c=e.length,u=Ne(o-s,0),h=n(c+u),d=!i;while(++l1?n[i-1]:a,s=i>2?n[2]:a;o=t.length>3&&"function"==typeof o?(i--,o):a,s&&ss(n[0],n[1],s)&&(o=i<3?a:o,i=1),e=ne(e);while(++r-1?i[o?e[s]:s]:a}}function yo(t){return Ro((function(e){var n=e.length,r=n,i=_r.prototype.thru;t&&e.reverse();while(r--){var o=e[r];if("function"!=typeof o)throw new ae(c);if(i&&!s&&"wrapper"==$o(o))var s=new _r([],!0)}r=s?r:n;while(++r1&&b.reverse(),d&&ul))return!1;var u=o.get(t),h=o.get(e);if(u&&h)return u==e&&h==t;var d=-1,f=!0,p=n&y?new qr:a;o.set(t,e),o.set(e,t);while(++d1?"& ":"")+e[r],e=e.join(n>2?", ":" "),t.replace(Nt,"{\n/* [wrapped with "+e+"] */\n")}function as(t){return lu(t)||su(t)||!!(_e&&t&&t[_e])}function os(t,e){var n=typeof t;return e=null==e?B:e,!!e&&("number"==n||"symbol"!=n&&Jt.test(t))&&t>-1&&t%1==0&&t0){if(++e>=P)return arguments[0]}else e=0;return t.apply(a,arguments)}}function Es(t,e){var n=-1,r=t.length,i=r-1;e=e===a?r:e;while(++n1?t[e-1]:a;return n="function"==typeof n?(t.pop(),n):a,jl(t,n)}));function Wl(t){var e=wr(t);return e.__chain__=!0,e}function Xl(t,e){return e(t),t}function Gl(t,e){return e(t)}var Ul=Ro((function(t){var e=t.length,n=e?t[0]:0,r=this.__wrapped__,i=function(e){return vi(e,t)};return!(e>1||this.__actions__.length)&&r instanceof Dr&&os(n)?(r=r.slice(n,+n+(e?1:0)),r.__actions__.push({func:Gl,args:[i],thisArg:a}),new _r(r,this.__chain__).thru((function(t){return e&&!t.length&&t.push(a),t}))):this.thru(i)}));function ql(){return Wl(this)}function Zl(){return new _r(this.value(),this.__chain__)}function Kl(){this.__values__===a&&(this.__values__=Xu(this.value()));var t=this.__index__>=this.__values__.length,e=t?a:this.__values__[this.__index__++];return{done:t,value:e}}function Jl(){return this}function Ql(t){var e,n=this;while(n instanceof Ar){var r=Vs(n);r.__index__=0,r.__values__=a,e?i.__wrapped__=r:e=r;var i=r;n=n.__wrapped__}return i.__wrapped__=t,e}function tc(){var t=this.__wrapped__;if(t instanceof Dr){var e=t;return this.__actions__.length&&(e=new Dr(this)),e=e.reverse(),e.__actions__.push({func:Gl,args:[pl],thisArg:a}),new _r(e,this.__chain__)}return this.thru(pl)}function ec(){return Ra(this.__wrapped__,this.__actions__)}var nc=so((function(t,e,n){he.call(t,n)?++t[n]:pi(t,n,1)}));function rc(t,e,n){var r=lu(t)?Cn:Ci;return n&&ss(t,e,n)&&(e=a),r(t,Ho(e,3))}function ic(t,e){var n=lu(t)?An:Di;return n(t,Ho(e,3))}var ac=mo(Xs),oc=mo(Gs);function sc(t,e){return Ti(gc(t,e),1)}function lc(t,e){return Ti(gc(t,e),j)}function cc(t,e,n){return n=n===a?1:Uu(n),Ti(gc(t,e),n)}function uc(t,e){var n=lu(t)?kn:ki;return n(t,Ho(e,3))}function hc(t,e){var n=lu(t)?Sn:Si;return n(t,Ho(e,3))}var dc=so((function(t,e,n){he.call(t,n)?t[n].push(e):pi(t,n,[e])}));function fc(t,e,n,r){t=uu(t)?t:zh(t),n=n&&!r?Uu(n):0;var i=t.length;return n<0&&(n=Ne(i+n,0)),Ru(t)?n<=i&&t.indexOf(e,n)>-1:!!i&&Rn(t,e,n)>-1}var pc=xa((function(t,e,r){var i=-1,a="function"==typeof e,o=uu(t)?n(t.length):[];return ki(t,(function(t){o[++i]=a?xn(e,t,r):Yi(t,e,r)})),o})),vc=so((function(t,e,n){pi(t,n,e)}));function gc(t,e){var n=lu(t)?Tn:aa;return n(t,Ho(e,3))}function mc(t,e,n,r){return null==t?[]:(lu(e)||(e=null==e?[]:[e]),n=r?a:n,lu(n)||(n=null==n?[]:[n]),ha(t,e,n))}var yc=so((function(t,e,n){t[n?0:1].push(e)}),(function(){return[[],[]]}));function bc(t,e,n){var r=lu(t)?On:Hn,i=arguments.length<3;return r(t,Ho(e,4),n,i,ki)}function xc(t,e,n){var r=lu(t)?Pn:Hn,i=arguments.length<3;return r(t,Ho(e,4),n,i,Si)}function wc(t,e){var n=lu(t)?An:Di;return n(t,zc(Ho(e,3)))}function kc(t){var e=lu(t)?ai:wa;return e(t)}function Sc(t,e,n){e=(n?ss(t,e,n):e===a)?1:Uu(e);var r=lu(t)?oi:ka;return r(t,e)}function Cc(t){var e=lu(t)?si:_a;return e(t)}function Ac(t){if(null==t)return 0;if(uu(t))return Ru(t)?gr(t):t.length;var e=Ko(t);return e==Q||e==ot?t.size:na(t).length}function _c(t,e,n){var r=lu(t)?In:Ta;return n&&ss(t,e,n)&&(e=a),r(t,Ho(e,3))}var Dc=xa((function(t,e){if(null==t)return[];var n=e.length;return n>1&&ss(t,e[0],e[1])?e=[]:n>2&&ss(e[0],e[1],e[2])&&(e=[e[0]]),ha(t,Ti(e,1),[])})),Tc=Pe||function(){return ln.Date.now()};function Ec(t,e){if("function"!=typeof e)throw new ae(c);return t=Uu(t),function(){if(--t<1)return e.apply(this,arguments)}}function Oc(t,e,n){return e=n?a:e,e=t&&null==e?t.length:e,Po(t,_,a,a,a,a,e)}function Pc(t,e){var n;if("function"!=typeof e)throw new ae(c);return t=Uu(t),function(){return--t>0&&(n=e.apply(this,arguments)),t<=1&&(e=a),n}}var Ic=xa((function(t,e,n){var r=b;if(n.length){var i=hr(n,Yo(Ic));r|=C}return Po(t,r,e,n,i)})),Mc=xa((function(t,e,n){var r=b|x;if(n.length){var i=hr(n,Yo(Mc));r|=C}return Po(e,r,t,n,i)}));function Vc(t,e,n){e=n?a:e;var r=Po(t,k,a,a,a,a,a,e);return r.placeholder=Vc.placeholder,r}function Lc(t,e,n){e=n?a:e;var r=Po(t,S,a,a,a,a,a,e);return r.placeholder=Lc.placeholder,r}function jc(t,e,n){var r,i,o,s,l,u,h=0,d=!1,f=!1,p=!0;if("function"!=typeof t)throw new ae(c);function v(e){var n=r,o=i;return r=i=a,h=e,s=t.apply(o,n),s}function g(t){return h=t,l=As(b,e),d?v(t):s}function m(t){var n=t-u,r=t-h,i=e-n;return f?ze(i,o-r):i}function y(t){var n=t-u,r=t-h;return u===a||n>=e||n<0||f&&r>=o}function b(){var t=Tc();if(y(t))return x(t);l=As(b,m(t))}function x(t){return l=a,p&&r?v(t):(r=i=a,s)}function w(){l!==a&&Xa(l),h=0,r=u=i=l=a}function k(){return l===a?s:x(Tc())}function S(){var t=Tc(),n=y(t);if(r=arguments,i=this,u=t,n){if(l===a)return g(u);if(f)return Xa(l),l=As(b,e),v(u)}return l===a&&(l=As(b,e)),s}return e=Zu(e)||0,Cu(n)&&(d=!!n.leading,f="maxWait"in n,o=f?Ne(Zu(n.maxWait)||0,e):o,p="trailing"in n?!!n.trailing:p),S.cancel=w,S.flush=k,S}var Bc=xa((function(t,e){return xi(t,1,e)})),Rc=xa((function(t,e,n){return xi(t,Zu(e)||0,n)}));function Fc(t){return Po(t,T)}function Nc(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new ae(c);var n=function(){var r=arguments,i=e?e.apply(this,r):r[0],a=n.cache;if(a.has(i))return a.get(i);var o=t.apply(this,r);return n.cache=a.set(i,o)||a,o};return n.cache=new(Nc.Cache||Yr),n}function zc(t){if("function"!=typeof t)throw new ae(c);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}function $c(t){return Pc(2,t)}Nc.Cache=Yr;var Yc=Ha((function(t,e){e=1==e.length&&lu(e[0])?Tn(e[0],Zn(Ho())):Tn(Ti(e,1),Zn(Ho()));var n=e.length;return xa((function(r){var i=-1,a=ze(r.length,n);while(++i=e})),su=Hi(function(){return arguments}())?Hi:function(t){return Au(t)&&he.call(t,"callee")&&!Ce.call(t,"callee")},lu=n.isArray,cu=pn?Zn(pn):Wi;function uu(t){return null!=t&&Su(t.length)&&!wu(t)}function hu(t){return Au(t)&&uu(t)}function du(t){return!0===t||!1===t||Au(t)&&ji(t)==G}var fu=je||Ud,pu=vn?Zn(vn):Xi;function vu(t){return Au(t)&&1===t.nodeType&&!Vu(t)}function gu(t){if(null==t)return!0;if(uu(t)&&(lu(t)||"string"==typeof t||"function"==typeof t.splice||fu(t)||Nu(t)||su(t)))return!t.length;var e=Ko(t);if(e==Q||e==ot)return!t.size;if(fs(t))return!na(t).length;for(var n in t)if(he.call(t,n))return!1;return!0}function mu(t,e){return Gi(t,e)}function yu(t,e,n){n="function"==typeof n?n:a;var r=n?n(t,e):a;return r===a?Gi(t,e,a,n):!!r}function bu(t){if(!Au(t))return!1;var e=ji(t);return e==Z||e==q||"string"==typeof t.message&&"string"==typeof t.name&&!Vu(t)}function xu(t){return"number"==typeof t&&Be(t)}function wu(t){if(!Cu(t))return!1;var e=ji(t);return e==K||e==J||e==X||e==it}function ku(t){return"number"==typeof t&&t==Uu(t)}function Su(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=B}function Cu(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function Au(t){return null!=t&&"object"==typeof t}var _u=gn?Zn(gn):qi;function Du(t,e){return t===e||Zi(t,e,Xo(e))}function Tu(t,e,n){return n="function"==typeof n?n:a,Zi(t,e,Xo(e),n)}function Eu(t){return Mu(t)&&t!=+t}function Ou(t){if(ds(t))throw new i(l);return Ki(t)}function Pu(t){return null===t}function Iu(t){return null==t}function Mu(t){return"number"==typeof t||Au(t)&&ji(t)==tt}function Vu(t){if(!Au(t)||ji(t)!=nt)return!1;var e=ke(t);if(null===e)return!0;var n=he.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&ue.call(n)==ve}var Lu=mn?Zn(mn):Ji;function ju(t){return ku(t)&&t>=-B&&t<=B}var Bu=yn?Zn(yn):Qi;function Ru(t){return"string"==typeof t||!lu(t)&&Au(t)&&ji(t)==st}function Fu(t){return"symbol"==typeof t||Au(t)&&ji(t)==lt}var Nu=bn?Zn(bn):ta;function zu(t){return t===a}function $u(t){return Au(t)&&Ko(t)==ut}function Yu(t){return Au(t)&&ji(t)==ht}var Hu=_o(ia),Wu=_o((function(t,e){return t<=e}));function Xu(t){if(!t)return[];if(uu(t))return Ru(t)?mr(t):ro(t);if(De&&t[De])return lr(t[De]());var e=Ko(t),n=e==Q?cr:e==ot?dr:zh;return n(t)}function Gu(t){if(!t)return 0===t?t:0;if(t=Zu(t),t===j||t===-j){var e=t<0?-1:1;return e*R}return t===t?t:0}function Uu(t){var e=Gu(t),n=e%1;return e===e?n?e-n:e:0}function qu(t){return t?gi(Uu(t),0,N):0}function Zu(t){if("number"==typeof t)return t;if(Fu(t))return F;if(Cu(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=Cu(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=qn(t);var n=qt.test(t);return n||Kt.test(t)?an(t.slice(2),n?2:8):Ut.test(t)?F:+t}function Ku(t){return io(t,Sh(t))}function Ju(t){return t?gi(Uu(t),-B,B):0===t?t:0}function Qu(t){return null==t?"":Ma(t)}var th=lo((function(t,e){if(fs(e)||uu(e))io(e,kh(e),t);else for(var n in e)he.call(e,n)&&ci(t,n,e[n])})),eh=lo((function(t,e){io(e,Sh(e),t)})),nh=lo((function(t,e,n,r){io(e,Sh(e),t,r)})),rh=lo((function(t,e,n,r){io(e,kh(e),t,r)})),ih=Ro(vi);function ah(t,e){var n=Sr(t);return null==e?n:di(n,e)}var oh=xa((function(t,e){t=ne(t);var n=-1,r=e.length,i=r>2?e[2]:a;i&&ss(e[0],e[1],i)&&(r=1);while(++n1),e})),io(t,No(t),n),r&&(n=mi(n,p|v|g,Vo));var i=e.length;while(i--)La(n,e[i]);return n}));function Eh(t,e){return Ph(t,zc(Ho(e)))}var Oh=Ro((function(t,e){return null==t?{}:da(t,e)}));function Ph(t,e){if(null==t)return{};var n=Tn(No(t),(function(t){return[t]}));return e=Ho(e),fa(t,n,(function(t,n){return e(t,n[0])}))}function Ih(t,e,n){e=Ya(e,t);var r=-1,i=e.length;i||(i=1,t=a);while(++re){var r=t;t=e,e=r}if(n||t%1||e%1){var i=Xe();return ze(t+i*(e-t+rn("1e-"+((i+"").length-1))),e)}return ma(t,e)}var Xh=po((function(t,e,n){return e=e.toLowerCase(),t+(n?Gh(e):e)}));function Gh(t){return xd(Qu(t).toLowerCase())}function Uh(t){return t=Qu(t),t&&t.replace(Qt,nr).replace(He,"")}function qh(t,e,n){t=Qu(t),e=Ma(e);var r=t.length;n=n===a?r:gi(Uu(n),0,r);var i=n;return n-=e.length,n>=0&&t.slice(n,i)==e}function Zh(t){return t=Qu(t),t&&Et.test(t)?t.replace(Dt,rr):t}function Kh(t){return t=Qu(t),t&&Bt.test(t)?t.replace(jt,"\\$&"):t}var Jh=po((function(t,e,n){return t+(n?"-":"")+e.toLowerCase()})),Qh=po((function(t,e,n){return t+(n?" ":"")+e.toLowerCase()})),td=fo("toLowerCase");function ed(t,e,n){t=Qu(t),e=Uu(e);var r=e?gr(t):0;if(!e||r>=e)return t;var i=(e-r)/2;return So(Ve(i),n)+t+So(Me(i),n)}function nd(t,e,n){t=Qu(t),e=Uu(e);var r=e?gr(t):0;return e&&r>>0,n?(t=Qu(t),t&&("string"==typeof e||null!=e&&!Lu(e))&&(e=Ma(e),!e&&or(t))?Wa(mr(t),0,n):t.split(e,n)):[]}var cd=po((function(t,e,n){return t+(n?" ":"")+xd(e)}));function ud(t,e,n){return t=Qu(t),n=null==n?0:gi(Uu(n),0,t.length),e=Ma(e),t.slice(n,n+e.length)==e}function hd(t,e,n){var r=wr.templateSettings;n&&ss(t,e,n)&&(e=a),t=Qu(t),e=nh({},e,r,Io);var o,s,l=nh({},e.imports,r.imports,Io),c=kh(l),h=Kn(l,c),d=0,f=e.interpolate||te,p="__p += '",v=re((e.escape||te).source+"|"+f.source+"|"+(f===It?Xt:te).source+"|"+(e.evaluate||te).source+"|$","g"),g="//# sourceURL="+(he.call(e,"sourceURL")?(e.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++Ze+"]")+"\n";t.replace(v,(function(e,n,r,i,a,l){return r||(r=i),p+=t.slice(d,l).replace(ee,ir),n&&(o=!0,p+="' +\n__e("+n+") +\n'"),a&&(s=!0,p+="';\n"+a+";\n__p += '"),r&&(p+="' +\n((__t = ("+r+")) == null ? '' : __t) +\n'"),d=l+e.length,e})),p+="';\n";var m=he.call(e,"variable")&&e.variable;if(m){if(Ht.test(m))throw new i(u)}else p="with (obj) {\n"+p+"\n}\n";p=(s?p.replace(St,""):p).replace(Ct,"$1").replace(At,"$1;"),p="function("+(m||"obj")+") {\n"+(m?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(o?", __e = _.escape":"")+(s?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+p+"return __p\n}";var y=kd((function(){return Ft(c,g+"return "+p).apply(a,h)}));if(y.source=p,bu(y))throw y;return y}function dd(t){return Qu(t).toLowerCase()}function fd(t){return Qu(t).toUpperCase()}function pd(t,e,n){if(t=Qu(t),t&&(n||e===a))return qn(t);if(!t||!(e=Ma(e)))return t;var r=mr(t),i=mr(e),o=Qn(r,i),s=tr(r,i)+1;return Wa(r,o,s).join("")}function vd(t,e,n){if(t=Qu(t),t&&(n||e===a))return t.slice(0,yr(t)+1);if(!t||!(e=Ma(e)))return t;var r=mr(t),i=tr(r,mr(e))+1;return Wa(r,0,i).join("")}function gd(t,e,n){if(t=Qu(t),t&&(n||e===a))return t.replace(Rt,"");if(!t||!(e=Ma(e)))return t;var r=mr(t),i=Qn(r,mr(e));return Wa(r,i).join("")}function md(t,e){var n=E,r=O;if(Cu(e)){var i="separator"in e?e.separator:i;n="length"in e?Uu(e.length):n,r="omission"in e?Ma(e.omission):r}t=Qu(t);var o=t.length;if(or(t)){var s=mr(t);o=s.length}if(n>=o)return t;var l=n-gr(r);if(l<1)return r;var c=s?Wa(s,0,l).join(""):t.slice(0,l);if(i===a)return c+r;if(s&&(l+=c.length-l),Lu(i)){if(t.slice(l).search(i)){var u,h=c;i.global||(i=re(i.source,Qu(Gt.exec(i))+"g")),i.lastIndex=0;while(u=i.exec(h))var d=u.index;c=c.slice(0,d===a?l:d)}}else if(t.indexOf(Ma(i),l)!=l){var f=c.lastIndexOf(i);f>-1&&(c=c.slice(0,f))}return c+r}function yd(t){return t=Qu(t),t&&Tt.test(t)?t.replace(_t,br):t}var bd=po((function(t,e,n){return t+(n?" ":"")+e.toUpperCase()})),xd=fo("toUpperCase");function wd(t,e,n){return t=Qu(t),e=n?a:e,e===a?sr(t)?kr(t):Ln(t):t.match(e)||[]}var kd=xa((function(t,e){try{return xn(t,a,e)}catch(n){return bu(n)?n:new i(n)}})),Sd=Ro((function(t,e){return kn(e,(function(e){e=Ps(e),pi(t,e,Ic(t[e],t))})),t}));function Cd(t){var e=null==t?0:t.length,n=Ho();return t=e?Tn(t,(function(t){if("function"!=typeof t[1])throw new ae(c);return[n(t[0]),t[1]]})):[],xa((function(n){var r=-1;while(++rB)return[];var n=N,r=ze(t,N);e=Ho(e),t-=N;var i=Gn(r,e);while(++n0||e<0)?new Dr(n):(t<0?n=n.takeRight(-t):t&&(n=n.drop(t)),e!==a&&(e=Uu(e),n=e<0?n.dropRight(-e):n.take(e-t)),n)},Dr.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},Dr.prototype.toArray=function(){return this.take(N)},Pi(Dr.prototype,(function(t,e){var n=/^(?:filter|find|map|reject)|While$/.test(e),r=/^(?:head|last)$/.test(e),i=wr[r?"take"+("last"==e?"Right":""):e],o=r||/^find/.test(e);i&&(wr.prototype[e]=function(){var e=this.__wrapped__,s=r?[1]:arguments,l=e instanceof Dr,c=s[0],u=l||lu(e),h=function(t){var e=i.apply(wr,En([t],s));return r&&d?e[0]:e};u&&n&&"function"==typeof c&&1!=c.length&&(l=u=!1);var d=this.__chain__,f=!!this.__actions__.length,p=o&&!d,v=l&&!f;if(!o&&u){e=v?e:new Dr(this);var g=t.apply(e,s);return g.__actions__.push({func:Gl,args:[h],thisArg:a}),new _r(g,d)}return p&&v?t.apply(this,s):(g=this.thru(h),p?r?g.value()[0]:g.value():g)})})),kn(["pop","push","shift","sort","splice","unshift"],(function(t){var e=oe[t],n=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",r=/^(?:pop|shift)$/.test(t);wr.prototype[t]=function(){var t=arguments;if(r&&!this.__chain__){var i=this.value();return e.apply(lu(i)?i:[],t)}return this[n]((function(n){return e.apply(lu(n)?n:[],t)}))}})),Pi(Dr.prototype,(function(t,e){var n=wr[e];if(n){var r=n.name+"";he.call(cn,r)||(cn[r]=[]),cn[r].push({name:e,func:n})}})),cn[bo(a,x).name]=[{name:"wrapper",func:a}],Dr.prototype.clone=Tr,Dr.prototype.reverse=Er,Dr.prototype.value=Or,wr.prototype.at=Ul,wr.prototype.chain=ql,wr.prototype.commit=Zl,wr.prototype.next=Kl,wr.prototype.plant=Ql,wr.prototype.reverse=tc,wr.prototype.toJSON=wr.prototype.valueOf=wr.prototype.value=ec,wr.prototype.first=wr.prototype.head,De&&(wr.prototype[De]=Jl),wr},Cr=Sr();ln._=Cr,i=function(){return Cr}.call(e,n,e,r),i===a||(r.exports=i)}).call(this)}).call(this,n("c8ba"),n("62e4")(t))},"2f21":function(t,e,n){"use strict";var r=n("79e5");t.exports=function(t,e){return!!t&&r((function(){e?t.call(null,(function(){}),1):t.call(null)}))}},"2f62":function(t,e,n){"use strict";(function(t){ +/*! + * vuex v3.6.2 + * (c) 2021 Evan You + * @license MIT + */ +function n(t){var e=Number(t.version.split(".")[0]);if(e>=2)t.mixin({beforeCreate:r});else{var n=t.prototype._init;t.prototype._init=function(t){void 0===t&&(t={}),t.init=t.init?[r].concat(t.init):r,n.call(this,t)}}function r(){var t=this.$options;t.store?this.$store="function"===typeof t.store?t.store():t.store:t.parent&&t.parent.$store&&(this.$store=t.parent.$store)}}var r="undefined"!==typeof window?window:"undefined"!==typeof t?t:{},i=r.__VUE_DEVTOOLS_GLOBAL_HOOK__;function a(t){i&&(t._devtoolHook=i,i.emit("vuex:init",t),i.on("vuex:travel-to-state",(function(e){t.replaceState(e)})),t.subscribe((function(t,e){i.emit("vuex:mutation",t,e)}),{prepend:!0}),t.subscribeAction((function(t,e){i.emit("vuex:action",t,e)}),{prepend:!0}))}function o(t,e){return t.filter(e)[0]}function s(t,e){if(void 0===e&&(e=[]),null===t||"object"!==typeof t)return t;var n=o(e,(function(e){return e.original===t}));if(n)return n.copy;var r=Array.isArray(t)?[]:{};return e.push({original:t,copy:r}),Object.keys(t).forEach((function(n){r[n]=s(t[n],e)})),r}function l(t,e){Object.keys(t).forEach((function(n){return e(t[n],n)}))}function c(t){return null!==t&&"object"===typeof t}function u(t){return t&&"function"===typeof t.then}function h(t,e){return function(){return t(e)}}var d=function(t,e){this.runtime=e,this._children=Object.create(null),this._rawModule=t;var n=t.state;this.state=("function"===typeof n?n():n)||{}},f={namespaced:{configurable:!0}};f.namespaced.get=function(){return!!this._rawModule.namespaced},d.prototype.addChild=function(t,e){this._children[t]=e},d.prototype.removeChild=function(t){delete this._children[t]},d.prototype.getChild=function(t){return this._children[t]},d.prototype.hasChild=function(t){return t in this._children},d.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)},d.prototype.forEachChild=function(t){l(this._children,t)},d.prototype.forEachGetter=function(t){this._rawModule.getters&&l(this._rawModule.getters,t)},d.prototype.forEachAction=function(t){this._rawModule.actions&&l(this._rawModule.actions,t)},d.prototype.forEachMutation=function(t){this._rawModule.mutations&&l(this._rawModule.mutations,t)},Object.defineProperties(d.prototype,f);var p=function(t){this.register([],t,!1)};function v(t,e,n){if(e.update(n),n.modules)for(var r in n.modules){if(!e.getChild(r))return void 0;v(t.concat(r),e.getChild(r),n.modules[r])}}p.prototype.get=function(t){return t.reduce((function(t,e){return t.getChild(e)}),this.root)},p.prototype.getNamespace=function(t){var e=this.root;return t.reduce((function(t,n){return e=e.getChild(n),t+(e.namespaced?n+"/":"")}),"")},p.prototype.update=function(t){v([],this.root,t)},p.prototype.register=function(t,e,n){var r=this;void 0===n&&(n=!0);var i=new d(e,n);if(0===t.length)this.root=i;else{var a=this.get(t.slice(0,-1));a.addChild(t[t.length-1],i)}e.modules&&l(e.modules,(function(e,i){r.register(t.concat(i),e,n)}))},p.prototype.unregister=function(t){var e=this.get(t.slice(0,-1)),n=t[t.length-1],r=e.getChild(n);r&&r.runtime&&e.removeChild(n)},p.prototype.isRegistered=function(t){var e=this.get(t.slice(0,-1)),n=t[t.length-1];return!!e&&e.hasChild(n)};var g;var m=function(t){var e=this;void 0===t&&(t={}),!g&&"undefined"!==typeof window&&window.Vue&&P(window.Vue);var n=t.plugins;void 0===n&&(n=[]);var r=t.strict;void 0===r&&(r=!1),this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new p(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._watcherVM=new g,this._makeLocalGettersCache=Object.create(null);var i=this,o=this,s=o.dispatch,l=o.commit;this.dispatch=function(t,e){return s.call(i,t,e)},this.commit=function(t,e,n){return l.call(i,t,e,n)},this.strict=r;var c=this._modules.root.state;k(this,c,[],this._modules.root),w(this,c),n.forEach((function(t){return t(e)}));var u=void 0!==t.devtools?t.devtools:g.config.devtools;u&&a(this)},y={state:{configurable:!0}};function b(t,e,n){return e.indexOf(t)<0&&(n&&n.prepend?e.unshift(t):e.push(t)),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}function x(t,e){t._actions=Object.create(null),t._mutations=Object.create(null),t._wrappedGetters=Object.create(null),t._modulesNamespaceMap=Object.create(null);var n=t.state;k(t,n,[],t._modules.root,!0),w(t,n,e)}function w(t,e,n){var r=t._vm;t.getters={},t._makeLocalGettersCache=Object.create(null);var i=t._wrappedGetters,a={};l(i,(function(e,n){a[n]=h(e,t),Object.defineProperty(t.getters,n,{get:function(){return t._vm[n]},enumerable:!0})}));var o=g.config.silent;g.config.silent=!0,t._vm=new g({data:{$$state:e},computed:a}),g.config.silent=o,t.strict&&T(t),r&&(n&&t._withCommit((function(){r._data.$$state=null})),g.nextTick((function(){return r.$destroy()})))}function k(t,e,n,r,i){var a=!n.length,o=t._modules.getNamespace(n);if(r.namespaced&&(t._modulesNamespaceMap[o],t._modulesNamespaceMap[o]=r),!a&&!i){var s=E(e,n.slice(0,-1)),l=n[n.length-1];t._withCommit((function(){g.set(s,l,r.state)}))}var c=r.context=S(t,o,n);r.forEachMutation((function(e,n){var r=o+n;A(t,r,e,c)})),r.forEachAction((function(e,n){var r=e.root?n:o+n,i=e.handler||e;_(t,r,i,c)})),r.forEachGetter((function(e,n){var r=o+n;D(t,r,e,c)})),r.forEachChild((function(r,a){k(t,e,n.concat(a),r,i)}))}function S(t,e,n){var r=""===e,i={dispatch:r?t.dispatch:function(n,r,i){var a=O(n,r,i),o=a.payload,s=a.options,l=a.type;return s&&s.root||(l=e+l),t.dispatch(l,o)},commit:r?t.commit:function(n,r,i){var a=O(n,r,i),o=a.payload,s=a.options,l=a.type;s&&s.root||(l=e+l),t.commit(l,o,s)}};return Object.defineProperties(i,{getters:{get:r?function(){return t.getters}:function(){return C(t,e)}},state:{get:function(){return E(t.state,n)}}}),i}function C(t,e){if(!t._makeLocalGettersCache[e]){var n={},r=e.length;Object.keys(t.getters).forEach((function(i){if(i.slice(0,r)===e){var a=i.slice(r);Object.defineProperty(n,a,{get:function(){return t.getters[i]},enumerable:!0})}})),t._makeLocalGettersCache[e]=n}return t._makeLocalGettersCache[e]}function A(t,e,n,r){var i=t._mutations[e]||(t._mutations[e]=[]);i.push((function(e){n.call(t,r.state,e)}))}function _(t,e,n,r){var i=t._actions[e]||(t._actions[e]=[]);i.push((function(e){var i=n.call(t,{dispatch:r.dispatch,commit:r.commit,getters:r.getters,state:r.state,rootGetters:t.getters,rootState:t.state},e);return u(i)||(i=Promise.resolve(i)),t._devtoolHook?i.catch((function(e){throw t._devtoolHook.emit("vuex:error",e),e})):i}))}function D(t,e,n,r){t._wrappedGetters[e]||(t._wrappedGetters[e]=function(t){return n(r.state,r.getters,t.state,t.getters)})}function T(t){t._vm.$watch((function(){return this._data.$$state}),(function(){0}),{deep:!0,sync:!0})}function E(t,e){return e.reduce((function(t,e){return t[e]}),t)}function O(t,e,n){return c(t)&&t.type&&(n=e,e=t,t=t.type),{type:t,payload:e,options:n}}function P(t){g&&t===g||(g=t,n(g))}y.state.get=function(){return this._vm._data.$$state},y.state.set=function(t){0},m.prototype.commit=function(t,e,n){var r=this,i=O(t,e,n),a=i.type,o=i.payload,s=(i.options,{type:a,payload:o}),l=this._mutations[a];l&&(this._withCommit((function(){l.forEach((function(t){t(o)}))})),this._subscribers.slice().forEach((function(t){return t(s,r.state)})))},m.prototype.dispatch=function(t,e){var n=this,r=O(t,e),i=r.type,a=r.payload,o={type:i,payload:a},s=this._actions[i];if(s){try{this._actionSubscribers.slice().filter((function(t){return t.before})).forEach((function(t){return t.before(o,n.state)}))}catch(c){0}var l=s.length>1?Promise.all(s.map((function(t){return t(a)}))):s[0](a);return new Promise((function(t,e){l.then((function(e){try{n._actionSubscribers.filter((function(t){return t.after})).forEach((function(t){return t.after(o,n.state)}))}catch(c){0}t(e)}),(function(t){try{n._actionSubscribers.filter((function(t){return t.error})).forEach((function(e){return e.error(o,n.state,t)}))}catch(c){0}e(t)}))}))}},m.prototype.subscribe=function(t,e){return b(t,this._subscribers,e)},m.prototype.subscribeAction=function(t,e){var n="function"===typeof t?{before:t}:t;return b(n,this._actionSubscribers,e)},m.prototype.watch=function(t,e,n){var r=this;return this._watcherVM.$watch((function(){return t(r.state,r.getters)}),e,n)},m.prototype.replaceState=function(t){var e=this;this._withCommit((function(){e._vm._data.$$state=t}))},m.prototype.registerModule=function(t,e,n){void 0===n&&(n={}),"string"===typeof t&&(t=[t]),this._modules.register(t,e),k(this,this.state,t,this._modules.get(t),n.preserveState),w(this,this.state)},m.prototype.unregisterModule=function(t){var e=this;"string"===typeof t&&(t=[t]),this._modules.unregister(t),this._withCommit((function(){var n=E(e.state,t.slice(0,-1));g.delete(n,t[t.length-1])})),x(this)},m.prototype.hasModule=function(t){return"string"===typeof t&&(t=[t]),this._modules.isRegistered(t)},m.prototype.hotUpdate=function(t){this._modules.update(t),x(this,!0)},m.prototype._withCommit=function(t){var e=this._committing;this._committing=!0,t(),this._committing=e},Object.defineProperties(m.prototype,y);var I=F((function(t,e){var n={};return B(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){var e=this.$store.state,n=this.$store.getters;if(t){var r=N(this.$store,"mapState",t);if(!r)return;e=r.context.state,n=r.context.getters}return"function"===typeof i?i.call(this,e,n):e[i]},n[r].vuex=!0})),n})),M=F((function(t,e){var n={};return B(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){var e=[],n=arguments.length;while(n--)e[n]=arguments[n];var r=this.$store.commit;if(t){var a=N(this.$store,"mapMutations",t);if(!a)return;r=a.context.commit}return"function"===typeof i?i.apply(this,[r].concat(e)):r.apply(this.$store,[i].concat(e))}})),n})),V=F((function(t,e){var n={};return B(e).forEach((function(e){var r=e.key,i=e.val;i=t+i,n[r]=function(){if(!t||N(this.$store,"mapGetters",t))return this.$store.getters[i]},n[r].vuex=!0})),n})),L=F((function(t,e){var n={};return B(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){var e=[],n=arguments.length;while(n--)e[n]=arguments[n];var r=this.$store.dispatch;if(t){var a=N(this.$store,"mapActions",t);if(!a)return;r=a.context.dispatch}return"function"===typeof i?i.apply(this,[r].concat(e)):r.apply(this.$store,[i].concat(e))}})),n})),j=function(t){return{mapState:I.bind(null,t),mapGetters:V.bind(null,t),mapMutations:M.bind(null,t),mapActions:L.bind(null,t)}};function B(t){return R(t)?Array.isArray(t)?t.map((function(t){return{key:t,val:t}})):Object.keys(t).map((function(e){return{key:e,val:t[e]}})):[]}function R(t){return Array.isArray(t)||c(t)}function F(t){return function(e,n){return"string"!==typeof e?(n=e,e=""):"/"!==e.charAt(e.length-1)&&(e+="/"),t(e,n)}}function N(t,e,n){var r=t._modulesNamespaceMap[n];return r}function z(t){void 0===t&&(t={});var e=t.collapsed;void 0===e&&(e=!0);var n=t.filter;void 0===n&&(n=function(t,e,n){return!0});var r=t.transformer;void 0===r&&(r=function(t){return t});var i=t.mutationTransformer;void 0===i&&(i=function(t){return t});var a=t.actionFilter;void 0===a&&(a=function(t,e){return!0});var o=t.actionTransformer;void 0===o&&(o=function(t){return t});var l=t.logMutations;void 0===l&&(l=!0);var c=t.logActions;void 0===c&&(c=!0);var u=t.logger;return void 0===u&&(u=console),function(t){var h=s(t.state);"undefined"!==typeof u&&(l&&t.subscribe((function(t,a){var o=s(a);if(n(t,h,o)){var l=H(),c=i(t),d="mutation "+t.type+l;$(u,d,e),u.log("%c prev state","color: #9E9E9E; font-weight: bold",r(h)),u.log("%c mutation","color: #03A9F4; font-weight: bold",c),u.log("%c next state","color: #4CAF50; font-weight: bold",r(o)),Y(u)}h=o})),c&&t.subscribeAction((function(t,n){if(a(t,n)){var r=H(),i=o(t),s="action "+t.type+r;$(u,s,e),u.log("%c action","color: #03A9F4; font-weight: bold",i),Y(u)}})))}}function $(t,e,n){var r=n?t.groupCollapsed:t.group;try{r.call(t,e)}catch(i){t.log(e)}}function Y(t){try{t.groupEnd()}catch(e){t.log("—— log end ——")}}function H(){var t=new Date;return" @ "+X(t.getHours(),2)+":"+X(t.getMinutes(),2)+":"+X(t.getSeconds(),2)+"."+X(t.getMilliseconds(),3)}function W(t,e){return new Array(e+1).join(t)}function X(t,e){return W("0",e-t.toString().length)+t}var G={Store:m,install:P,version:"3.6.2",mapState:I,mapMutations:M,mapGetters:V,mapActions:L,createNamespacedHelpers:j,createLogger:z};e["a"]=G}).call(this,n("c8ba"))},"2fcc":function(t,e){function n(t){var e=this.__data__,n=e["delete"](t);return this.size=e.size,n}t.exports=n},"2fdb":function(t,e,n){"use strict";var r=n("5ca1"),i=n("d2c8"),a="includes";r(r.P+r.F*n("5147")(a),"String",{includes:function(t){return!!~i(this,t,a).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},3024:function(t,e){t.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},"30c9":function(t,e,n){var r=n("9520"),i=n("b218");function a(t){return null!=t&&i(t.length)&&!r(t)}t.exports=a},"30f1":function(t,e,n){"use strict";var r=n("b8e3"),i=n("63b6"),a=n("9138"),o=n("35e8"),s=n("481b"),l=n("8f60"),c=n("45f2"),u=n("53e2"),h=n("5168")("iterator"),d=!([].keys&&"next"in[].keys()),f="@@iterator",p="keys",v="values",g=function(){return this};t.exports=function(t,e,n,m,y,b,x){l(n,e,m);var w,k,S,C=function(t){if(!d&&t in T)return T[t];switch(t){case p:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},A=e+" Iterator",_=y==v,D=!1,T=t.prototype,E=T[h]||T[f]||y&&T[y],O=E||C(y),P=y?_?C("entries"):O:void 0,I="Array"==e&&T.entries||E;if(I&&(S=u(I.call(new t)),S!==Object.prototype&&S.next&&(c(S,A,!0),r||"function"==typeof S[h]||o(S,h,g))),_&&E&&E.name!==v&&(D=!0,O=function(){return E.call(this)}),r&&!x||!d&&!D&&T[h]||o(T,h,O),s[e]=O,s[A]=g,y)if(w={values:_?O:C(v),keys:b?O:C(p),entries:P},x)for(k in w)k in T||a(T,k,w[k]);else i(i.P+i.F*(d||D),e,w);return w}},"31f4":function(t,e){t.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},"32b3":function(t,e,n){var r=n("872a"),i=n("9638"),a=Object.prototype,o=a.hasOwnProperty;function s(t,e,n){var a=t[e];o.call(t,e)&&i(a,n)&&(void 0!==n||e in t)||r(t,e,n)}t.exports=s},"32e9":function(t,e,n){var r=n("86cc"),i=n("4630");t.exports=n("9e1e")?function(t,e,n){return r.f(t,e,i(1,n))}:function(t,e,n){return t[e]=n,t}},"32f4":function(t,e,n){var r=n("2d7c"),i=n("d327"),a=Object.prototype,o=a.propertyIsEnumerable,s=Object.getOwnPropertySymbols,l=s?function(t){return null==t?[]:(t=Object(t),r(s(t),(function(e){return o.call(t,e)})))}:i;t.exports=l},"32fc":function(t,e,n){var r=n("e53d").document;t.exports=r&&r.documentElement},"335c":function(t,e,n){var r=n("6b4c");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},"33a4":function(t,e,n){var r=n("84f2"),i=n("2b4c")("iterator"),a=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||a[i]===t)}},"33de":function(t,e,n){var r;try{r={clone:n("b8ce"),constant:n("72f0"),each:n("c641"),filter:n("9380"),has:n("3852"),isArray:n("6747"),isEmpty:n("13ea"),isFunction:n("9520"),isUndefined:n("4cfe"),keys:n("ec69"),map:n("dd61"),reduce:n("c5a2"),size:n("d623"),transform:n("50ca"),union:n("bfc7"),values:n("3ff1")}}catch(i){}r||(r=window._),t.exports=r},"34ac":function(t,e,n){var r=n("9520"),i=n("1368"),a=n("1a8c"),o=n("dc57"),s=/[\\^$.*+?()[\]{}|]/g,l=/^\[object .+?Constructor\]$/,c=Function.prototype,u=Object.prototype,h=c.toString,d=u.hasOwnProperty,f=RegExp("^"+h.call(d).replace(s,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function p(t){if(!a(t)||i(t))return!1;var e=r(t)?f:l;return e.test(o(t))}t.exports=p},"34f3":function(t,e,n){"use strict";n.d(e,"a",(function(){return l}));var r={addEventListeners(t,e,n){for(let r=0,i=e.length;r=s.scrollWidth||0===s.scrollLeft,p=s.scrollTop+s.clientHeight>=s.scrollHeight||0===s.scrollTop;o=-t+(t=a?i.clientX:i.touches[0].clientX),d=-l+(l=a?i.clientY:i.touches[0].clientY),e.modifiers.pass?(s.scrollLeft-=e.modifiers.y?-0:o,s.scrollTop-=e.modifiers.x?-0:d,s===document.body&&(s.scrollLeft-=e.modifiers.y?-0:o,s.scrollTop-=e.modifiers.x?-0:d),(c||e.modifiers.y)&&u(-o,0),(p||e.modifiers.x)&&u(0,-d)):(e.modifiers.x&&(d=-0),e.modifiers.y&&(o=-0),s.scrollLeft-=o,s.scrollTop-=d,s===document.body&&(s.scrollLeft-=o,s.scrollTop-=d)),f.deltaX=-o,f.deltaY=-d,r.emitEvent(n,"dragscrollmove",f)}},r.addEventListeners(s,i,s.md),r.addEventListeners(window,o,s.mu),r.addEventListeners(window,a,s.mm)};l?"complete"===document.readyState?h():window.addEventListener("load",h):(r.removeEventListeners(s,i,s.md),r.removeEventListeners(window,o,s.mu),r.removeEventListeners(window,a,s.mm))};var l={inserted:function(t,e,n){s(t,e,n)},update:function(t,e,n,r){JSON.stringify(e.value)!==JSON.stringify(e.oldValue)&&s(t,e,n)},unbind:function(t,e,n){const s=t;r.removeEventListeners(s,i,s.md),r.removeEventListeners(window,o,s.mu),r.removeEventListeners(window,a,s.mm)}};const c=["mousedown","touchstart"],u=["mousemove","touchmove"],h=["mouseup","touchend"],d=function(t,e,n){let i=t,a=!0,o=window;"boolean"===typeof e.value?a=e.value:"object"===typeof e.value?("string"===typeof e.value.target?(i=t.querySelector(e.value.target),i||console.error("There is no element with the current target value.")):"undefined"!==typeof e.value.target&&console.error("The parameter \"target\" should be either 'undefined' or 'string'."),"string"===typeof e.value.container?(o=document.querySelector(e.value.container),o||console.error("There is no element with the current container value.")):"undefined"!==typeof e.value.container&&console.error("The parameter \"container\" should be be either 'undefined' or 'string'."),"boolean"===typeof e.value.active?a=e.value.active:"undefined"!==typeof e.value.active&&console.error("The parameter \"active\" value should be either 'undefined', 'true' or 'false'.")):"undefined"!==typeof e.value&&console.error("The passed value should be either 'undefined', 'true' or 'false' or 'object'.");const s=function(t,e){o===window?window.scrollBy(t,e):(o.scrollLeft+=t,o.scrollTop+=e)},l=function(){let t,a,o,l=!1;i.md=function(n){const r=n instanceof window.MouseEvent,s=r?n.pageX:n.touches[0].pageX,l=r?n.pageY:n.touches[0].pageY,c=document.elementFromPoint(s-window.pageXOffset,l-window.pageYOffset),u="nochilddrag"===e.arg,h=e.modifiers.noleft,d=e.modifiers.noright,f=e.modifiers.nomiddle,p=e.modifiers.noback,v=e.modifiers.noforward,g="firstchilddrag"===e.arg,m=c===i,y=c===i.firstChild,b=u?"undefined"!==typeof c.dataset.dragscroll:"undefined"===typeof c.dataset.noDragscroll;(m||b&&(!g||y))&&(1===n.which&&h||2===n.which&&f||3===n.which&&d||4===n.which&&p||5===n.which&&v||(o=1,t=r?n.clientX:n.touches[0].clientX,a=r?n.clientY:n.touches[0].clientY))},i.mu=function(t){o=0,l&&r.emitEvent2(n,"dragscrollend"),l=!1},i.mm=function(c){const u=c instanceof window.MouseEvent;let h,d;const f={};if(o){c.preventDefault(),l||r.emitEvent2(n,"dragscrollstart"),l=!0;const o=i.scrollLeft+i.clientWidth>=i.scrollWidth||0===i.scrollLeft,p=i.scrollTop+i.clientHeight>=i.scrollHeight||0===i.scrollTop;h=-t+(t=u?c.clientX:c.touches[0].clientX),d=-a+(a=u?c.clientY:c.touches[0].clientY),e.modifiers.pass?(i.scrollLeft-=e.modifiers.y?-0:h,i.scrollTop-=e.modifiers.x?-0:d,i===document.body&&(i.scrollLeft-=e.modifiers.y?-0:h,i.scrollTop-=e.modifiers.x?-0:d),(o||e.modifiers.y)&&s(-h,0),(p||e.modifiers.x)&&s(0,-d)):(e.modifiers.x&&(d=-0),e.modifiers.y&&(h=-0),i.scrollLeft-=h,i.scrollTop-=d,i===document.body&&(i.scrollLeft-=h,i.scrollTop-=d)),f.deltaX=-h,f.deltaY=-d,r.emitEvent2(n,"dragscrollmove",f)}},r.addEventListeners(i,c,i.md),r.addEventListeners(window,h,i.mu),r.addEventListeners(window,u,i.mm)};a?"complete"===document.readyState?l():window.addEventListener("load",l):(r.removeEventListeners(i,c,i.md),r.removeEventListeners(window,h,i.mu),r.removeEventListeners(window,u,i.mm))};var f={mounted:function(t,e,n){d(t,e,n)},updated:function(t,e,n,r){JSON.stringify(e.value)!==JSON.stringify(e.oldValue)&&d(t,e,n)},unmounted:function(t,e,n){const i=t;r.removeEventListeners(i,c,i.md),r.removeEventListeners(window,h,i.mu),r.removeEventListeners(window,u,i.mm)}};const p={install(t,e){const n=Number(t.version.split(".")[0]),r=Number(t.version.split(".")[1]);if(n<2&&r<1)throw new Error(`v-dragscroll supports vue version 2.1 and above. You are using Vue@${t.version}. Please upgrade to the latest version of Vue.`);t.directive("dragscroll",l)}};"undefined"!==typeof window&&window.Vue&&(window.Vue.version.split(".")[0]<=2?(window.VueDragscroll=p,window.Vue.use(p)):window.VueDragscroll=f)},"355d":function(t,e){e.f={}.propertyIsEnumerable},"35e8":function(t,e,n){var r=n("d9f6"),i=n("aebd");t.exports=n("8e60")?function(t,e,n){return r.f(t,e,i(1,n))}:function(t,e,n){return t[e]=n,t}},"366e":function(t,e,n){t.exports=n("ccb9").f("toPrimitive")},3698:function(t,e){function n(t,e){return null==t?void 0:t[e]}t.exports=n},"36bd":function(t,e,n){"use strict";var r=n("4bf8"),i=n("77f1"),a=n("9def");t.exports=function(t){var e=r(this),n=a(e.length),o=arguments.length,s=i(o>1?arguments[1]:void 0,n),l=o>2?arguments[2]:void 0,c=void 0===l?n:i(l,n);while(c>s)e[s++]=t;return e}},"36c3":function(t,e,n){var r=n("335c"),i=n("25eb");t.exports=function(t){return r(i(t))}},3702:function(t,e,n){var r=n("481b"),i=n("5168")("iterator"),a=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||a[i]===t)}},3729:function(t,e,n){var r=n("9e69"),i=n("00fd"),a=n("29f3"),o="[object Null]",s="[object Undefined]",l=r?r.toStringTag:void 0;function c(t){return null==t?void 0===t?s:o:l&&l in Object(t)?i(t):a(t)}t.exports=c},"37c8":function(t,e,n){e.f=n("2b4c")},3818:function(t,e,n){var r=n("7e64"),i=n("8057"),a=n("32b3"),o=n("5b01"),s=n("0f0f"),l=n("e538"),c=n("4359"),u=n("54eb"),h=n("1041"),d=n("a994"),f=n("1bac"),p=n("42a2"),v=n("c87c"),g=n("c2b6"),m=n("fa21"),y=n("6747"),b=n("0d24"),x=n("cc45"),w=n("1a8c"),k=n("d7ee"),S=n("ec69"),C=n("9934"),A=1,_=2,D=4,T="[object Arguments]",E="[object Array]",O="[object Boolean]",P="[object Date]",I="[object Error]",M="[object Function]",V="[object GeneratorFunction]",L="[object Map]",j="[object Number]",B="[object Object]",R="[object RegExp]",F="[object Set]",N="[object String]",z="[object Symbol]",$="[object WeakMap]",Y="[object ArrayBuffer]",H="[object DataView]",W="[object Float32Array]",X="[object Float64Array]",G="[object Int8Array]",U="[object Int16Array]",q="[object Int32Array]",Z="[object Uint8Array]",K="[object Uint8ClampedArray]",J="[object Uint16Array]",Q="[object Uint32Array]",tt={};function et(t,e,n,E,O,P){var I,L=e&A,j=e&_,R=e&D;if(n&&(I=O?n(t,E,O,P):n(t)),void 0!==I)return I;if(!w(t))return t;var F=y(t);if(F){if(I=v(t),!L)return c(t,I)}else{var N=p(t),z=N==M||N==V;if(b(t))return l(t,L);if(N==B||N==T||z&&!O){if(I=j||z?{}:m(t),!L)return j?h(t,s(I,t)):u(t,o(I,t))}else{if(!tt[N])return O?t:{};I=g(t,N,L)}}P||(P=new r);var $=P.get(t);if($)return $;P.set(t,I),k(t)?t.forEach((function(r){I.add(et(r,e,n,r,t,P))})):x(t)&&t.forEach((function(r,i){I.set(i,et(r,e,n,i,t,P))}));var Y=R?j?f:d:j?C:S,H=F?void 0:Y(t);return i(H||t,(function(r,i){H&&(i=r,r=t[i]),a(I,i,et(r,e,n,i,t,P))})),I}tt[T]=tt[E]=tt[Y]=tt[H]=tt[O]=tt[P]=tt[W]=tt[X]=tt[G]=tt[U]=tt[q]=tt[L]=tt[j]=tt[B]=tt[R]=tt[F]=tt[N]=tt[z]=tt[Z]=tt[K]=tt[J]=tt[Q]=!0,tt[I]=tt[M]=tt[$]=!1,t.exports=et},3846:function(t,e,n){n("9e1e")&&"g"!=/./g.flags&&n("86cc").f(RegExp.prototype,"flags",{configurable:!0,get:n("0bfb")})},3852:function(t,e,n){var r=n("96f3"),i=n("e2c0");function a(t,e){return null!=t&&i(t,e,r)}t.exports=a},"386d":function(t,e,n){"use strict";var r=n("cb7c"),i=n("83a1"),a=n("5f1b");n("214f")("search",1,(function(t,e,n,o){return[function(n){var r=t(this),i=void 0==n?void 0:n[e];return void 0!==i?i.call(n,r):new RegExp(n)[e](String(r))},function(t){var e=o(n,t,this);if(e.done)return e.value;var s=r(t),l=String(this),c=s.lastIndex;i(c,0)||(s.lastIndex=0);var u=a(s,l);return i(s.lastIndex,c)||(s.lastIndex=c),null===u?-1:u.index}]}))},"38e2":function(t,e,n){var r=n("6f9c"),i=n("1f3a"),a=n("d9f3"),o=n("f352");function s(t,e,n,u){var h=t.children(e),d=t.node(e),f=d?d.borderLeft:void 0,p=d?d.borderRight:void 0,v={};f&&(h=r.filter(h,(function(t){return t!==f&&t!==p})));var g=i(t,h);r.forEach(g,(function(e){if(t.children(e.v).length){var i=s(t,e.v,n,u);v[e.v]=i,r.has(i,"barycenter")&&c(e,i)}}));var m=a(g,n);l(m,v);var y=o(m,u);if(f&&(y.vs=r.flatten([f,y.vs,p],!0),t.predecessors(f).length)){var b=t.node(t.predecessors(f)[0]),x=t.node(t.predecessors(p)[0]);r.has(y,"barycenter")||(y.barycenter=0,y.weight=0),y.barycenter=(y.barycenter*y.weight+b.order+x.order)/(y.weight+2),y.weight+=2}return y}function l(t,e){r.forEach(t,(function(t){t.vs=r.flatten(t.vs.map((function(t){return e[t]?e[t].vs:t})),!0)}))}function c(t,e){r.isUndefined(t.barycenter)?(t.barycenter=e.barycenter,t.weight=e.weight):(t.barycenter=(t.barycenter*t.weight+e.barycenter*e.weight)/(t.weight+e.weight),t.weight+=e.weight)}t.exports=s},"38fd":function(t,e,n){var r=n("69a8"),i=n("4bf8"),a=n("613b")("IE_PROTO"),o=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),r(t,a)?t[a]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?o:null}},"39ff":function(t,e,n){var r=n("0b07"),i=n("2b3e"),a=r(i,"WeakMap");t.exports=a},"3a38":function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},"3a72":function(t,e,n){var r=n("7726"),i=n("8378"),a=n("2d00"),o=n("37c8"),s=n("86cc").f;t.exports=function(t){var e=i.Symbol||(i.Symbol=a?{}:r.Symbol||{});"_"==t.charAt(0)||t in e||s(e,t,{value:o.f(t)})}},"3b2b":function(t,e,n){var r=n("7726"),i=n("5dbc"),a=n("86cc").f,o=n("9093").f,s=n("aae3"),l=n("0bfb"),c=r.RegExp,u=c,h=c.prototype,d=/a/g,f=/a/g,p=new c(d)!==d;if(n("9e1e")&&(!p||n("79e5")((function(){return f[n("2b4c")("match")]=!1,c(d)!=d||c(f)==f||"/a/i"!=c(d,"i")})))){c=function(t,e){var n=this instanceof c,r=s(t),a=void 0===e;return!n&&r&&t.constructor===c&&a?t:i(p?new u(r&&!a?t.source:t,e):u((r=t instanceof c)?t.source:t,r&&a?l.call(t):e),n?this:h,c)};for(var v=function(t){t in c||a(c,t,{configurable:!0,get:function(){return u[t]},set:function(e){u[t]=e}})},g=o(u),m=0;g.length>m;)v(g[m++]);h.constructor=c,c.prototype=h,n("2aba")(r,"RegExp",c)}n("7a56")("RegExp")},"3b4a":function(t,e,n){var r=n("0b07"),i=function(){try{var t=r(Object,"defineProperty");return t({},"",{}),t}catch(e){}}();t.exports=i},"3b8d":function(t,e,n){"use strict";n.d(e,"a",(function(){return o}));var r=n("696e"),i=n.n(r);function a(t,e,n,r,a,o,s){try{var l=t[o](s),c=l.value}catch(t){return void n(t)}l.done?e(c):i.a.resolve(c).then(r,a)}function o(t){return function(){var e=this,n=arguments;return new i.a((function(r,i){var o=t.apply(e,n);function s(t){a(o,r,i,s,l,"next",t)}function l(t){a(o,r,i,s,l,"throw",t)}s(void 0)}))}}},"3bb4":function(t,e,n){var r=n("08cc"),i=n("ec69");function a(t){var e=i(t),n=e.length;while(n--){var a=e[n],o=t[a];e[n]=[a,o,r(o)]}return e}t.exports=a},"3c11":function(t,e,n){"use strict";var r=n("63b6"),i=n("584a"),a=n("e53d"),o=n("f201"),s=n("cd78");r(r.P+r.R,"Promise",{finally:function(t){var e=o(this,i.Promise||a.Promise),n="function"==typeof t;return this.then(n?function(n){return s(e,t()).then((function(){return n}))}:t,n?function(n){return s(e,t()).then((function(){throw n}))}:t)}})},"3d1e":function(t,e,n){var r; +/*! + * ApexCharts v3.54.1 + * (c) 2018-2024 ApexCharts + * Released under the MIT License. + */!function(e,n){t.exports=n()}(0,(function(){"use strict";function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,o=!0,s=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return o=t.done,t},e:function(t){s=!0,a=t},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw a}}}}function u(t){var e=p();return function(){var n,r=d(t);if(e){var i=d(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return function(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return a(t)}(this,n)}}function h(t,e,n){return(e=x(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function d(t){return d=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},d(t)}function f(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&m(t,e)}function p(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(t){}return(p=function(){return!!t})()}function v(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function g(t){for(var e=1;e>16,o=n>>8&255,s=255&n;return"#"+(16777216+65536*(Math.round((r-a)*i)+a)+256*(Math.round((r-o)*i)+o)+(Math.round((r-s)*i)+s)).toString(16).slice(1)}},{key:"shadeColor",value:function(e,n){return t.isColorHex(n)?this.shadeHexColor(e,n):this.shadeRGBColor(e,n)}}],[{key:"bind",value:function(t,e){return function(){return t.apply(e,arguments)}}},{key:"isObject",value:function(t){return t&&"object"===w(t)&&!Array.isArray(t)&&null!=t}},{key:"is",value:function(t,e){return Object.prototype.toString.call(e)==="[object "+t+"]"}},{key:"listToArray",value:function(t){var e,n=[];for(e=0;e1&&void 0!==arguments[1]?arguments[1]:2;return Number.isInteger(t)?t:parseFloat(t.toPrecision(e))}},{key:"randomId",value:function(){return(Math.random()+1).toString(36).substring(4)}},{key:"noExponents",value:function(t){var e=String(t).split(/[eE]/);if(1===e.length)return e[0];var n="",r=t<0?"-":"",i=e[0].replace(".",""),a=Number(e[1])+1;if(a<0){for(n=r+"0.";a++;)n+="0";return n+i.replace(/^-/,"")}for(a-=i.length;a--;)n+="0";return i+n}},{key:"getDimensions",value:function(t){var e=getComputedStyle(t,null),n=t.clientHeight,r=t.clientWidth;return n-=parseFloat(e.paddingTop)+parseFloat(e.paddingBottom),[r-=parseFloat(e.paddingLeft)+parseFloat(e.paddingRight),n]}},{key:"getBoundingClientRect",value:function(t){var e=t.getBoundingClientRect();return{top:e.top,right:e.right,bottom:e.bottom,left:e.left,width:t.clientWidth,height:t.clientHeight,x:e.left,y:e.top}}},{key:"getLargestStringFromArr",value:function(t){return t.reduce((function(t,e){return Array.isArray(e)&&(e=e.reduce((function(t,e){return t.length>e.length?t:e}))),t.length>e.length?t:e}),0)}},{key:"hexToRgba",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"#999999",e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:.6;"#"!==t.substring(0,1)&&(t="#999999");var n=t.replace("#","");n=n.match(new RegExp("(.{"+n.length/3+"})","g"));for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:"x",n=t.toString().slice();return n.replace(/[` ~!@#$%^&*()|+\=?;:'",.<>{}[\]\\/]/gi,e)}},{key:"negToZero",value:function(t){return t<0?0:t}},{key:"moveIndexInArray",value:function(t,e,n){if(n>=t.length)for(var r=n-t.length+1;r--;)t.push(void 0);return t.splice(n,0,t.splice(e,1)[0]),t}},{key:"extractNumber",value:function(t){return parseFloat(t.replace(/[^\d.]*/g,""))}},{key:"findAncestor",value:function(t,e){for(;(t=t.parentElement)&&!t.classList.contains(e););return t}},{key:"setELstyles",value:function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t.style.key=e[n])}},{key:"preciseAddition",value:function(t,e){var n=(String(t).split(".")[1]||"").length,r=(String(e).split(".")[1]||"").length,i=Math.pow(10,Math.max(n,r));return(Math.round(t*i)+Math.round(e*i))/i}},{key:"isNumber",value:function(t){return!isNaN(t)&&parseFloat(Number(t))===t&&!isNaN(parseInt(t,10))}},{key:"isFloat",value:function(t){return Number(t)===t&&t%1!=0}},{key:"isSafari",value:function(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}},{key:"isFirefox",value:function(){return navigator.userAgent.toLowerCase().indexOf("firefox")>-1}},{key:"isMsEdge",value:function(){var t=window.navigator.userAgent,e=t.indexOf("Edge/");return e>0&&parseInt(t.substring(e+5,t.indexOf(".",e)),10)}},{key:"getGCD",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:7,r=Math.pow(10,n-Math.floor(Math.log10(Math.max(t,e))));for(t=Math.round(Math.abs(t)*r),e=Math.round(Math.abs(e)*r);e;){var i=e;e=t%e,t=i}return t/r}},{key:"getPrimeFactors",value:function(t){for(var e=[],n=2;t>=2;)t%n==0?(e.push(n),t/=n):n++;return e}},{key:"mod",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:7,r=Math.pow(10,n-Math.floor(Math.log10(Math.max(t,e))));return(t=Math.round(Math.abs(t)*r))%(e=Math.round(Math.abs(e)*r))/r}}]),t}(),C=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.setEasingFunctions()}return l(t,[{key:"setEasingFunctions",value:function(){var t;if(!this.w.globals.easing){switch(this.w.config.chart.animations.easing){case"linear":t="-";break;case"easein":t="<";break;case"easeout":t=">";break;case"easeinout":default:t="<>";break;case"swing":t=function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1};break;case"bounce":t=function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375};break;case"elastic":t=function(t){return t===!!t?t:Math.pow(2,-10*t)*Math.sin((t-.075)*(2*Math.PI)/.3)+1}}this.w.globals.easing=t}}},{key:"animateLine",value:function(t,e,n,r){t.attr(e).animate(r).attr(n)}},{key:"animateMarker",value:function(t,e,n,r){t.attr({opacity:0}).animate(e,n).attr({opacity:1}).afterAll((function(){r()}))}},{key:"animateRect",value:function(t,e,n,r,i){t.attr(e).animate(r).attr(n).afterAll((function(){return i()}))}},{key:"animatePathsGradually",value:function(t){var e=t.el,n=t.realIndex,r=t.j,i=t.fill,a=t.pathFrom,o=t.pathTo,s=t.speed,l=t.delay,c=this.w,u=0;c.config.chart.animations.animateGradually.enabled&&(u=c.config.chart.animations.animateGradually.delay),c.config.chart.animations.dynamicAnimation.enabled&&c.globals.dataChanged&&"bar"!==c.config.chart.type&&(u=0),this.morphSVG(e,n,r,"line"!==c.config.chart.type||c.globals.comboCharts?i:"stroke",a,o,s,l*u)}},{key:"showDelayedElements",value:function(){this.w.globals.delayedElements.forEach((function(t){var e=t.el;e.classList.remove("apexcharts-element-hidden"),e.classList.add("apexcharts-hidden-element-shown")}))}},{key:"animationCompleted",value:function(t){var e=this.w;e.globals.animationEnded||(e.globals.animationEnded=!0,this.showDelayedElements(),"function"==typeof e.config.chart.events.animationEnd&&e.config.chart.events.animationEnd(this.ctx,{el:t,w:e}))}},{key:"morphSVG",value:function(t,e,n,r,i,a,o,s){var l=this,c=this.w;i||(i=t.attr("pathFrom")),a||(a=t.attr("pathTo"));var u=function(t){return"radar"===c.config.chart.type&&(o=1),"M 0 ".concat(c.globals.gridHeight)};(!i||i.indexOf("undefined")>-1||i.indexOf("NaN")>-1)&&(i=u()),(!a||a.indexOf("undefined")>-1||a.indexOf("NaN")>-1)&&(a=u()),c.globals.shouldAnimate||(o=1),t.plot(i).animate(1,c.globals.easing,s).plot(i).animate(o,c.globals.easing,s).plot(a).afterAll((function(){S.isNumber(n)?n===c.globals.series[c.globals.maxValsInArrayIndex].length-2&&c.globals.shouldAnimate&&l.animationCompleted(t):"none"!==r&&c.globals.shouldAnimate&&(!c.globals.comboCharts&&e===c.globals.series.length-1||c.globals.comboCharts)&&l.animationCompleted(t),l.showDelayedElements()}))}}]),t}(),A=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"getDefaultFilter",value:function(t,e){var n=this.w;t.unfilter(!0),(new window.SVG.Filter).size("120%","180%","-5%","-40%"),"none"!==n.config.states.normal.filter?this.applyFilter(t,e,n.config.states.normal.filter.type,n.config.states.normal.filter.value):n.config.chart.dropShadow.enabled&&this.dropShadow(t,n.config.chart.dropShadow,e)}},{key:"addNormalFilter",value:function(t,e){var n=this.w;n.config.chart.dropShadow.enabled&&!t.node.classList.contains("apexcharts-marker")&&this.dropShadow(t,n.config.chart.dropShadow,e)}},{key:"addLightenFilter",value:function(t,e,n){var r=this,i=this.w,a=n.intensity;t.unfilter(!0),new window.SVG.Filter,t.filter((function(t){var n=i.config.chart.dropShadow;(n.enabled?r.addShadow(t,e,n):t).componentTransfer({rgb:{type:"linear",slope:1.5,intercept:a}})})),t.filterer.node.setAttribute("filterUnits","userSpaceOnUse"),this._scaleFilterSize(t.filterer.node)}},{key:"addDarkenFilter",value:function(t,e,n){var r=this,i=this.w,a=n.intensity;t.unfilter(!0),new window.SVG.Filter,t.filter((function(t){var n=i.config.chart.dropShadow;(n.enabled?r.addShadow(t,e,n):t).componentTransfer({rgb:{type:"linear",slope:a}})})),t.filterer.node.setAttribute("filterUnits","userSpaceOnUse"),this._scaleFilterSize(t.filterer.node)}},{key:"applyFilter",value:function(t,e,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:.5;switch(n){case"none":this.addNormalFilter(t,e);break;case"lighten":this.addLightenFilter(t,e,{intensity:r});break;case"darken":this.addDarkenFilter(t,e,{intensity:r})}}},{key:"addShadow",value:function(t,e,n){var r,i=this.w,a=n.blur,o=n.top,s=n.left,l=n.color,c=n.opacity;if((null===(r=i.config.chart.dropShadow.enabledOnSeries)||void 0===r?void 0:r.length)>0&&-1===i.config.chart.dropShadow.enabledOnSeries.indexOf(e))return t;var u=t.flood(Array.isArray(l)?l[e]:l,c).composite(t.sourceAlpha,"in").offset(s,o).gaussianBlur(a).merge(t.source);return t.blend(t.source,u)}},{key:"dropShadow",value:function(t,e){var n,r,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,a=e.top,o=e.left,s=e.blur,l=e.color,c=e.opacity,u=e.noUserSpaceOnUse,h=this.w;return t.unfilter(!0),S.isMsEdge()&&"radialBar"===h.config.chart.type||(null===(n=h.config.chart.dropShadow.enabledOnSeries)||void 0===n?void 0:n.length)>0&&-1===(null===(r=h.config.chart.dropShadow.enabledOnSeries)||void 0===r?void 0:r.indexOf(i))||(l=Array.isArray(l)?l[i]:l,t.filter((function(t){var e=null;e=S.isSafari()||S.isFirefox()||S.isMsEdge()?t.flood(l,c).composite(t.sourceAlpha,"in").offset(o,a).gaussianBlur(s):t.flood(l,c).composite(t.sourceAlpha,"in").offset(o,a).gaussianBlur(s).merge(t.source),t.blend(t.source,e)})),u||t.filterer.node.setAttribute("filterUnits","userSpaceOnUse"),this._scaleFilterSize(t.filterer.node)),t}},{key:"setSelectionFilter",value:function(t,e,n){var r=this.w;if(void 0!==r.globals.selectedDataPoints[e]&&r.globals.selectedDataPoints[e].indexOf(n)>-1){t.node.setAttribute("selected",!0);var i=r.config.states.active.filter;"none"!==i&&this.applyFilter(t,e,i.type,i.value)}}},{key:"_scaleFilterSize",value:function(t){!function(e){for(var n in e)e.hasOwnProperty(n)&&t.setAttribute(n,e[n])}({width:"200%",height:"200%",x:"-50%",y:"-50%"})}}]),t}(),_=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"roundPathCorners",value:function(t,e){function n(t,e,n){var i=e.x-t.x,a=e.y-t.y,o=Math.sqrt(i*i+a*a);return r(t,e,Math.min(1,n/o))}function r(t,e,n){return{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n}}function i(t,e){t.length>2&&(t[t.length-2]=e.x,t[t.length-1]=e.y)}function a(t){return{x:parseFloat(t[t.length-2]),y:parseFloat(t[t.length-1])}}t.indexOf("NaN")>-1&&(t="");var o=t.split(/[,\s]/).reduce((function(t,e){var n=e.match("([a-zA-Z])(.+)");return n?(t.push(n[1]),t.push(n[2])):t.push(e),t}),[]).reduce((function(t,e){return parseFloat(e)==e&&t.length?t[t.length-1].push(e):t.push([e]),t}),[]),s=[];if(o.length>1){var l=a(o[0]),c=null;"Z"==o[o.length-1][0]&&o[0].length>2&&(c=["L",l.x,l.y],o[o.length-1]=c),s.push(o[0]);for(var u=1;u2&&"L"==d[0]&&f.length>2&&"L"==f[0]){var p,v,g=a(h),m=a(d),y=a(f);p=n(m,g,e),v=n(m,y,e),i(d,p),d.origPoint=m,s.push(d);var b=r(p,m,.5),x=r(m,v,.5),w=["C",b.x,b.y,x.x,x.y,v.x,v.y];w.origPoint=m,s.push(w)}else s.push(d)}if(c){var k=a(s[s.length-1]);s.push(["Z"]),i(s[0],k)}}else s=o;return s.reduce((function(t,e){return t+e.join(" ")+" "}),"")}},{key:"drawLine",value:function(t,e,n,r){var i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"#a8a8a8",a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0,o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null,s=arguments.length>7&&void 0!==arguments[7]?arguments[7]:"butt";return this.w.globals.dom.Paper.line().attr({x1:t,y1:e,x2:n,y2:r,stroke:i,"stroke-dasharray":a,"stroke-width":o,"stroke-linecap":s})}},{key:"drawRect",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"#fefefe",o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:1,s=arguments.length>7&&void 0!==arguments[7]?arguments[7]:null,l=arguments.length>8&&void 0!==arguments[8]?arguments[8]:null,c=arguments.length>9&&void 0!==arguments[9]?arguments[9]:0,u=this.w.globals.dom.Paper.rect();return u.attr({x:t,y:e,width:n>0?n:0,height:r>0?r:0,rx:i,ry:i,opacity:o,"stroke-width":null!==s?s:0,stroke:null!==l?l:"none","stroke-dasharray":c}),u.node.setAttribute("fill",a),u}},{key:"drawPolygon",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"#e1e1e1",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"none";return this.w.globals.dom.Paper.polygon(t).attr({fill:r,stroke:e,"stroke-width":n})}},{key:"drawCircle",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;t<0&&(t=0);var n=this.w.globals.dom.Paper.circle(2*t);return null!==e&&n.attr(e),n}},{key:"drawPath",value:function(t){var e=t.d,n=void 0===e?"":e,r=t.stroke,i=void 0===r?"#a8a8a8":r,a=t.strokeWidth,o=void 0===a?1:a,s=t.fill,l=t.fillOpacity,c=void 0===l?1:l,u=t.strokeOpacity,h=void 0===u?1:u,d=t.classes,f=t.strokeLinecap,p=void 0===f?null:f,v=t.strokeDashArray,g=void 0===v?0:v,m=this.w;return null===p&&(p=m.config.stroke.lineCap),(n.indexOf("undefined")>-1||n.indexOf("NaN")>-1)&&(n="M 0 ".concat(m.globals.gridHeight)),m.globals.dom.Paper.path(n).attr({fill:s,"fill-opacity":c,stroke:i,"stroke-opacity":h,"stroke-linecap":p,"stroke-width":o,"stroke-dasharray":g,class:d})}},{key:"group",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=this.w.globals.dom.Paper.group();return null!==t&&e.attr(t),e}},{key:"move",value:function(t,e){var n=["M",t,e].join(" ");return n}},{key:"line",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=null;return null===n?r=[" L",t,e].join(" "):"H"===n?r=[" H",t].join(" "):"V"===n&&(r=[" V",e].join(" ")),r}},{key:"curve",value:function(t,e,n,r,i,a){var o=["C",t,e,n,r,i,a].join(" ");return o}},{key:"quadraticCurve",value:function(t,e,n,r){return["Q",t,e,n,r].join(" ")}},{key:"arc",value:function(t,e,n,r,i,a,o){var s="A";arguments.length>7&&void 0!==arguments[7]&&arguments[7]&&(s="a");var l=[s,t,e,n,r,i,a,o].join(" ");return l}},{key:"renderPaths",value:function(t){var e,n=t.j,r=t.realIndex,i=t.pathFrom,a=t.pathTo,o=t.stroke,s=t.strokeWidth,l=t.strokeLinecap,c=t.fill,u=t.animationDelay,h=t.initialSpeed,d=t.dataChangeSpeed,f=t.className,p=t.chartType,v=t.shouldClipToGrid,m=void 0===v||v,y=t.bindEventsOnPaths,b=void 0===y||y,x=t.drawShadow,w=void 0===x||x,k=this.w,S=new A(this.ctx),_=new C(this.ctx),D=this.w.config.chart.animations.enabled,T=D&&this.w.config.chart.animations.dynamicAnimation.enabled,E=!!(D&&!k.globals.resized||T&&k.globals.dataChanged&&k.globals.shouldAnimate);E?e=i:(e=a,k.globals.animationEnded=!0);var O=k.config.stroke.dashArray,P=0;P=Array.isArray(O)?O[r]:k.config.stroke.dashArray;var I=this.drawPath({d:e,stroke:o,strokeWidth:s,fill:c,fillOpacity:1,classes:f,strokeLinecap:l,strokeDashArray:P});if(I.attr("index",r),m&&("bar"===p&&!k.globals.isHorizontal||k.globals.comboCharts?I.attr({"clip-path":"url(#gridRectBarMask".concat(k.globals.cuid,")")}):I.attr({"clip-path":"url(#gridRectMask".concat(k.globals.cuid,")")})),"none"!==k.config.states.normal.filter.type)S.getDefaultFilter(I,r);else if(k.config.chart.dropShadow.enabled&&w){var M=k.config.chart.dropShadow;S.dropShadow(I,M,r)}b&&(I.node.addEventListener("mouseenter",this.pathMouseEnter.bind(this,I)),I.node.addEventListener("mouseleave",this.pathMouseLeave.bind(this,I)),I.node.addEventListener("mousedown",this.pathMouseDown.bind(this,I))),I.attr({pathTo:a,pathFrom:i});var V={el:I,j:n,realIndex:r,pathFrom:i,pathTo:a,fill:c,strokeWidth:s,delay:u};return!D||k.globals.resized||k.globals.dataChanged?!k.globals.resized&&k.globals.dataChanged||_.showDelayedElements():_.animatePathsGradually(g(g({},V),{},{speed:h})),k.globals.dataChanged&&T&&E&&_.animatePathsGradually(g(g({},V),{},{speed:d})),I}},{key:"drawPattern",value:function(t,e,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"#a8a8a8",i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0;return this.w.globals.dom.Paper.pattern(e,n,(function(a){"horizontalLines"===t?a.line(0,0,n,0).stroke({color:r,width:i+1}):"verticalLines"===t?a.line(0,0,0,e).stroke({color:r,width:i+1}):"slantedLines"===t?a.line(0,0,e,n).stroke({color:r,width:i}):"squares"===t?a.rect(e,n).fill("none").stroke({color:r,width:i}):"circles"===t&&a.circle(e).fill("none").stroke({color:r,width:i})}))}},{key:"drawGradient",value:function(t,e,n,r,i){var a,o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,s=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null,l=arguments.length>7&&void 0!==arguments[7]?arguments[7]:null,c=arguments.length>8&&void 0!==arguments[8]?arguments[8]:0,u=this.w;e.length<9&&0===e.indexOf("#")&&(e=S.hexToRgba(e,r)),n.length<9&&0===n.indexOf("#")&&(n=S.hexToRgba(n,i));var h=0,d=1,f=1,p=null;null!==s&&(h=void 0!==s[0]?s[0]/100:0,d=void 0!==s[1]?s[1]/100:1,f=void 0!==s[2]?s[2]/100:1,p=void 0!==s[3]?s[3]/100:null);var v=!("donut"!==u.config.chart.type&&"pie"!==u.config.chart.type&&"polarArea"!==u.config.chart.type&&"bubble"!==u.config.chart.type);if(a=null===l||0===l.length?u.globals.dom.Paper.gradient(v?"radial":"linear",(function(t){t.at(h,e,r),t.at(d,n,i),t.at(f,n,i),null!==p&&t.at(p,e,r)})):u.globals.dom.Paper.gradient(v?"radial":"linear",(function(t){(Array.isArray(l[c])?l[c]:l).forEach((function(e){t.at(e.offset/100,e.color,e.opacity)}))})),v){var g=u.globals.gridWidth/2,m=u.globals.gridHeight/2;"bubble"!==u.config.chart.type?a.attr({gradientUnits:"userSpaceOnUse",cx:g,cy:m,r:o}):a.attr({cx:.5,cy:.5,r:.8,fx:.2,fy:.2})}else"vertical"===t?a.from(0,0).to(0,1):"diagonal"===t?a.from(0,0).to(1,1):"horizontal"===t?a.from(0,1).to(1,1):"diagonal2"===t&&a.from(1,0).to(0,1);return a}},{key:"getTextBasedOnMaxWidth",value:function(t){var e=t.text,n=t.maxWidth,r=t.fontSize,i=t.fontFamily,a=this.getTextRects(e,r,i),o=a.width/e.length,s=Math.floor(n/o);return n-1){var s=n.globals.selectedDataPoints[i].indexOf(a);n.globals.selectedDataPoints[i].splice(s,1)}}else{if(!n.config.states.active.allowMultipleDataPointsSelection&&n.globals.selectedDataPoints.length>0){n.globals.selectedDataPoints=[];var l=n.globals.dom.Paper.select(".apexcharts-series path").members,c=n.globals.dom.Paper.select(".apexcharts-series circle, .apexcharts-series rect").members,u=function(t){Array.prototype.forEach.call(t,(function(t){t.node.setAttribute("selected","false"),r.getDefaultFilter(t,i)}))};u(l),u(c)}t.node.setAttribute("selected","true"),o="true",void 0===n.globals.selectedDataPoints[i]&&(n.globals.selectedDataPoints[i]=[]),n.globals.selectedDataPoints[i].push(a)}if("true"===o){var h=n.config.states.active.filter;if("none"!==h)r.applyFilter(t,i,h.type,h.value);else if("none"!==n.config.states.hover.filter&&!n.globals.isTouchDevice){var d=n.config.states.hover.filter;r.applyFilter(t,i,d.type,d.value)}}else"none"!==n.config.states.active.filter.type&&("none"===n.config.states.hover.filter.type||n.globals.isTouchDevice?r.getDefaultFilter(t,i):(d=n.config.states.hover.filter,r.applyFilter(t,i,d.type,d.value)));"function"==typeof n.config.chart.events.dataPointSelection&&n.config.chart.events.dataPointSelection(e,this.ctx,{selectedDataPoints:n.globals.selectedDataPoints,seriesIndex:i,dataPointIndex:a,w:n}),e&&this.ctx.events.fireEvent("dataPointSelection",[e,this.ctx,{selectedDataPoints:n.globals.selectedDataPoints,seriesIndex:i,dataPointIndex:a,w:n}])}},{key:"rotateAroundCenter",value:function(t){var e={};return t&&"function"==typeof t.getBBox&&(e=t.getBBox()),{x:e.x+e.width/2,y:e.y+e.height/2}}},{key:"getTextRects",value:function(t,e,n,r){var i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=this.w,o=this.drawText({x:-200,y:-200,text:t,textAnchor:"start",fontSize:e,fontFamily:n,foreColor:"#fff",opacity:0});r&&o.attr("transform",r),a.globals.dom.Paper.add(o);var s=o.bbox();return i||(s=o.node.getBoundingClientRect()),o.remove(),{width:s.width,height:s.height}}},{key:"placeTextWithEllipsis",value:function(t,e,n){if("function"==typeof t.getComputedTextLength&&(t.textContent=e,e.length>0&&t.getComputedTextLength()>=n/1.1)){for(var r=e.length-3;r>0;r-=3)if(t.getSubStringLength(0,r)<=n/1.1)return void(t.textContent=e.substring(0,r)+"...");t.textContent="."}}}],[{key:"setAttrs",value:function(t,e){for(var n in e)e.hasOwnProperty(n)&&t.setAttribute(n,e[n])}}]),t}(),D=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"getStackedSeriesTotals",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=this.w,n=[];if(0===e.globals.series.length)return n;for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:null;return null===t?this.w.config.series.reduce((function(t,e){return t+e}),0):this.w.globals.series[t].reduce((function(t,e){return t+e}),0)}},{key:"getStackedSeriesTotalsByGroups",value:function(){var t=this,e=this.w,n=[];return e.globals.seriesGroups.forEach((function(r){var i=[];e.config.series.forEach((function(t,n){r.indexOf(e.globals.seriesNames[n])>-1&&i.push(n)}));var a=e.globals.series.map((function(t,e){return-1===i.indexOf(e)?e:-1})).filter((function(t){return-1!==t}));n.push(t.getStackedSeriesTotals(a))})),n}},{key:"setSeriesYAxisMappings",value:function(){var t=this.w.globals,e=this.w.config,n=[],r=[],i=[],a=t.series.length>e.yaxis.length||e.yaxis.some((function(t){return Array.isArray(t.seriesName)}));e.series.forEach((function(t,e){i.push(e),r.push(null)})),e.yaxis.forEach((function(t,e){n[e]=[]}));var o=[];e.yaxis.forEach((function(t,r){var s=!1;if(t.seriesName){var l=[];Array.isArray(t.seriesName)?l=t.seriesName:l.push(t.seriesName),l.forEach((function(t){e.series.forEach((function(e,o){if(e.name===t){var l=o;r===o||a?!a||i.indexOf(o)>-1?n[r].push([r,o]):console.warn("Series '"+e.name+"' referenced more than once in what looks like the new style. That is, when using either seriesName: [], or when there are more series than yaxes."):(n[o].push([o,r]),l=r),s=!0,-1!==(l=i.indexOf(l))&&i.splice(l,1)}}))}))}s||o.push(r)})),n=n.map((function(t,e){var n=[];return t.forEach((function(t){r[t[1]]=t[0],n.push(t[1])})),n}));for(var s=e.yaxis.length-1,l=0;l0&&void 0!==arguments[0]?arguments[0]:null;return 0===(null===t?this.w.config.series.filter((function(t){return null!==t})):this.w.config.series[t].data.filter((function(t){return null!==t}))).length}},{key:"seriesHaveSameValues",value:function(t){return this.w.globals.series[t].every((function(t,e,n){return t===n[0]}))}},{key:"getCategoryLabels",value:function(t){var e=this.w,n=t.slice();return e.config.xaxis.convertedCatToNumeric&&(n=t.map((function(t,n){return e.config.xaxis.labels.formatter(t-e.globals.minX+1)}))),n}},{key:"getLargestSeries",value:function(){var t=this.w;t.globals.maxValsInArrayIndex=t.globals.series.map((function(t){return t.length})).indexOf(Math.max.apply(Math,t.globals.series.map((function(t){return t.length}))))}},{key:"getLargestMarkerSize",value:function(){var t=this.w,e=0;return t.globals.markers.size.forEach((function(t){e=Math.max(e,t)})),t.config.markers.discrete&&t.config.markers.discrete.length&&t.config.markers.discrete.forEach((function(t){e=Math.max(e,t.size)})),e>0&&(t.config.markers.hover.size>0?e=t.config.markers.hover.size:e+=t.config.markers.hover.sizeOffset),t.globals.markers.largestSize=e,e}},{key:"getSeriesTotals",value:function(){var t=this.w;t.globals.seriesTotals=t.globals.series.map((function(t,e){var n=0;if(Array.isArray(t))for(var r=0;rt&&n.globals.seriesX[i][o]0){var f=function(t,e){var n=i.config.yaxis[i.globals.seriesYAxisReverseMap[e]],a=t<0?-1:1;return t=Math.abs(t),n.logarithmic&&(t=r.getBaseLog(n.logBase,t)),-a*t/o[e]};if(a.isMultipleYAxis){l=[];for(var p=0;p0&&e.forEach((function(e){var o=[],s=[];t.i.forEach((function(n,r){i.config.series[n].group===e&&(o.push(t.series[r]),s.push(n))})),o.length>0&&a.push(r.draw(o,n,s))})),a}}],[{key:"checkComboSeries",value:function(t,e){var n=!1,r=0,i=0;return void 0===e&&(e="line"),t.length&&void 0!==t[0].type&&t.forEach((function(t){"bar"!==t.type&&"column"!==t.type&&"candlestick"!==t.type&&"boxPlot"!==t.type||r++,void 0!==t.type&&t.type!==e&&i++})),i>0&&(n=!0),{comboBarCount:r,comboCharts:n}}},{key:"extendArrayProps",value:function(t,e,n){var r,i,a,o,s,l;return null!==(r=e)&&void 0!==r&&r.yaxis&&(e=t.extendYAxis(e,n)),null!==(i=e)&&void 0!==i&&i.annotations&&(e.annotations.yaxis&&(e=t.extendYAxisAnnotations(e)),null!==(a=e)&&void 0!==a&&null!==(o=a.annotations)&&void 0!==o&&o.xaxis&&(e=t.extendXAxisAnnotations(e)),null!==(s=e)&&void 0!==s&&null!==(l=s.annotations)&&void 0!==l&&l.points&&(e=t.extendPointAnnotations(e))),e}}]),t}(),T=function(){function t(e){o(this,t),this.w=e.w,this.annoCtx=e}return l(t,[{key:"setOrientations",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=this.w;if("vertical"===t.label.orientation){var r=null!==e?e:0,i=n.globals.dom.baseEl.querySelector(".apexcharts-xaxis-annotations .apexcharts-xaxis-annotation-label[rel='".concat(r,"']"));if(null!==i){var a=i.getBoundingClientRect();i.setAttribute("x",parseFloat(i.getAttribute("x"))-a.height+4);var o="top"===t.label.position?a.width:-a.width;i.setAttribute("y",parseFloat(i.getAttribute("y"))+o);var s=this.annoCtx.graphics.rotateAroundCenter(i),l=s.x,c=s.y;i.setAttribute("transform","rotate(-90 ".concat(l," ").concat(c,")"))}}}},{key:"addBackgroundToAnno",value:function(t,e){var n=this.w;if(!t||!e.label.text||!String(e.label.text).trim())return null;var r=n.globals.dom.baseEl.querySelector(".apexcharts-grid").getBoundingClientRect(),i=t.getBoundingClientRect(),a=e.label.style.padding,o=a.left,s=a.right,l=a.top,c=a.bottom;if("vertical"===e.label.orientation){var u=[o,s,l,c];l=u[0],c=u[1],o=u[2],s=u[3]}var h=i.left-r.left-o,d=i.top-r.top-l,f=this.annoCtx.graphics.drawRect(h-n.globals.barPadForNumericAxis,d,i.width+o+s,i.height+l+c,e.label.borderRadius,e.label.style.background,1,e.label.borderWidth,e.label.borderColor,0);return e.id&&f.node.classList.add(e.id),f}},{key:"annotationsBackground",value:function(){var t=this,e=this.w,n=function(n,r,i){var a=e.globals.dom.baseEl.querySelector(".apexcharts-".concat(i,"-annotations .apexcharts-").concat(i,"-annotation-label[rel='").concat(r,"']"));if(a){var o=a.parentNode,s=t.addBackgroundToAnno(a,n);s&&(o.insertBefore(s.node,a),n.label.mouseEnter&&s.node.addEventListener("mouseenter",n.label.mouseEnter.bind(t,n)),n.label.mouseLeave&&s.node.addEventListener("mouseleave",n.label.mouseLeave.bind(t,n)),n.label.click&&s.node.addEventListener("click",n.label.click.bind(t,n)))}};e.config.annotations.xaxis.forEach((function(t,e){return n(t,e,"xaxis")})),e.config.annotations.yaxis.forEach((function(t,e){return n(t,e,"yaxis")})),e.config.annotations.points.forEach((function(t,e){return n(t,e,"point")}))}},{key:"getY1Y2",value:function(t,e){var n,r=this.w,i="y1"===t?e.y:e.y2,a=!1;if(this.annoCtx.invertAxis){var o=r.config.xaxis.convertedCatToNumeric?r.globals.categoryLabels:r.globals.labels,s=o.indexOf(i),l=r.globals.dom.baseEl.querySelector(".apexcharts-yaxis-texts-g text:nth-child(".concat(s+1,")"));n=l?parseFloat(l.getAttribute("y")):(r.globals.gridHeight/o.length-1)*(s+1)-r.globals.barHeight,void 0!==e.seriesIndex&&r.globals.barHeight&&(n-=r.globals.barHeight/2*(r.globals.series.length-1)-r.globals.barHeight*e.seriesIndex)}else{var c,u=r.globals.seriesYAxisMap[e.yAxisIndex][0],h=r.config.yaxis[e.yAxisIndex].logarithmic?new D(this.annoCtx.ctx).getLogVal(r.config.yaxis[e.yAxisIndex].logBase,i,u)/r.globals.yLogRatio[u]:(i-r.globals.minYArr[u])/(r.globals.yRange[u]/r.globals.gridHeight);n=r.globals.gridHeight-Math.min(Math.max(h,0),r.globals.gridHeight),a=h>r.globals.gridHeight||h<0,!e.marker||void 0!==e.y&&null!==e.y||(n=0),null!==(c=r.config.yaxis[e.yAxisIndex])&&void 0!==c&&c.reversed&&(n=h)}return"string"==typeof i&&i.includes("px")&&(n=parseFloat(i)),{yP:n,clipped:a}}},{key:"getX1X2",value:function(t,e){var n=this.w,r="x1"===t?e.x:e.x2,i=this.annoCtx.invertAxis?n.globals.minY:n.globals.minX,a=this.annoCtx.invertAxis?n.globals.maxY:n.globals.maxX,o=this.annoCtx.invertAxis?n.globals.yRange[0]:n.globals.xRange,s=!1,l=this.annoCtx.inversedReversedAxis?(a-r)/(o/n.globals.gridWidth):(r-i)/(o/n.globals.gridWidth);return"category"!==n.config.xaxis.type&&!n.config.xaxis.convertedCatToNumeric||this.annoCtx.invertAxis||n.globals.dataFormatXNumeric||n.config.chart.sparkline.enabled||(l=this.getStringX(r)),"string"==typeof r&&r.includes("px")&&(l=parseFloat(r)),null==r&&e.marker&&(l=n.globals.gridWidth),void 0!==e.seriesIndex&&n.globals.barWidth&&!this.annoCtx.invertAxis&&(l-=n.globals.barWidth/2*(n.globals.series.length-1)-n.globals.barWidth*e.seriesIndex),l>n.globals.gridWidth?(l=n.globals.gridWidth,s=!0):l<0&&(l=0,s=!0),{x:l,clipped:s}}},{key:"getStringX",value:function(t){var e=this.w,n=t;e.config.xaxis.convertedCatToNumeric&&e.globals.categoryLabels.length&&(t=e.globals.categoryLabels.indexOf(t)+1);var r=e.globals.labels.map((function(t){return Array.isArray(t)?t.join(" "):t})).indexOf(t),i=e.globals.dom.baseEl.querySelector(".apexcharts-xaxis-texts-g text:nth-child(".concat(r+1,")"));return i&&(n=parseFloat(i.getAttribute("x"))),n}}]),t}(),E=function(){function t(e){o(this,t),this.w=e.w,this.annoCtx=e,this.invertAxis=this.annoCtx.invertAxis,this.helpers=new T(this.annoCtx)}return l(t,[{key:"addXaxisAnnotation",value:function(t,e,n){var r,i=this.w,a=this.helpers.getX1X2("x1",t),o=a.x,s=a.clipped,l=!0,c=t.label.text,u=t.strokeDashArray;if(S.isNumber(o)){if(null===t.x2||void 0===t.x2){if(!s){var h=this.annoCtx.graphics.drawLine(o+t.offsetX,0+t.offsetY,o+t.offsetX,i.globals.gridHeight+t.offsetY,t.borderColor,u,t.borderWidth);e.appendChild(h.node),t.id&&h.node.classList.add(t.id)}}else{var d=this.helpers.getX1X2("x2",t);if(r=d.x,l=d.clipped,!s||!l){if(r12?d-12:0===d?12:d;e=(e=(e=(e=e.replace(/(^|[^\\])HH+/g,"$1"+l(d))).replace(/(^|[^\\])H/g,"$1"+d)).replace(/(^|[^\\])hh+/g,"$1"+l(f))).replace(/(^|[^\\])h/g,"$1"+f);var p=r?t.getUTCMinutes():t.getMinutes();e=(e=e.replace(/(^|[^\\])mm+/g,"$1"+l(p))).replace(/(^|[^\\])m/g,"$1"+p);var v=r?t.getUTCSeconds():t.getSeconds();e=(e=e.replace(/(^|[^\\])ss+/g,"$1"+l(v))).replace(/(^|[^\\])s/g,"$1"+v);var g=r?t.getUTCMilliseconds():t.getMilliseconds();e=e.replace(/(^|[^\\])fff+/g,"$1"+l(g,3)),g=Math.round(g/10),e=e.replace(/(^|[^\\])ff/g,"$1"+l(g)),g=Math.round(g/10);var m=d<12?"AM":"PM";e=(e=(e=e.replace(/(^|[^\\])f/g,"$1"+g)).replace(/(^|[^\\])TT+/g,"$1"+m)).replace(/(^|[^\\])T/g,"$1"+m.charAt(0));var y=m.toLowerCase();e=(e=e.replace(/(^|[^\\])tt+/g,"$1"+y)).replace(/(^|[^\\])t/g,"$1"+y.charAt(0));var x=-t.getTimezoneOffset(),w=r||!x?"Z":x>0?"+":"-";if(!r){var k=(x=Math.abs(x))%60;w+=l(Math.floor(x/60))+":"+l(k)}e=e.replace(/(^|[^\\])K/g,"$1"+w);var S=(r?t.getUTCDay():t.getDay())+1;return(e=(e=(e=(e=e.replace(new RegExp(o[0],"g"),o[S])).replace(new RegExp(s[0],"g"),s[S])).replace(new RegExp(i[0],"g"),i[u])).replace(new RegExp(a[0],"g"),a[u])).replace(/\\(.)/g,"$1")}},{key:"getTimeUnitsfromTimestamp",value:function(t,e,n){var r=this.w;void 0!==r.config.xaxis.min&&(t=r.config.xaxis.min),void 0!==r.config.xaxis.max&&(e=r.config.xaxis.max);var i=this.getDate(t),a=this.getDate(e),o=this.formatDate(i,"yyyy MM dd HH mm ss fff").split(" "),s=this.formatDate(a,"yyyy MM dd HH mm ss fff").split(" ");return{minMillisecond:parseInt(o[6],10),maxMillisecond:parseInt(s[6],10),minSecond:parseInt(o[5],10),maxSecond:parseInt(s[5],10),minMinute:parseInt(o[4],10),maxMinute:parseInt(s[4],10),minHour:parseInt(o[3],10),maxHour:parseInt(s[3],10),minDate:parseInt(o[2],10),maxDate:parseInt(s[2],10),minMonth:parseInt(o[1],10)-1,maxMonth:parseInt(s[1],10)-1,minYear:parseInt(o[0],10),maxYear:parseInt(s[0],10)}}},{key:"isLeapYear",value:function(t){return t%4==0&&t%100!=0||t%400==0}},{key:"calculcateLastDaysOfMonth",value:function(t,e,n){return this.determineDaysOfMonths(t,e)-n}},{key:"determineDaysOfYear",value:function(t){var e=365;return this.isLeapYear(t)&&(e=366),e}},{key:"determineRemainingDaysOfYear",value:function(t,e,n){var r=this.daysCntOfYear[e]+n;return e>1&&this.isLeapYear()&&r++,r}},{key:"determineDaysOfMonths",value:function(t,e){var n=30;switch(t=S.monthMod(t),!0){case this.months30.indexOf(t)>-1:2===t&&(n=this.isLeapYear(e)?29:28);break;case this.months31.indexOf(t)>-1:default:n=31}return n}}]),t}(),P=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.tooltipKeyFormat="dd MMM"}return l(t,[{key:"xLabelFormat",value:function(t,e,n,r){var i=this.w;if("datetime"===i.config.xaxis.type&&void 0===i.config.xaxis.labels.formatter&&void 0===i.config.tooltip.x.formatter){var a=new O(this.ctx);return a.formatDate(a.getDate(e),i.config.tooltip.x.format)}return t(e,n,r)}},{key:"defaultGeneralFormatter",value:function(t){return Array.isArray(t)?t.map((function(t){return t})):t}},{key:"defaultYFormatter",value:function(t,e,n){var r=this.w;if(S.isNumber(t))if(0!==r.globals.yValueDecimal)t=t.toFixed(void 0!==e.decimalsInFloat?e.decimalsInFloat:r.globals.yValueDecimal);else{var i=t.toFixed(0);t=t==i?i:t.toFixed(1)}return t}},{key:"setLabelFormatters",value:function(){var t=this,e=this.w;return e.globals.xaxisTooltipFormatter=function(e){return t.defaultGeneralFormatter(e)},e.globals.ttKeyFormatter=function(e){return t.defaultGeneralFormatter(e)},e.globals.ttZFormatter=function(t){return t},e.globals.legendFormatter=function(e){return t.defaultGeneralFormatter(e)},void 0!==e.config.xaxis.labels.formatter?e.globals.xLabelFormatter=e.config.xaxis.labels.formatter:e.globals.xLabelFormatter=function(t){if(S.isNumber(t)){if(!e.config.xaxis.convertedCatToNumeric&&"numeric"===e.config.xaxis.type){if(S.isNumber(e.config.xaxis.decimalsInFloat))return t.toFixed(e.config.xaxis.decimalsInFloat);var n=e.globals.maxX-e.globals.minX;return n>0&&n<100?t.toFixed(1):t.toFixed(0)}return e.globals.isBarHorizontal&&e.globals.maxY-e.globals.minYArr<4?t.toFixed(1):t.toFixed(0)}return t},"function"==typeof e.config.tooltip.x.formatter?e.globals.ttKeyFormatter=e.config.tooltip.x.formatter:e.globals.ttKeyFormatter=e.globals.xLabelFormatter,"function"==typeof e.config.xaxis.tooltip.formatter&&(e.globals.xaxisTooltipFormatter=e.config.xaxis.tooltip.formatter),(Array.isArray(e.config.tooltip.y)||void 0!==e.config.tooltip.y.formatter)&&(e.globals.ttVal=e.config.tooltip.y),void 0!==e.config.tooltip.z.formatter&&(e.globals.ttZFormatter=e.config.tooltip.z.formatter),void 0!==e.config.legend.formatter&&(e.globals.legendFormatter=e.config.legend.formatter),e.config.yaxis.forEach((function(n,r){void 0!==n.labels.formatter?e.globals.yLabelFormatters[r]=n.labels.formatter:e.globals.yLabelFormatters[r]=function(i){return e.globals.xyCharts?Array.isArray(i)?i.map((function(e){return t.defaultYFormatter(e,n,r)})):t.defaultYFormatter(i,n,r):i}})),e.globals}},{key:"heatmapLabelFormatters",value:function(){var t=this.w;if("heatmap"===t.config.chart.type){t.globals.yAxisScale[0].result=t.globals.seriesNames.slice();var e=t.globals.seriesNames.reduce((function(t,e){return t.length>e.length?t:e}),0);t.globals.yAxisScale[0].niceMax=e,t.globals.yAxisScale[0].niceMin=e}}}]),t}(),I=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"getLabel",value:function(t,e,n,r){var i,a,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],s=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"12px",l=!(arguments.length>6&&void 0!==arguments[6])||arguments[6],c=this.w,u=void 0===t[r]?"":t[r],h=u,d=c.globals.xLabelFormatter,f=c.config.xaxis.labels.formatter,p=!1,v=new P(this.ctx),g=u;l&&(h=v.xLabelFormat(d,u,g,{i:r,dateFormatter:new O(this.ctx).formatDate,w:c}),void 0!==f&&(h=f(u,t[r],{i:r,dateFormatter:new O(this.ctx).formatDate,w:c}))),e.length>0?(i=e[r].unit,a=null,e.forEach((function(t){"month"===t.unit?a="year":"day"===t.unit?a="month":"hour"===t.unit?a="day":"minute"===t.unit&&(a="hour")})),p=a===i,n=e[r].position,h=e[r].value):"datetime"===c.config.xaxis.type&&void 0===f&&(h=""),void 0===h&&(h=""),h=Array.isArray(h)?h:h.toString();var m=new _(this.ctx),y={};y=c.globals.rotateXLabels&&l?m.getTextRects(h,parseInt(s,10),null,"rotate(".concat(c.config.xaxis.labels.rotate," 0 0)"),!1):m.getTextRects(h,parseInt(s,10));var b=!c.config.xaxis.labels.showDuplicates&&this.ctx.timeScale;return!Array.isArray(h)&&("NaN"===String(h)||o.indexOf(h)>=0&&b)&&(h=""),{x:n,text:h,textRect:y,isBold:p}}},{key:"checkLabelBasedOnTickamount",value:function(t,e,n){var r=this.w,i=r.config.xaxis.tickAmount;return"dataPoints"===i&&(i=Math.round(r.globals.gridWidth/120)),i>n||t%Math.round(n/(i+1))==0||(e.text=""),e}},{key:"checkForOverflowingLabels",value:function(t,e,n,r,i){var a=this.w;if(0===t&&a.globals.skipFirstTimelinelabel&&(e.text=""),t===n-1&&a.globals.skipLastTimelinelabel&&(e.text=""),a.config.xaxis.labels.hideOverlappingLabels&&r.length>0){var o=i[i.length-1];e.xr.length||r.some((function(t){return Array.isArray(t.seriesName)}))?t:n.seriesYAxisReverseMap[t]}},{key:"isYAxisHidden",value:function(t){var e=this.w,n=e.config.yaxis[t];if(!n.show||this.yAxisAllSeriesCollapsed(t))return!0;if(!n.showForNullSeries){var r=e.globals.seriesYAxisMap[t],i=new D(this.ctx);return r.every((function(t){return i.isSeriesNull(t)}))}return!1}},{key:"getYAxisForeColor",value:function(t,e){var n=this.w;return Array.isArray(t)&&n.globals.yAxisScale[e]&&this.ctx.theme.pushExtraColors(t,n.globals.yAxisScale[e].result.length,!1),t}},{key:"drawYAxisTicks",value:function(t,e,n,r,i,a,o){var s=this.w,l=new _(this.ctx),c=s.globals.translateY+s.config.yaxis[i].labels.offsetY;if(s.globals.isBarHorizontal?c=0:"heatmap"===s.config.chart.type&&(c+=a/2),r.show&&e>0){!0===s.config.yaxis[i].opposite&&(t+=r.width);for(var u=e;u>=0;u--){var h=l.drawLine(t+n.offsetX-r.width+r.offsetX,c+r.offsetY,t+n.offsetX+r.offsetX,c+r.offsetY,r.color);o.add(h),c+=a}}}}]),t}(),M=function(){function t(e){o(this,t),this.w=e.w,this.annoCtx=e,this.helpers=new T(this.annoCtx),this.axesUtils=new I(this.annoCtx)}return l(t,[{key:"addYaxisAnnotation",value:function(t,e,n){var r,i=this.w,a=t.strokeDashArray,o=this.helpers.getY1Y2("y1",t),s=o.yP,l=o.clipped,c=!0,u=!1,h=t.label.text;if(null===t.y2||void 0===t.y2){if(!l){u=!0;var d=this.annoCtx.graphics.drawLine(0+t.offsetX,s+t.offsetY,this._getYAxisAnnotationWidth(t),s+t.offsetY,t.borderColor,a,t.borderWidth);e.appendChild(d.node),t.id&&d.node.classList.add(t.id)}}else{if(r=(o=this.helpers.getY1Y2("y2",t)).yP,c=o.clipped,r>s){var f=s;s=r,r=f}if(!l||!c){u=!0;var p=this.annoCtx.graphics.drawRect(0+t.offsetX,r+t.offsetY,this._getYAxisAnnotationWidth(t),s-r,0,t.fillColor,t.opacity,1,t.borderColor,a);p.node.classList.add("apexcharts-annotation-rect"),p.attr("clip-path","url(#gridRectMask".concat(i.globals.cuid,")")),e.appendChild(p.node),t.id&&p.node.classList.add(t.id)}}if(u){var v="right"===t.label.position?i.globals.gridWidth:"center"===t.label.position?i.globals.gridWidth/2:0,g=this.annoCtx.graphics.drawText({x:v+t.label.offsetX,y:(null!=r?r:s)+t.label.offsetY-3,text:h,textAnchor:t.label.textAnchor,fontSize:t.label.style.fontSize,fontFamily:t.label.style.fontFamily,fontWeight:t.label.style.fontWeight,foreColor:t.label.style.color,cssClass:"apexcharts-yaxis-annotation-label ".concat(t.label.style.cssClass," ").concat(t.id?t.id:"")});g.attr({rel:n}),e.appendChild(g.node)}}},{key:"_getYAxisAnnotationWidth",value:function(t){var e=this.w;return e.globals.gridWidth,(t.width.indexOf("%")>-1?e.globals.gridWidth*parseInt(t.width,10)/100:parseInt(t.width,10))+t.offsetX}},{key:"drawYAxisAnnotations",value:function(){var t=this,e=this.w,n=this.annoCtx.graphics.group({class:"apexcharts-yaxis-annotations"});return e.config.annotations.yaxis.forEach((function(e,r){e.yAxisIndex=t.axesUtils.translateYAxisIndex(e.yAxisIndex),t.axesUtils.isYAxisHidden(e.yAxisIndex)&&t.axesUtils.yAxisAllSeriesCollapsed(e.yAxisIndex)||t.addYaxisAnnotation(e,n.node,r)})),n}}]),t}(),V=function(){function t(e){o(this,t),this.w=e.w,this.annoCtx=e,this.helpers=new T(this.annoCtx)}return l(t,[{key:"addPointAnnotation",value:function(t,e,n){if(!(this.w.globals.collapsedSeriesIndices.indexOf(t.seriesIndex)>-1)){var r=this.helpers.getX1X2("x1",t),i=r.x,a=r.clipped,o=(r=this.helpers.getY1Y2("y1",t)).yP,s=r.clipped;if(S.isNumber(i)&&!s&&!a){var l={pSize:t.marker.size,pointStrokeWidth:t.marker.strokeWidth,pointFillColor:t.marker.fillColor,pointStrokeColor:t.marker.strokeColor,shape:t.marker.shape,pRadius:t.marker.radius,class:"apexcharts-point-annotation-marker ".concat(t.marker.cssClass," ").concat(t.id?t.id:"")},c=this.annoCtx.graphics.drawMarker(i+t.marker.offsetX,o+t.marker.offsetY,l);e.appendChild(c.node);var u=t.label.text?t.label.text:"",h=this.annoCtx.graphics.drawText({x:i+t.label.offsetX,y:o+t.label.offsetY-t.marker.size-parseFloat(t.label.style.fontSize)/1.6,text:u,textAnchor:t.label.textAnchor,fontSize:t.label.style.fontSize,fontFamily:t.label.style.fontFamily,fontWeight:t.label.style.fontWeight,foreColor:t.label.style.color,cssClass:"apexcharts-point-annotation-label ".concat(t.label.style.cssClass," ").concat(t.id?t.id:"")});if(h.attr({rel:n}),e.appendChild(h.node),t.customSVG.SVG){var d=this.annoCtx.graphics.group({class:"apexcharts-point-annotations-custom-svg "+t.customSVG.cssClass});d.attr({transform:"translate(".concat(i+t.customSVG.offsetX,", ").concat(o+t.customSVG.offsetY,")")}),d.node.innerHTML=t.customSVG.SVG,e.appendChild(d.node)}if(t.image.path){var f=t.image.width?t.image.width:20,p=t.image.height?t.image.height:20;c=this.annoCtx.addImage({x:i+t.image.offsetX-f/2,y:o+t.image.offsetY-p/2,width:f,height:p,path:t.image.path,appendTo:".apexcharts-point-annotations"})}t.mouseEnter&&c.node.addEventListener("mouseenter",t.mouseEnter.bind(this,t)),t.mouseLeave&&c.node.addEventListener("mouseleave",t.mouseLeave.bind(this,t)),t.click&&c.node.addEventListener("click",t.click.bind(this,t))}}}},{key:"drawPointAnnotations",value:function(){var t=this,e=this.w,n=this.annoCtx.graphics.group({class:"apexcharts-point-annotations"});return e.config.annotations.points.map((function(e,r){t.addPointAnnotation(e,n.node,r)})),n}}]),t}(),L={name:"en",options:{months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],toolbar:{exportToSVG:"Download SVG",exportToPNG:"Download PNG",exportToCSV:"Download CSV",menu:"Menu",selection:"Selection",selectionZoom:"Selection Zoom",zoomIn:"Zoom In",zoomOut:"Zoom Out",pan:"Panning",reset:"Reset Zoom"}}},B=function(){function t(){o(this,t),this.yAxis={show:!0,showAlways:!1,showForNullSeries:!0,seriesName:void 0,opposite:!1,reversed:!1,logarithmic:!1,logBase:10,tickAmount:void 0,stepSize:void 0,forceNiceScale:!1,max:void 0,min:void 0,floating:!1,decimalsInFloat:void 0,labels:{show:!0,showDuplicates:!1,minWidth:0,maxWidth:160,offsetX:0,offsetY:0,align:void 0,rotate:0,padding:20,style:{colors:[],fontSize:"11px",fontWeight:400,fontFamily:void 0,cssClass:""},formatter:void 0},axisBorder:{show:!1,color:"#e0e0e0",width:1,offsetX:0,offsetY:0},axisTicks:{show:!1,color:"#e0e0e0",width:6,offsetX:0,offsetY:0},title:{text:void 0,rotate:-90,offsetY:0,offsetX:0,style:{color:void 0,fontSize:"11px",fontWeight:900,fontFamily:void 0,cssClass:""}},tooltip:{enabled:!1,offsetX:0},crosshairs:{show:!0,position:"front",stroke:{color:"#b6b6b6",width:1,dashArray:0}}},this.pointAnnotation={id:void 0,x:0,y:null,yAxisIndex:0,seriesIndex:void 0,mouseEnter:void 0,mouseLeave:void 0,click:void 0,marker:{size:4,fillColor:"#fff",strokeWidth:2,strokeColor:"#333",shape:"circle",offsetX:0,offsetY:0,cssClass:""},label:{borderColor:"#c2c2c2",borderWidth:1,borderRadius:2,text:void 0,textAnchor:"middle",offsetX:0,offsetY:0,mouseEnter:void 0,mouseLeave:void 0,click:void 0,style:{background:"#fff",color:void 0,fontSize:"11px",fontFamily:void 0,fontWeight:400,cssClass:"",padding:{left:5,right:5,top:2,bottom:2}}},customSVG:{SVG:void 0,cssClass:void 0,offsetX:0,offsetY:0},image:{path:void 0,width:20,height:20,offsetX:0,offsetY:0}},this.yAxisAnnotation={id:void 0,y:0,y2:null,strokeDashArray:1,fillColor:"#c2c2c2",borderColor:"#c2c2c2",borderWidth:1,opacity:.3,offsetX:0,offsetY:0,width:"100%",yAxisIndex:0,label:{borderColor:"#c2c2c2",borderWidth:1,borderRadius:2,text:void 0,textAnchor:"end",position:"right",offsetX:0,offsetY:-3,mouseEnter:void 0,mouseLeave:void 0,click:void 0,style:{background:"#fff",color:void 0,fontSize:"11px",fontFamily:void 0,fontWeight:400,cssClass:"",padding:{left:5,right:5,top:2,bottom:2}}}},this.xAxisAnnotation={id:void 0,x:0,x2:null,strokeDashArray:1,fillColor:"#c2c2c2",borderColor:"#c2c2c2",borderWidth:1,opacity:.3,offsetX:0,offsetY:0,label:{borderColor:"#c2c2c2",borderWidth:1,borderRadius:2,text:void 0,textAnchor:"middle",orientation:"vertical",position:"top",offsetX:0,offsetY:0,mouseEnter:void 0,mouseLeave:void 0,click:void 0,style:{background:"#fff",color:void 0,fontSize:"11px",fontFamily:void 0,fontWeight:400,cssClass:"",padding:{left:5,right:5,top:2,bottom:2}}}},this.text={x:0,y:0,text:"",textAnchor:"start",foreColor:void 0,fontSize:"13px",fontFamily:void 0,fontWeight:400,appendTo:".apexcharts-annotations",backgroundColor:"transparent",borderColor:"#c2c2c2",borderRadius:0,borderWidth:0,paddingLeft:4,paddingRight:4,paddingTop:2,paddingBottom:2}}return l(t,[{key:"init",value:function(){return{annotations:{yaxis:[this.yAxisAnnotation],xaxis:[this.xAxisAnnotation],points:[this.pointAnnotation],texts:[],images:[],shapes:[]},chart:{animations:{enabled:!0,easing:"easeinout",speed:800,animateGradually:{delay:150,enabled:!0},dynamicAnimation:{enabled:!0,speed:350}},background:"",locales:[L],defaultLocale:"en",dropShadow:{enabled:!1,enabledOnSeries:void 0,top:2,left:2,blur:4,color:"#000",opacity:.35},events:{animationEnd:void 0,beforeMount:void 0,mounted:void 0,updated:void 0,click:void 0,mouseMove:void 0,mouseLeave:void 0,xAxisLabelClick:void 0,legendClick:void 0,markerClick:void 0,selection:void 0,dataPointSelection:void 0,dataPointMouseEnter:void 0,dataPointMouseLeave:void 0,beforeZoom:void 0,beforeResetZoom:void 0,zoomed:void 0,scrolled:void 0,brushScrolled:void 0},foreColor:"#373d3f",fontFamily:"Helvetica, Arial, sans-serif",height:"auto",parentHeightOffset:15,redrawOnParentResize:!0,redrawOnWindowResize:!0,id:void 0,group:void 0,nonce:void 0,offsetX:0,offsetY:0,selection:{enabled:!1,type:"x",fill:{color:"#24292e",opacity:.1},stroke:{width:1,color:"#24292e",opacity:.4,dashArray:3},xaxis:{min:void 0,max:void 0},yaxis:{min:void 0,max:void 0}},sparkline:{enabled:!1},brush:{enabled:!1,autoScaleYaxis:!0,target:void 0,targets:void 0},stacked:!1,stackOnlyBar:!0,stackType:"normal",toolbar:{show:!0,offsetX:0,offsetY:0,tools:{download:!0,selection:!0,zoom:!0,zoomin:!0,zoomout:!0,pan:!0,reset:!0,customIcons:[]},export:{csv:{filename:void 0,columnDelimiter:",",headerCategory:"category",headerValue:"value",categoryFormatter:void 0,valueFormatter:void 0},png:{filename:void 0},svg:{filename:void 0},scale:void 0,width:void 0},autoSelected:"zoom"},type:"line",width:"100%",zoom:{enabled:!0,type:"x",autoScaleYaxis:!1,allowMouseWheelZoom:!0,zoomedArea:{fill:{color:"#90CAF9",opacity:.4},stroke:{color:"#0D47A1",opacity:.4,width:1}}}},plotOptions:{line:{isSlopeChart:!1},area:{fillTo:"origin"},bar:{horizontal:!1,columnWidth:"70%",barHeight:"70%",distributed:!1,borderRadius:0,borderRadiusApplication:"around",borderRadiusWhenStacked:"last",rangeBarOverlap:!0,rangeBarGroupRows:!1,hideZeroBarsWhenGrouped:!1,isDumbbell:!1,dumbbellColors:void 0,isFunnel:!1,isFunnel3d:!0,colors:{ranges:[],backgroundBarColors:[],backgroundBarOpacity:1,backgroundBarRadius:0},dataLabels:{position:"top",maxItems:100,hideOverflowingLabels:!0,orientation:"horizontal",total:{enabled:!1,formatter:void 0,offsetX:0,offsetY:0,style:{color:"#373d3f",fontSize:"12px",fontFamily:void 0,fontWeight:600}}}},bubble:{zScaling:!0,minBubbleRadius:void 0,maxBubbleRadius:void 0},candlestick:{colors:{upward:"#00B746",downward:"#EF403C"},wick:{useFillColor:!0}},boxPlot:{colors:{upper:"#00E396",lower:"#008FFB"}},heatmap:{radius:2,enableShades:!0,shadeIntensity:.5,reverseNegativeShade:!1,distributed:!1,useFillColorAsStroke:!1,colorScale:{inverse:!1,ranges:[],min:void 0,max:void 0}},treemap:{enableShades:!0,shadeIntensity:.5,distributed:!1,reverseNegativeShade:!1,useFillColorAsStroke:!1,borderRadius:4,dataLabels:{format:"scale"},colorScale:{inverse:!1,ranges:[],min:void 0,max:void 0}},radialBar:{inverseOrder:!1,startAngle:0,endAngle:360,offsetX:0,offsetY:0,hollow:{margin:5,size:"50%",background:"transparent",image:void 0,imageWidth:150,imageHeight:150,imageOffsetX:0,imageOffsetY:0,imageClipped:!0,position:"front",dropShadow:{enabled:!1,top:0,left:0,blur:3,color:"#000",opacity:.5}},track:{show:!0,startAngle:void 0,endAngle:void 0,background:"#f2f2f2",strokeWidth:"97%",opacity:1,margin:5,dropShadow:{enabled:!1,top:0,left:0,blur:3,color:"#000",opacity:.5}},dataLabels:{show:!0,name:{show:!0,fontSize:"16px",fontFamily:void 0,fontWeight:600,color:void 0,offsetY:0,formatter:function(t){return t}},value:{show:!0,fontSize:"14px",fontFamily:void 0,fontWeight:400,color:void 0,offsetY:16,formatter:function(t){return t+"%"}},total:{show:!1,label:"Total",fontSize:"16px",fontWeight:600,fontFamily:void 0,color:void 0,formatter:function(t){return t.globals.seriesTotals.reduce((function(t,e){return t+e}),0)/t.globals.series.length+"%"}}},barLabels:{enabled:!1,offsetX:0,offsetY:0,useSeriesColors:!0,fontFamily:void 0,fontWeight:600,fontSize:"16px",formatter:function(t){return t},onClick:void 0}},pie:{customScale:1,offsetX:0,offsetY:0,startAngle:0,endAngle:360,expandOnClick:!0,dataLabels:{offset:0,minAngleToShowLabel:10},donut:{size:"65%",background:"transparent",labels:{show:!1,name:{show:!0,fontSize:"16px",fontFamily:void 0,fontWeight:600,color:void 0,offsetY:-10,formatter:function(t){return t}},value:{show:!0,fontSize:"20px",fontFamily:void 0,fontWeight:400,color:void 0,offsetY:10,formatter:function(t){return t}},total:{show:!1,showAlways:!1,label:"Total",fontSize:"16px",fontWeight:400,fontFamily:void 0,color:void 0,formatter:function(t){return t.globals.seriesTotals.reduce((function(t,e){return t+e}),0)}}}}},polarArea:{rings:{strokeWidth:1,strokeColor:"#e8e8e8"},spokes:{strokeWidth:1,connectorColors:"#e8e8e8"}},radar:{size:void 0,offsetX:0,offsetY:0,polygons:{strokeWidth:1,strokeColors:"#e8e8e8",connectorColors:"#e8e8e8",fill:{colors:void 0}}}},colors:void 0,dataLabels:{enabled:!0,enabledOnSeries:void 0,formatter:function(t){return null!==t?t:""},textAnchor:"middle",distributed:!1,offsetX:0,offsetY:0,style:{fontSize:"12px",fontFamily:void 0,fontWeight:600,colors:void 0},background:{enabled:!0,foreColor:"#fff",borderRadius:2,padding:4,opacity:.9,borderWidth:1,borderColor:"#fff",dropShadow:{enabled:!1,top:1,left:1,blur:1,color:"#000",opacity:.45}},dropShadow:{enabled:!1,top:1,left:1,blur:1,color:"#000",opacity:.45}},fill:{type:"solid",colors:void 0,opacity:.85,gradient:{shade:"dark",type:"horizontal",shadeIntensity:.5,gradientToColors:void 0,inverseColors:!0,opacityFrom:1,opacityTo:1,stops:[0,50,100],colorStops:[]},image:{src:[],width:void 0,height:void 0},pattern:{style:"squares",width:6,height:6,strokeWidth:2}},forecastDataPoints:{count:0,fillOpacity:.5,strokeWidth:void 0,dashArray:4},grid:{show:!0,borderColor:"#e0e0e0",strokeDashArray:0,position:"back",xaxis:{lines:{show:!1}},yaxis:{lines:{show:!0}},row:{colors:void 0,opacity:.5},column:{colors:void 0,opacity:.5},padding:{top:0,right:10,bottom:0,left:12}},labels:[],legend:{show:!0,showForSingleSeries:!1,showForNullSeries:!0,showForZeroSeries:!0,floating:!1,position:"bottom",horizontalAlign:"center",inverseOrder:!1,fontSize:"12px",fontFamily:void 0,fontWeight:400,width:void 0,height:void 0,formatter:void 0,tooltipHoverFormatter:void 0,offsetX:-20,offsetY:4,customLegendItems:[],labels:{colors:void 0,useSeriesColors:!1},markers:{size:7,fillColors:void 0,strokeWidth:1,shape:void 0,offsetX:0,offsetY:0,customHTML:void 0,onClick:void 0},itemMargin:{horizontal:5,vertical:4},onItemClick:{toggleDataSeries:!0},onItemHover:{highlightDataSeries:!0}},markers:{discrete:[],size:0,colors:void 0,strokeColors:"#fff",strokeWidth:2,strokeOpacity:.9,strokeDashArray:0,fillOpacity:1,shape:"circle",offsetX:0,offsetY:0,showNullDataPoints:!0,onClick:void 0,onDblClick:void 0,hover:{size:void 0,sizeOffset:3}},noData:{text:void 0,align:"center",verticalAlign:"middle",offsetX:0,offsetY:0,style:{color:void 0,fontSize:"14px",fontFamily:void 0}},responsive:[],series:void 0,states:{normal:{filter:{type:"none",value:0}},hover:{filter:{type:"lighten",value:.1}},active:{allowMultipleDataPointsSelection:!1,filter:{type:"darken",value:.5}}},title:{text:void 0,align:"left",margin:5,offsetX:0,offsetY:0,floating:!1,style:{fontSize:"14px",fontWeight:900,fontFamily:void 0,color:void 0}},subtitle:{text:void 0,align:"left",margin:5,offsetX:0,offsetY:30,floating:!1,style:{fontSize:"12px",fontWeight:400,fontFamily:void 0,color:void 0}},stroke:{show:!0,curve:"smooth",lineCap:"butt",width:2,colors:void 0,dashArray:0,fill:{type:"solid",colors:void 0,opacity:.85,gradient:{shade:"dark",type:"horizontal",shadeIntensity:.5,gradientToColors:void 0,inverseColors:!0,opacityFrom:1,opacityTo:1,stops:[0,50,100],colorStops:[]}}},tooltip:{enabled:!0,enabledOnSeries:void 0,shared:!0,hideEmptySeries:!1,followCursor:!1,intersect:!1,inverseOrder:!1,custom:void 0,fillSeriesColor:!1,theme:"light",cssClass:"",style:{fontSize:"12px",fontFamily:void 0},onDatasetHover:{highlightDataSeries:!1},x:{show:!0,format:"dd MMM",formatter:void 0},y:{formatter:void 0,title:{formatter:function(t){return t?t+": ":""}}},z:{formatter:void 0,title:"Size: "},marker:{show:!0,fillColors:void 0},items:{display:"flex"},fixed:{enabled:!1,position:"topRight",offsetX:0,offsetY:0}},xaxis:{type:"category",categories:[],convertedCatToNumeric:!1,offsetX:0,offsetY:0,overwriteCategories:void 0,labels:{show:!0,rotate:-45,rotateAlways:!1,hideOverlappingLabels:!0,trim:!1,minHeight:void 0,maxHeight:120,showDuplicates:!0,style:{colors:[],fontSize:"12px",fontWeight:400,fontFamily:void 0,cssClass:""},offsetX:0,offsetY:0,format:void 0,formatter:void 0,datetimeUTC:!0,datetimeFormatter:{year:"yyyy",month:"MMM 'yy",day:"dd MMM",hour:"HH:mm",minute:"HH:mm:ss",second:"HH:mm:ss"}},group:{groups:[],style:{colors:[],fontSize:"12px",fontWeight:400,fontFamily:void 0,cssClass:""}},axisBorder:{show:!0,color:"#e0e0e0",width:"100%",height:1,offsetX:0,offsetY:0},axisTicks:{show:!0,color:"#e0e0e0",height:6,offsetX:0,offsetY:0},stepSize:void 0,tickAmount:void 0,tickPlacement:"on",min:void 0,max:void 0,range:void 0,floating:!1,decimalsInFloat:void 0,position:"bottom",title:{text:void 0,offsetX:0,offsetY:0,style:{color:void 0,fontSize:"12px",fontWeight:900,fontFamily:void 0,cssClass:""}},crosshairs:{show:!0,width:1,position:"back",opacity:.9,stroke:{color:"#b6b6b6",width:1,dashArray:3},fill:{type:"solid",color:"#B1B9C4",gradient:{colorFrom:"#D8E3F0",colorTo:"#BED1E6",stops:[0,100],opacityFrom:.4,opacityTo:.5}},dropShadow:{enabled:!1,left:0,top:0,blur:1,opacity:.4}},tooltip:{enabled:!0,offsetY:0,formatter:void 0,style:{fontSize:"12px",fontFamily:void 0}}},yaxis:this.yAxis,theme:{mode:"",palette:"palette1",monochrome:{enabled:!1,color:"#008FFB",shadeTo:"light",shadeIntensity:.65}}}}}]),t}(),R=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.graphics=new _(this.ctx),this.w.globals.isBarHorizontal&&(this.invertAxis=!0),this.helpers=new T(this),this.xAxisAnnotations=new E(this),this.yAxisAnnotations=new M(this),this.pointsAnnotations=new V(this),this.w.globals.isBarHorizontal&&this.w.config.yaxis[0].reversed&&(this.inversedReversedAxis=!0),this.xDivision=this.w.globals.gridWidth/this.w.globals.dataPoints}return l(t,[{key:"drawAxesAnnotations",value:function(){var t=this.w;if(t.globals.axisCharts&&t.globals.dataPoints){for(var e=this.yAxisAnnotations.drawYAxisAnnotations(),n=this.xAxisAnnotations.drawXAxisAnnotations(),r=this.pointsAnnotations.drawPointAnnotations(),i=t.config.chart.animations.enabled,a=[e,n,r],o=[n.node,e.node,r.node],s=0;s<3;s++)t.globals.dom.elGraphical.add(a[s]),!i||t.globals.resized||t.globals.dataChanged||"scatter"!==t.config.chart.type&&"bubble"!==t.config.chart.type&&t.globals.dataPoints>1&&o[s].classList.add("apexcharts-element-hidden"),t.globals.delayedElements.push({el:o[s],index:0});this.helpers.annotationsBackground()}}},{key:"drawImageAnnos",value:function(){var t=this;this.w.config.annotations.images.map((function(e,n){t.addImage(e,n)}))}},{key:"drawTextAnnos",value:function(){var t=this;this.w.config.annotations.texts.map((function(e,n){t.addText(e,n)}))}},{key:"addXaxisAnnotation",value:function(t,e,n){this.xAxisAnnotations.addXaxisAnnotation(t,e,n)}},{key:"addYaxisAnnotation",value:function(t,e,n){this.yAxisAnnotations.addYaxisAnnotation(t,e,n)}},{key:"addPointAnnotation",value:function(t,e,n){this.pointsAnnotations.addPointAnnotation(t,e,n)}},{key:"addText",value:function(t,e){var n=t.x,r=t.y,i=t.text,a=t.textAnchor,o=t.foreColor,s=t.fontSize,l=t.fontFamily,c=t.fontWeight,u=t.cssClass,h=t.backgroundColor,d=t.borderWidth,f=t.strokeDashArray,p=t.borderRadius,v=t.borderColor,g=t.appendTo,m=void 0===g?".apexcharts-svg":g,y=t.paddingLeft,b=void 0===y?4:y,x=t.paddingRight,w=void 0===x?4:x,k=t.paddingBottom,S=void 0===k?2:k,C=t.paddingTop,A=void 0===C?2:C,_=this.w,D=this.graphics.drawText({x:n,y:r,text:i,textAnchor:a||"start",fontSize:s||"12px",fontWeight:c||"regular",fontFamily:l||_.config.chart.fontFamily,foreColor:o||_.config.chart.foreColor,cssClass:u}),T=_.globals.dom.baseEl.querySelector(m);T&&T.appendChild(D.node);var E=D.bbox();if(i){var O=this.graphics.drawRect(E.x-b,E.y-A,E.width+b+w,E.height+S+A,p,h||"transparent",1,d,v,f);T.insertBefore(O.node,D.node)}}},{key:"addImage",value:function(t,e){var n=this.w,r=t.path,i=t.x,a=void 0===i?0:i,o=t.y,s=void 0===o?0:o,l=t.width,c=void 0===l?20:l,u=t.height,h=void 0===u?20:u,d=t.appendTo,f=void 0===d?".apexcharts-svg":d,p=n.globals.dom.Paper.image(r);p.size(c,h).move(a,s);var v=n.globals.dom.baseEl.querySelector(f);return v&&v.appendChild(p.node),p}},{key:"addXaxisAnnotationExternal",value:function(t,e,n){return this.addAnnotationExternal({params:t,pushToMemory:e,context:n,type:"xaxis",contextMethod:n.addXaxisAnnotation}),n}},{key:"addYaxisAnnotationExternal",value:function(t,e,n){return this.addAnnotationExternal({params:t,pushToMemory:e,context:n,type:"yaxis",contextMethod:n.addYaxisAnnotation}),n}},{key:"addPointAnnotationExternal",value:function(t,e,n){return void 0===this.invertAxis&&(this.invertAxis=n.w.globals.isBarHorizontal),this.addAnnotationExternal({params:t,pushToMemory:e,context:n,type:"point",contextMethod:n.addPointAnnotation}),n}},{key:"addAnnotationExternal",value:function(t){var e=t.params,n=t.pushToMemory,r=t.context,i=t.type,a=t.contextMethod,o=r,s=o.w,l=s.globals.dom.baseEl.querySelector(".apexcharts-".concat(i,"-annotations")),c=l.childNodes.length+1,u=new B,h=Object.assign({},"xaxis"===i?u.xAxisAnnotation:"yaxis"===i?u.yAxisAnnotation:u.pointAnnotation),d=S.extend(h,e);switch(i){case"xaxis":this.addXaxisAnnotation(d,l,c);break;case"yaxis":this.addYaxisAnnotation(d,l,c);break;case"point":this.addPointAnnotation(d,l,c)}var f=s.globals.dom.baseEl.querySelector(".apexcharts-".concat(i,"-annotations .apexcharts-").concat(i,"-annotation-label[rel='").concat(c,"']")),p=this.helpers.addBackgroundToAnno(f,d);return p&&l.insertBefore(p.node,f),n&&s.globals.memory.methodsToExec.push({context:o,id:d.id?d.id:S.randomId(),method:a,label:"addAnnotation",params:e}),r}},{key:"clearAnnotations",value:function(t){for(var e=t.w,n=e.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis-annotations, .apexcharts-xaxis-annotations, .apexcharts-point-annotations"),r=e.globals.memory.methodsToExec.length-1;r>=0;r--)"addText"!==e.globals.memory.methodsToExec[r].label&&"addAnnotation"!==e.globals.memory.methodsToExec[r].label||e.globals.memory.methodsToExec.splice(r,1);n=S.listToArray(n),Array.prototype.forEach.call(n,(function(t){for(;t.firstChild;)t.removeChild(t.firstChild)}))}},{key:"removeAnnotation",value:function(t,e){var n=t.w,r=n.globals.dom.baseEl.querySelectorAll(".".concat(e));r&&(n.globals.memory.methodsToExec.map((function(t,r){t.id===e&&n.globals.memory.methodsToExec.splice(r,1)})),Array.prototype.forEach.call(r,(function(t){t.parentElement.removeChild(t)})))}}]),t}(),F=function(t){var e,n=t.isTimeline,r=t.ctx,i=t.seriesIndex,a=t.dataPointIndex,o=t.y1,s=t.y2,l=t.w,c=l.globals.seriesRangeStart[i][a],u=l.globals.seriesRangeEnd[i][a],h=l.globals.labels[a],d=l.config.series[i].name?l.config.series[i].name:"",f=l.globals.ttKeyFormatter,p=l.config.tooltip.y.title.formatter,v={w:l,seriesIndex:i,dataPointIndex:a,start:c,end:u};"function"==typeof p&&(d=p(d,v)),null!==(e=l.config.series[i].data[a])&&void 0!==e&&e.x&&(h=l.config.series[i].data[a].x),n||"datetime"===l.config.xaxis.type&&(h=new P(r).xLabelFormat(l.globals.ttKeyFormatter,h,h,{i:void 0,dateFormatter:new O(r).formatDate,w:l})),"function"==typeof f&&(h=f(h,v)),Number.isFinite(o)&&Number.isFinite(s)&&(c=o,u=s);var g="",m="",y=l.globals.colors[i];if(void 0===l.config.tooltip.x.formatter)if("datetime"===l.config.xaxis.type){var b=new O(r);g=b.formatDate(b.getDate(c),l.config.tooltip.x.format),m=b.formatDate(b.getDate(u),l.config.tooltip.x.format)}else g=c,m=u;else g=l.config.tooltip.x.formatter(c),m=l.config.tooltip.x.formatter(u);return{start:c,end:u,startVal:g,endVal:m,ylabel:h,color:y,seriesName:d}},N=function(t){var e=t.color,n=t.seriesName,r=t.ylabel,i=t.start,a=t.end,o=t.seriesIndex,s=t.dataPointIndex,l=t.ctx.tooltip.tooltipLabels.getFormatters(o);i=l.yLbFormatter(i),a=l.yLbFormatter(a);var c=l.yLbFormatter(t.w.globals.series[o][s]),u='\n '.concat(i,'\n - \n ').concat(a,"\n ");return'
'+(n||"")+'
'+r+": "+(t.w.globals.comboCharts?"rangeArea"===t.w.config.series[o].type||"rangeBar"===t.w.config.series[o].type?u:"".concat(c,""):u)+"
"},z=function(){function t(e){o(this,t),this.opts=e}return l(t,[{key:"hideYAxis",value:function(){this.opts.yaxis[0].show=!1,this.opts.yaxis[0].title.text="",this.opts.yaxis[0].axisBorder.show=!1,this.opts.yaxis[0].axisTicks.show=!1,this.opts.yaxis[0].floating=!0}},{key:"line",value:function(){return{chart:{animations:{easing:"swing"}},dataLabels:{enabled:!1},stroke:{width:5,curve:"straight"},markers:{size:0,hover:{sizeOffset:6}},xaxis:{crosshairs:{width:1}}}}},{key:"sparkline",value:function(t){return this.hideYAxis(),S.extend(t,{grid:{show:!1,padding:{left:0,right:0,top:0,bottom:0}},legend:{show:!1},xaxis:{labels:{show:!1},tooltip:{enabled:!1},axisBorder:{show:!1},axisTicks:{show:!1}},chart:{toolbar:{show:!1},zoom:{enabled:!1}},dataLabels:{enabled:!1}})}},{key:"slope",value:function(){return this.hideYAxis(),{chart:{toolbar:{show:!1},zoom:{enabled:!1}},dataLabels:{enabled:!0,formatter:function(t,e){var n=e.w.config.series[e.seriesIndex].name;return null!==t?n+": "+t:""},background:{enabled:!1},offsetX:-5},grid:{xaxis:{lines:{show:!0}},yaxis:{lines:{show:!1}}},xaxis:{position:"top",labels:{style:{fontSize:14,fontWeight:900}},tooltip:{enabled:!1},crosshairs:{show:!1}},markers:{size:8,hover:{sizeOffset:1}},legend:{show:!1},tooltip:{shared:!1,intersect:!0,followCursor:!0},stroke:{width:5,curve:"straight"}}}},{key:"bar",value:function(){return{chart:{stacked:!1,animations:{easing:"swing"}},plotOptions:{bar:{dataLabels:{position:"center"}}},dataLabels:{style:{colors:["#fff"]},background:{enabled:!1}},stroke:{width:0,lineCap:"round"},fill:{opacity:.85},legend:{markers:{shape:"square"}},tooltip:{shared:!1,intersect:!0},xaxis:{tooltip:{enabled:!1},tickPlacement:"between",crosshairs:{width:"barWidth",position:"back",fill:{type:"gradient"},dropShadow:{enabled:!1},stroke:{width:0}}}}}},{key:"funnel",value:function(){return this.hideYAxis(),g(g({},this.bar()),{},{chart:{animations:{easing:"linear",speed:800,animateGradually:{enabled:!1}}},plotOptions:{bar:{horizontal:!0,borderRadiusApplication:"around",borderRadius:0,dataLabels:{position:"center"}}},grid:{show:!1,padding:{left:0,right:0}},xaxis:{labels:{show:!1},tooltip:{enabled:!1},axisBorder:{show:!1},axisTicks:{show:!1}}})}},{key:"candlestick",value:function(){var t=this;return{stroke:{width:1,colors:["#333"]},fill:{opacity:1},dataLabels:{enabled:!1},tooltip:{shared:!0,custom:function(e){var n=e.seriesIndex,r=e.dataPointIndex,i=e.w;return t._getBoxTooltip(i,n,r,["Open","High","","Low","Close"],"candlestick")}},states:{active:{filter:{type:"none"}}},xaxis:{crosshairs:{width:1}}}}},{key:"boxPlot",value:function(){var t=this;return{chart:{animations:{dynamicAnimation:{enabled:!1}}},stroke:{width:1,colors:["#24292e"]},dataLabels:{enabled:!1},tooltip:{shared:!0,custom:function(e){var n=e.seriesIndex,r=e.dataPointIndex,i=e.w;return t._getBoxTooltip(i,n,r,["Minimum","Q1","Median","Q3","Maximum"],"boxPlot")}},markers:{size:7,strokeWidth:1,strokeColors:"#111"},xaxis:{crosshairs:{width:1}}}}},{key:"rangeBar",value:function(){return{chart:{animations:{animateGradually:!1}},stroke:{width:0,lineCap:"square"},plotOptions:{bar:{borderRadius:0,dataLabels:{position:"center"}}},dataLabels:{enabled:!1,formatter:function(t,e){e.ctx;var n=e.seriesIndex,r=e.dataPointIndex,i=e.w,a=function(){var t=i.globals.seriesRangeStart[n][r];return i.globals.seriesRangeEnd[n][r]-t};return i.globals.comboCharts?"rangeBar"===i.config.series[n].type||"rangeArea"===i.config.series[n].type?a():t:a()},background:{enabled:!1},style:{colors:["#fff"]}},markers:{size:10},tooltip:{shared:!1,followCursor:!0,custom:function(t){return t.w.config.plotOptions&&t.w.config.plotOptions.bar&&t.w.config.plotOptions.bar.horizontal?function(t){var e=F(g(g({},t),{},{isTimeline:!0})),n=e.color,r=e.seriesName,i=e.ylabel,a=e.startVal,o=e.endVal;return N(g(g({},t),{},{color:n,seriesName:r,ylabel:i,start:a,end:o}))}(t):function(t){var e=F(t),n=e.color,r=e.seriesName,i=e.ylabel,a=e.start,o=e.end;return N(g(g({},t),{},{color:n,seriesName:r,ylabel:i,start:a,end:o}))}(t)}},xaxis:{tickPlacement:"between",tooltip:{enabled:!1},crosshairs:{stroke:{width:0}}}}}},{key:"dumbbell",value:function(t){var e,n;return null!==(e=t.plotOptions.bar)&&void 0!==e&&e.barHeight||(t.plotOptions.bar.barHeight=2),null!==(n=t.plotOptions.bar)&&void 0!==n&&n.columnWidth||(t.plotOptions.bar.columnWidth=2),t}},{key:"area",value:function(){return{stroke:{width:4,fill:{type:"solid",gradient:{inverseColors:!1,shade:"light",type:"vertical",opacityFrom:.65,opacityTo:.5,stops:[0,100,100]}}},fill:{type:"gradient",gradient:{inverseColors:!1,shade:"light",type:"vertical",opacityFrom:.65,opacityTo:.5,stops:[0,100,100]}},markers:{size:0,hover:{sizeOffset:6}},tooltip:{followCursor:!1}}}},{key:"rangeArea",value:function(){return{stroke:{curve:"straight",width:0},fill:{type:"solid",opacity:.6},markers:{size:0},states:{hover:{filter:{type:"none"}},active:{filter:{type:"none"}}},tooltip:{intersect:!1,shared:!0,followCursor:!0,custom:function(t){return function(t){var e=F(t),n=e.color,r=e.seriesName,i=e.ylabel,a=e.start,o=e.end;return N(g(g({},t),{},{color:n,seriesName:r,ylabel:i,start:a,end:o}))}(t)}}}}},{key:"brush",value:function(t){return S.extend(t,{chart:{toolbar:{autoSelected:"selection",show:!1},zoom:{enabled:!1}},dataLabels:{enabled:!1},stroke:{width:1},tooltip:{enabled:!1},xaxis:{tooltip:{enabled:!1}}})}},{key:"stacked100",value:function(t){t.dataLabels=t.dataLabels||{},t.dataLabels.formatter=t.dataLabels.formatter||void 0;var e=t.dataLabels.formatter;return t.yaxis.forEach((function(e,n){t.yaxis[n].min=0,t.yaxis[n].max=100})),"bar"===t.chart.type&&(t.dataLabels.formatter=e||function(t){return"number"==typeof t&&t?t.toFixed(0)+"%":t}),t}},{key:"stackedBars",value:function(){var t=this.bar();return g(g({},t),{},{plotOptions:g(g({},t.plotOptions),{},{bar:g(g({},t.plotOptions.bar),{},{borderRadiusApplication:"end",borderRadiusWhenStacked:"last"})})})}},{key:"convertCatToNumeric",value:function(t){return t.xaxis.convertedCatToNumeric=!0,t}},{key:"convertCatToNumericXaxis",value:function(t,e,n){t.xaxis.type="numeric",t.xaxis.labels=t.xaxis.labels||{},t.xaxis.labels.formatter=t.xaxis.labels.formatter||function(t){return S.isNumber(t)?Math.floor(t):t};var r=t.xaxis.labels.formatter,i=t.xaxis.categories&&t.xaxis.categories.length?t.xaxis.categories:t.labels;return n&&n.length&&(i=n.map((function(t){return Array.isArray(t)?t:String(t)}))),i&&i.length&&(t.xaxis.labels.formatter=function(t){return S.isNumber(t)?r(i[Math.floor(t)-1]):r(t)}),t.xaxis.categories=[],t.labels=[],t.xaxis.tickAmount=t.xaxis.tickAmount||"dataPoints",t}},{key:"bubble",value:function(){return{dataLabels:{style:{colors:["#fff"]}},tooltip:{shared:!1,intersect:!0},xaxis:{crosshairs:{width:0}},fill:{type:"solid",gradient:{shade:"light",inverse:!0,shadeIntensity:.55,opacityFrom:.4,opacityTo:.8}}}}},{key:"scatter",value:function(){return{dataLabels:{enabled:!1},tooltip:{shared:!1,intersect:!0},markers:{size:6,strokeWidth:1,hover:{sizeOffset:2}}}}},{key:"heatmap",value:function(){return{chart:{stacked:!1},fill:{opacity:1},dataLabels:{style:{colors:["#fff"]}},stroke:{colors:["#fff"]},tooltip:{followCursor:!0,marker:{show:!1},x:{show:!1}},legend:{position:"top",markers:{shape:"square"}},grid:{padding:{right:20}}}}},{key:"treemap",value:function(){return{chart:{zoom:{enabled:!1}},dataLabels:{style:{fontSize:14,fontWeight:600,colors:["#fff"]}},stroke:{show:!0,width:2,colors:["#fff"]},legend:{show:!1},fill:{opacity:1,gradient:{stops:[0,100]}},tooltip:{followCursor:!0,x:{show:!1}},grid:{padding:{left:0,right:0}},xaxis:{crosshairs:{show:!1},tooltip:{enabled:!1}}}}},{key:"pie",value:function(){return{chart:{toolbar:{show:!1}},plotOptions:{pie:{donut:{labels:{show:!1}}}},dataLabels:{formatter:function(t){return t.toFixed(1)+"%"},style:{colors:["#fff"]},background:{enabled:!1},dropShadow:{enabled:!0}},stroke:{colors:["#fff"]},fill:{opacity:1,gradient:{shade:"light",stops:[0,100]}},tooltip:{theme:"dark",fillSeriesColor:!0},legend:{position:"right"},grid:{padding:{left:0,right:0,top:0,bottom:0}}}}},{key:"donut",value:function(){return{chart:{toolbar:{show:!1}},dataLabels:{formatter:function(t){return t.toFixed(1)+"%"},style:{colors:["#fff"]},background:{enabled:!1},dropShadow:{enabled:!0}},stroke:{colors:["#fff"]},fill:{opacity:1,gradient:{shade:"light",shadeIntensity:.35,stops:[80,100],opacityFrom:1,opacityTo:1}},tooltip:{theme:"dark",fillSeriesColor:!0},legend:{position:"right"},grid:{padding:{left:0,right:0,top:0,bottom:0}}}}},{key:"polarArea",value:function(){return{chart:{toolbar:{show:!1}},dataLabels:{formatter:function(t){return t.toFixed(1)+"%"},enabled:!1},stroke:{show:!0,width:2},fill:{opacity:.7},tooltip:{theme:"dark",fillSeriesColor:!0},legend:{position:"right"},grid:{padding:{left:0,right:0,top:0,bottom:0}}}}},{key:"radar",value:function(){return this.opts.yaxis[0].labels.offsetY=this.opts.yaxis[0].labels.offsetY?this.opts.yaxis[0].labels.offsetY:6,{dataLabels:{enabled:!1,style:{fontSize:"11px"}},stroke:{width:2},markers:{size:5,strokeWidth:1,strokeOpacity:1},fill:{opacity:.2},tooltip:{shared:!1,intersect:!0,followCursor:!0},grid:{show:!1,padding:{left:0,right:0,top:0,bottom:0}},xaxis:{labels:{formatter:function(t){return t},style:{colors:["#a8a8a8"],fontSize:"11px"}},tooltip:{enabled:!1},crosshairs:{show:!1}}}}},{key:"radialBar",value:function(){return{chart:{animations:{dynamicAnimation:{enabled:!0,speed:800}},toolbar:{show:!1}},fill:{gradient:{shade:"dark",shadeIntensity:.4,inverseColors:!1,type:"diagonal2",opacityFrom:1,opacityTo:1,stops:[70,98,100]}},legend:{show:!1,position:"right"},tooltip:{enabled:!1,fillSeriesColor:!0},grid:{padding:{left:0,right:0,top:0,bottom:0}}}}},{key:"_getBoxTooltip",value:function(t,e,n,r,i){var a=t.globals.seriesCandleO[e][n],o=t.globals.seriesCandleH[e][n],s=t.globals.seriesCandleM[e][n],l=t.globals.seriesCandleL[e][n],c=t.globals.seriesCandleC[e][n];return t.config.series[e].type&&t.config.series[e].type!==i?'
\n '.concat(t.config.series[e].name?t.config.series[e].name:"series-"+(e+1),": ").concat(t.globals.series[e][n],"\n
"):'
')+"
".concat(r[0],': ')+a+"
"+"
".concat(r[1],': ')+o+"
"+(s?"
".concat(r[2],': ')+s+"
":"")+"
".concat(r[3],': ')+l+"
"+"
".concat(r[4],': ')+c+"
"}}]),t}(),$=function(){function t(e){o(this,t),this.opts=e}return l(t,[{key:"init",value:function(t){var e=t.responsiveOverride,n=this.opts,r=new B,i=new z(n);this.chartType=n.chart.type,n=this.extendYAxis(n),n=this.extendAnnotations(n);var a=r.init(),o={};if(n&&"object"===w(n)){var s,l,c,u,h,d,f,p,v,g,m={};m=-1!==["line","area","bar","candlestick","boxPlot","rangeBar","rangeArea","bubble","scatter","heatmap","treemap","pie","polarArea","donut","radar","radialBar"].indexOf(n.chart.type)?i[n.chart.type]():i.line(),null!==(s=n.plotOptions)&&void 0!==s&&null!==(l=s.bar)&&void 0!==l&&l.isFunnel&&(m=i.funnel()),n.chart.stacked&&"bar"===n.chart.type&&(m=i.stackedBars()),null!==(c=n.chart.brush)&&void 0!==c&&c.enabled&&(m=i.brush(m)),null!==(u=n.plotOptions)&&void 0!==u&&null!==(h=u.line)&&void 0!==h&&h.isSlopeChart&&(m=i.slope()),n.chart.stacked&&"100%"===n.chart.stackType&&(n=i.stacked100(n)),null!==(d=n.plotOptions)&&void 0!==d&&null!==(f=d.bar)&&void 0!==f&&f.isDumbbell&&(n=i.dumbbell(n)),this.checkForDarkTheme(window.Apex),this.checkForDarkTheme(n),n.xaxis=n.xaxis||window.Apex.xaxis||{},e||(n.xaxis.convertedCatToNumeric=!1),(null!==(p=(n=this.checkForCatToNumericXAxis(this.chartType,m,n)).chart.sparkline)&&void 0!==p&&p.enabled||null!==(v=window.Apex.chart)&&void 0!==v&&null!==(g=v.sparkline)&&void 0!==g&&g.enabled)&&(m=i.sparkline(m)),o=S.extend(a,m)}var y=S.extend(o,window.Apex);return a=S.extend(y,n),this.handleUserInputErrors(a)}},{key:"checkForCatToNumericXAxis",value:function(t,e,n){var r,i,a=new z(n),o=("bar"===t||"boxPlot"===t)&&(null===(r=n.plotOptions)||void 0===r||null===(i=r.bar)||void 0===i?void 0:i.horizontal),s="pie"===t||"polarArea"===t||"donut"===t||"radar"===t||"radialBar"===t||"heatmap"===t,l="datetime"!==n.xaxis.type&&"numeric"!==n.xaxis.type,c=n.xaxis.tickPlacement?n.xaxis.tickPlacement:e.xaxis&&e.xaxis.tickPlacement;return o||s||!l||"between"===c||(n=a.convertCatToNumeric(n)),n}},{key:"extendYAxis",value:function(t,e){var n=new B;(void 0===t.yaxis||!t.yaxis||Array.isArray(t.yaxis)&&0===t.yaxis.length)&&(t.yaxis={}),t.yaxis.constructor!==Array&&window.Apex.yaxis&&window.Apex.yaxis.constructor!==Array&&(t.yaxis=S.extend(t.yaxis,window.Apex.yaxis)),t.yaxis.constructor!==Array?t.yaxis=[S.extend(n.yAxis,t.yaxis)]:t.yaxis=S.extendArray(t.yaxis,n.yAxis);var r=!1;t.yaxis.forEach((function(t){t.logarithmic&&(r=!0)}));var i=t.series;return e&&!i&&(i=e.config.series),r&&i.length!==t.yaxis.length&&i.length&&(t.yaxis=i.map((function(e,r){if(e.name||(i[r].name="series-".concat(r+1)),t.yaxis[r])return t.yaxis[r].seriesName=i[r].name,t.yaxis[r];var a=S.extend(n.yAxis,t.yaxis[0]);return a.show=!1,a}))),r&&i.length>1&&i.length!==t.yaxis.length&&console.warn("A multi-series logarithmic chart should have equal number of series and y-axes"),t}},{key:"extendAnnotations",value:function(t){return void 0===t.annotations&&(t.annotations={},t.annotations.yaxis=[],t.annotations.xaxis=[],t.annotations.points=[]),t=this.extendYAxisAnnotations(t),t=this.extendXAxisAnnotations(t),this.extendPointAnnotations(t)}},{key:"extendYAxisAnnotations",value:function(t){var e=new B;return t.annotations.yaxis=S.extendArray(void 0!==t.annotations.yaxis?t.annotations.yaxis:[],e.yAxisAnnotation),t}},{key:"extendXAxisAnnotations",value:function(t){var e=new B;return t.annotations.xaxis=S.extendArray(void 0!==t.annotations.xaxis?t.annotations.xaxis:[],e.xAxisAnnotation),t}},{key:"extendPointAnnotations",value:function(t){var e=new B;return t.annotations.points=S.extendArray(void 0!==t.annotations.points?t.annotations.points:[],e.pointAnnotation),t}},{key:"checkForDarkTheme",value:function(t){t.theme&&"dark"===t.theme.mode&&(t.tooltip||(t.tooltip={}),"light"!==t.tooltip.theme&&(t.tooltip.theme="dark"),t.chart.foreColor||(t.chart.foreColor="#f6f7f8"),t.theme.palette||(t.theme.palette="palette4"))}},{key:"handleUserInputErrors",value:function(t){var e=t;if(e.tooltip.shared&&e.tooltip.intersect)throw new Error("tooltip.shared cannot be enabled when tooltip.intersect is true. Turn off any other option by setting it to false.");if("bar"===e.chart.type&&e.plotOptions.bar.horizontal){if(e.yaxis.length>1)throw new Error("Multiple Y Axis for bars are not supported. Switch to column chart by setting plotOptions.bar.horizontal=false");e.yaxis[0].reversed&&(e.yaxis[0].opposite=!0),e.xaxis.tooltip.enabled=!1,e.yaxis[0].tooltip.enabled=!1,e.chart.zoom.enabled=!1}return"bar"!==e.chart.type&&"rangeBar"!==e.chart.type||e.tooltip.shared&&"barWidth"===e.xaxis.crosshairs.width&&e.series.length>1&&(e.xaxis.crosshairs.width="tickWidth"),"candlestick"!==e.chart.type&&"boxPlot"!==e.chart.type||e.yaxis[0].reversed&&(console.warn("Reversed y-axis in ".concat(e.chart.type," chart is not supported.")),e.yaxis[0].reversed=!1),e}}]),t}(),Y=function(){function t(){o(this,t)}return l(t,[{key:"initGlobalVars",value:function(t){t.series=[],t.seriesCandleO=[],t.seriesCandleH=[],t.seriesCandleM=[],t.seriesCandleL=[],t.seriesCandleC=[],t.seriesRangeStart=[],t.seriesRangeEnd=[],t.seriesRange=[],t.seriesPercent=[],t.seriesGoals=[],t.seriesX=[],t.seriesZ=[],t.seriesNames=[],t.seriesTotals=[],t.seriesLog=[],t.seriesColors=[],t.stackedSeriesTotals=[],t.seriesXvalues=[],t.seriesYvalues=[],t.labels=[],t.hasXaxisGroups=!1,t.groups=[],t.barGroups=[],t.lineGroups=[],t.areaGroups=[],t.hasSeriesGroups=!1,t.seriesGroups=[],t.categoryLabels=[],t.timescaleLabels=[],t.noLabelsProvided=!1,t.resizeTimer=null,t.selectionResizeTimer=null,t.lastWheelExecution=0,t.delayedElements=[],t.pointsArray=[],t.dataLabelsRects=[],t.isXNumeric=!1,t.skipLastTimelinelabel=!1,t.skipFirstTimelinelabel=!1,t.isDataXYZ=!1,t.isMultiLineX=!1,t.isMultipleYAxis=!1,t.maxY=-Number.MAX_VALUE,t.minY=Number.MIN_VALUE,t.minYArr=[],t.maxYArr=[],t.maxX=-Number.MAX_VALUE,t.minX=Number.MAX_VALUE,t.initialMaxX=-Number.MAX_VALUE,t.initialMinX=Number.MAX_VALUE,t.maxDate=0,t.minDate=Number.MAX_VALUE,t.minZ=Number.MAX_VALUE,t.maxZ=-Number.MAX_VALUE,t.minXDiff=Number.MAX_VALUE,t.yAxisScale=[],t.xAxisScale=null,t.xAxisTicksPositions=[],t.yLabelsCoords=[],t.yTitleCoords=[],t.barPadForNumericAxis=0,t.padHorizontal=0,t.xRange=0,t.yRange=[],t.zRange=0,t.dataPoints=0,t.xTickAmount=0,t.multiAxisTickAmount=0}},{key:"globalVars",value:function(t){return{chartID:null,cuid:null,events:{beforeMount:[],mounted:[],updated:[],clicked:[],selection:[],dataPointSelection:[],zoomed:[],scrolled:[]},colors:[],clientX:null,clientY:null,fill:{colors:[]},stroke:{colors:[]},dataLabels:{style:{colors:[]}},radarPolygons:{fill:{colors:[]}},markers:{colors:[],size:t.markers.size,largestSize:0},animationEnded:!1,isTouchDevice:"ontouchstart"in window||navigator.msMaxTouchPoints,isDirty:!1,isExecCalled:!1,initialConfig:null,initialSeries:[],lastXAxis:[],lastYAxis:[],columnSeries:null,labels:[],timescaleLabels:[],noLabelsProvided:!1,allSeriesCollapsed:!1,collapsedSeries:[],collapsedSeriesIndices:[],ancillaryCollapsedSeries:[],ancillaryCollapsedSeriesIndices:[],risingSeries:[],dataFormatXNumeric:!1,capturedSeriesIndex:-1,capturedDataPointIndex:-1,selectedDataPoints:[],invalidLogScale:!1,ignoreYAxisIndexes:[],maxValsInArrayIndex:0,radialSize:0,selection:void 0,zoomEnabled:"zoom"===t.chart.toolbar.autoSelected&&t.chart.toolbar.tools.zoom&&t.chart.zoom.enabled,panEnabled:"pan"===t.chart.toolbar.autoSelected&&t.chart.toolbar.tools.pan,selectionEnabled:"selection"===t.chart.toolbar.autoSelected&&t.chart.toolbar.tools.selection,yaxis:null,mousedown:!1,lastClientPosition:{},visibleXRange:void 0,yValueDecimal:0,total:0,SVGNS:"http://www.w3.org/2000/svg",svgWidth:0,svgHeight:0,noData:!1,locale:{},dom:{},memory:{methodsToExec:[]},shouldAnimate:!0,skipLastTimelinelabel:!1,skipFirstTimelinelabel:!1,delayedElements:[],axisCharts:!0,isDataXYZ:!1,isSlopeChart:t.plotOptions.line.isSlopeChart,resized:!1,resizeTimer:null,comboCharts:!1,dataChanged:!1,previousPaths:[],allSeriesHasEqualX:!0,pointsArray:[],dataLabelsRects:[],lastDrawnDataLabelsIndexes:[],hasNullValues:!1,easing:null,zoomed:!1,gridWidth:0,gridHeight:0,rotateXLabels:!1,defaultLabels:!1,xLabelFormatter:void 0,yLabelFormatters:[],xaxisTooltipFormatter:void 0,ttKeyFormatter:void 0,ttVal:void 0,ttZFormatter:void 0,LINE_HEIGHT_RATIO:1.618,xAxisLabelsHeight:0,xAxisGroupLabelsHeight:0,xAxisLabelsWidth:0,yAxisLabelsWidth:0,scaleX:1,scaleY:1,translateX:0,translateY:0,translateYAxisX:[],yAxisWidths:[],translateXAxisY:0,translateXAxisX:0,tooltip:null,niceScaleAllowedMagMsd:[[1,1,2,5,5,5,10,10,10,10,10],[1,1,2,5,5,5,10,10,10,10,10]],niceScaleDefaultTicks:[1,2,4,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,12,12,12,12,12,12,12,12,12,24],seriesYAxisMap:[],seriesYAxisReverseMap:[]}}},{key:"init",value:function(t){var e=this.globalVars(t);return this.initGlobalVars(e),e.initialConfig=S.extend({},t),e.initialSeries=S.clone(t.series),e.lastXAxis=S.clone(e.initialConfig.xaxis),e.lastYAxis=S.clone(e.initialConfig.yaxis),e}}]),t}(),H=function(){function t(e){o(this,t),this.opts=e}return l(t,[{key:"init",value:function(){var t=new $(this.opts).init({responsiveOverride:!1});return{config:t,globals:(new Y).init(t)}}}]),t}(),W=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.opts=null,this.seriesIndex=0,this.patternIDs=[]}return l(t,[{key:"clippedImgArea",value:function(t){var e=this.w,n=e.config,r=parseInt(e.globals.gridWidth,10),i=parseInt(e.globals.gridHeight,10),a=r>i?r:i,o=t.image,s=0,l=0;void 0===t.width&&void 0===t.height?void 0!==n.fill.image.width&&void 0!==n.fill.image.height?(s=n.fill.image.width+1,l=n.fill.image.height):(s=a+1,l=a):(s=t.width,l=t.height);var c=document.createElementNS(e.globals.SVGNS,"pattern");_.setAttrs(c,{id:t.patternID,patternUnits:t.patternUnits?t.patternUnits:"userSpaceOnUse",width:s+"px",height:l+"px"});var u=document.createElementNS(e.globals.SVGNS,"image");c.appendChild(u),u.setAttributeNS(window.SVG.xlink,"href",o),_.setAttrs(u,{x:0,y:0,preserveAspectRatio:"none",width:s+"px",height:l+"px"}),u.style.opacity=t.opacity,e.globals.dom.elDefs.node.appendChild(c)}},{key:"getSeriesIndex",value:function(t){var e=this.w,n=e.config.chart.type;return("bar"===n||"rangeBar"===n)&&e.config.plotOptions.bar.distributed||"heatmap"===n||"treemap"===n?this.seriesIndex=t.seriesNumber:this.seriesIndex=t.seriesNumber%e.globals.series.length,this.seriesIndex}},{key:"fillPath",value:function(t){var e=this.w;this.opts=t;var n,r,i,a=this.w.config;this.seriesIndex=this.getSeriesIndex(t);var o=this.getFillColors()[this.seriesIndex];void 0!==e.globals.seriesColors[this.seriesIndex]&&(o=e.globals.seriesColors[this.seriesIndex]),"function"==typeof o&&(o=o({seriesIndex:this.seriesIndex,dataPointIndex:t.dataPointIndex,value:t.value,w:e}));var s=t.fillType?t.fillType:this.getFillType(this.seriesIndex),l=Array.isArray(a.fill.opacity)?a.fill.opacity[this.seriesIndex]:a.fill.opacity;t.color&&(o=t.color),o||(o="#fff",console.warn("undefined color - ApexCharts"));var c=o;if(-1===o.indexOf("rgb")?o.length<9&&(c=S.hexToRgba(o,l)):o.indexOf("rgba")>-1&&(l=S.getOpacityFromRGBA(o)),t.opacity&&(l=t.opacity),"pattern"===s&&(r=this.handlePatternFill({fillConfig:t.fillConfig,patternFill:r,fillColor:o,fillOpacity:l,defaultColor:c})),"gradient"===s&&(i=this.handleGradientFill({fillConfig:t.fillConfig,fillColor:o,fillOpacity:l,i:this.seriesIndex})),"image"===s){var u=a.fill.image.src,h=t.patternID?t.patternID:"",d="pattern".concat(e.globals.cuid).concat(t.seriesNumber+1).concat(h);-1===this.patternIDs.indexOf(d)&&(this.clippedImgArea({opacity:l,image:Array.isArray(u)?t.seriesNumber-1&&(d=S.getOpacityFromRGBA(h));var f=void 0===a.gradient.opacityTo?n:Array.isArray(a.gradient.opacityTo)?a.gradient.opacityTo[i]:a.gradient.opacityTo;if(void 0===a.gradient.gradientToColors||0===a.gradient.gradientToColors.length)o="dark"===a.gradient.shade?c.shadeColor(-1*parseFloat(a.gradient.shadeIntensity),e.indexOf("rgb")>-1?S.rgb2hex(e):e):c.shadeColor(parseFloat(a.gradient.shadeIntensity),e.indexOf("rgb")>-1?S.rgb2hex(e):e);else if(a.gradient.gradientToColors[s.seriesNumber]){var p=a.gradient.gradientToColors[s.seriesNumber];o=p,p.indexOf("rgba")>-1&&(f=S.getOpacityFromRGBA(p))}else o=e;if(a.gradient.gradientFrom&&(h=a.gradient.gradientFrom),a.gradient.gradientTo&&(o=a.gradient.gradientTo),a.gradient.inverseColors){var v=h;h=o,o=v}return h.indexOf("rgb")>-1&&(h=S.rgb2hex(h)),o.indexOf("rgb")>-1&&(o=S.rgb2hex(o)),l.drawGradient(u,h,o,d,f,s.size,a.gradient.stops,a.gradient.colorStops,i)}}]),t}(),X=function(){function t(e,n){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"setGlobalMarkerSize",value:function(){var t=this.w;if(t.globals.markers.size=Array.isArray(t.config.markers.size)?t.config.markers.size:[t.config.markers.size],t.globals.markers.size.length>0){if(t.globals.markers.size.length4&&void 0!==arguments[4]&&arguments[4],o=this.w,s=e,l=t,c=null,u=new _(this.ctx),h=o.config.markers.discrete&&o.config.markers.discrete.length;if((o.globals.markers.size[e]>0||a||h)&&(c=u.group({class:a||h?"":"apexcharts-series-markers"})).attr("clip-path","url(#gridRectMarkerMask".concat(o.globals.cuid,")")),Array.isArray(l.x))for(var d=0;d0:o.config.markers.size>0)||a||h){S.isNumber(l.y[d])?p+=" w".concat(S.randomId()):p="apexcharts-nullpoint";var v=this.getMarkerConfig({cssClass:p,seriesIndex:e,dataPointIndex:f});o.config.series[s].data[f]&&(o.config.series[s].data[f].fillColor&&(v.pointFillColor=o.config.series[s].data[f].fillColor),o.config.series[s].data[f].strokeColor&&(v.pointStrokeColor=o.config.series[s].data[f].strokeColor)),void 0!==r&&(v.pSize=r),(l.x[d]<-o.globals.markers.largestSize||l.x[d]>o.globals.gridWidth+o.globals.markers.largestSize||l.y[d]<-o.globals.markers.largestSize||l.y[d]>o.globals.gridHeight+o.globals.markers.largestSize)&&(v.pSize=0),(i=u.drawMarker(l.x[d],l.y[d],v)).attr("rel",f),i.attr("j",f),i.attr("index",e),i.node.setAttribute("default-marker-size",v.pSize),new A(this.ctx).setSelectionFilter(i,e,f),this.addEvents(i),c&&c.add(i)}else void 0===o.globals.pointsArray[e]&&(o.globals.pointsArray[e]=[]),o.globals.pointsArray[e].push([l.x[d],l.y[d]])}return c}},{key:"getMarkerConfig",value:function(t){var e=t.cssClass,n=t.seriesIndex,r=t.dataPointIndex,i=void 0===r?null:r,a=t.radius,o=void 0===a?null:a,s=t.size,l=void 0===s?null:s,c=t.strokeWidth,u=void 0===c?null:c,h=this.w,d=this.getMarkerStyle(n),f=null===l?h.globals.markers.size[n]:l,p=h.config.markers;return null!==i&&p.discrete.length&&p.discrete.map((function(t){t.seriesIndex===n&&t.dataPointIndex===i&&(d.pointStrokeColor=t.strokeColor,d.pointFillColor=t.fillColor,f=t.size,d.pointShape=t.shape)})),{pSize:null===o?f:o,pRadius:null!==o?o:p.radius,pointStrokeWidth:null!==u?u:Array.isArray(p.strokeWidth)?p.strokeWidth[n]:p.strokeWidth,pointStrokeColor:d.pointStrokeColor,pointFillColor:d.pointFillColor,shape:d.pointShape||(Array.isArray(p.shape)?p.shape[n]:p.shape),class:e,pointStrokeOpacity:Array.isArray(p.strokeOpacity)?p.strokeOpacity[n]:p.strokeOpacity,pointStrokeDashArray:Array.isArray(p.strokeDashArray)?p.strokeDashArray[n]:p.strokeDashArray,pointFillOpacity:Array.isArray(p.fillOpacity)?p.fillOpacity[n]:p.fillOpacity,seriesIndex:n}}},{key:"addEvents",value:function(t){var e=this.w,n=new _(this.ctx);t.node.addEventListener("mouseenter",n.pathMouseEnter.bind(this.ctx,t)),t.node.addEventListener("mouseleave",n.pathMouseLeave.bind(this.ctx,t)),t.node.addEventListener("mousedown",n.pathMouseDown.bind(this.ctx,t)),t.node.addEventListener("click",e.config.markers.onClick),t.node.addEventListener("dblclick",e.config.markers.onDblClick),t.node.addEventListener("touchstart",n.pathMouseDown.bind(this.ctx,t),{passive:!0})}},{key:"getMarkerStyle",value:function(t){var e=this.w,n=e.globals.markers.colors,r=e.config.markers.strokeColor||e.config.markers.strokeColors;return{pointStrokeColor:Array.isArray(r)?r[t]:r,pointFillColor:Array.isArray(n)?n[t]:n}}}]),t}(),G=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.initialAnim=this.w.config.chart.animations.enabled}return l(t,[{key:"draw",value:function(t,e,n){var r=this.w,i=new _(this.ctx),a=n.realIndex,o=n.pointsPos,s=n.zRatio,l=n.elParent,c=i.group({class:"apexcharts-series-markers apexcharts-series-".concat(r.config.chart.type)});if(c.attr("clip-path","url(#gridRectMarkerMask".concat(r.globals.cuid,")")),Array.isArray(o.x))for(var u=0;up.maxBubbleRadius&&(f=p.maxBubbleRadius)}var v=o.x[u],g=o.y[u];if(f=f||0,null!==g&&void 0!==r.globals.series[a][h]||(d=!1),d){var m=this.drawPoint(v,g,f,a,h,e);c.add(m)}l.add(c)}}},{key:"drawPoint",value:function(t,e,n,r,i,a){var o=this.w,s=r,l=new C(this.ctx),c=new A(this.ctx),u=new W(this.ctx),h=new X(this.ctx),d=new _(this.ctx),f=h.getMarkerConfig({cssClass:"apexcharts-marker",seriesIndex:s,dataPointIndex:i,radius:"bubble"===o.config.chart.type||o.globals.comboCharts&&o.config.series[r]&&"bubble"===o.config.series[r].type?n:null}),p=u.fillPath({seriesNumber:r,dataPointIndex:i,color:f.pointFillColor,patternUnits:"objectBoundingBox",value:o.globals.series[r][a]}),v=d.drawMarker(t,e,f);if(o.config.series[s].data[i]&&o.config.series[s].data[i].fillColor&&(p=o.config.series[s].data[i].fillColor),v.attr({fill:p}),o.config.chart.dropShadow.enabled){var g=o.config.chart.dropShadow;c.dropShadow(v,g,r)}if(!this.initialAnim||o.globals.dataChanged||o.globals.resized)o.globals.animationEnded=!0;else{var m=o.config.chart.animations.speed;l.animateMarker(v,m,o.globals.easing,(function(){window.setTimeout((function(){l.animationCompleted(v)}),100)}))}return v.attr({rel:i,j:i,index:r,"default-marker-size":f.pSize}),c.setSelectionFilter(v,r,i),h.addEvents(v),v.node.classList.add("apexcharts-marker"),v}},{key:"centerTextInBubble",value:function(t){var e=this.w;return{y:t+=parseInt(e.config.dataLabels.style.fontSize,10)/4}}}]),t}(),U=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"dataLabelsCorrection",value:function(t,e,n,r,i,a,o){var s=this.w,l=!1,c=new _(this.ctx).getTextRects(n,o),u=c.width,h=c.height;e<0&&(e=0),e>s.globals.gridHeight+h&&(e=s.globals.gridHeight+h/2),void 0===s.globals.dataLabelsRects[r]&&(s.globals.dataLabelsRects[r]=[]),s.globals.dataLabelsRects[r].push({x:t,y:e,width:u,height:h});var d=s.globals.dataLabelsRects[r].length-2,f=void 0!==s.globals.lastDrawnDataLabelsIndexes[r]?s.globals.lastDrawnDataLabelsIndexes[r][s.globals.lastDrawnDataLabelsIndexes[r].length-1]:0;if(void 0!==s.globals.dataLabelsRects[r][d]){var p=s.globals.dataLabelsRects[r][f];(t>p.x+p.width||e>p.y+p.height||e+he.globals.gridWidth+m.textRects.width+30)&&(s="");var y=e.globals.dataLabels.style.colors[a];(("bar"===e.config.chart.type||"rangeBar"===e.config.chart.type)&&e.config.plotOptions.bar.distributed||e.config.dataLabels.distributed)&&(y=e.globals.dataLabels.style.colors[o]),"function"==typeof y&&(y=y({series:e.globals.series,seriesIndex:a,dataPointIndex:o,w:e})),d&&(y=d);var b=h.offsetX,x=h.offsetY;if("bar"!==e.config.chart.type&&"rangeBar"!==e.config.chart.type||(b=0,x=0),e.globals.isSlopeChart&&(0!==o&&(b=-2*h.offsetX+5),0!==o&&o!==e.config.series[a].data.length-1&&(b=0)),m.drawnextLabel){if((g=n.drawText({width:100,height:parseInt(h.style.fontSize,10),x:r+b,y:i+x,foreColor:y,textAnchor:l||h.textAnchor,text:s,fontSize:c||h.style.fontSize,fontFamily:h.style.fontFamily,fontWeight:h.style.fontWeight||"normal"})).attr({class:v||"apexcharts-datalabel",cx:r,cy:i}),h.dropShadow.enabled){var w=h.dropShadow;new A(this.ctx).dropShadow(g,w)}u.add(g),void 0===e.globals.lastDrawnDataLabelsIndexes[a]&&(e.globals.lastDrawnDataLabelsIndexes[a]=[]),e.globals.lastDrawnDataLabelsIndexes[a].push(o)}return g}},{key:"addBackgroundToDataLabel",value:function(t,e){var n=this.w,r=n.config.dataLabels.background,i=r.padding,a=r.padding/2,o=e.width,s=e.height,l=new _(this.ctx).drawRect(e.x-i,e.y-a/2,o+2*i,s+a,r.borderRadius,"transparent"!==n.config.chart.background&&n.config.chart.background?n.config.chart.background:"#fff",r.opacity,r.borderWidth,r.borderColor);return r.dropShadow.enabled&&new A(this.ctx).dropShadow(l,r.dropShadow),l}},{key:"dataLabelsBackground",value:function(){var t=this.w;if("bubble"!==t.config.chart.type)for(var e=t.globals.dom.baseEl.querySelectorAll(".apexcharts-datalabels text"),n=0;n0&&void 0!==arguments[0])||arguments[0],e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=this.w,i=S.clone(r.globals.initialSeries);r.globals.previousPaths=[],n?(r.globals.collapsedSeries=[],r.globals.ancillaryCollapsedSeries=[],r.globals.collapsedSeriesIndices=[],r.globals.ancillaryCollapsedSeriesIndices=[]):i=this.emptyCollapsedSeries(i),r.config.series=i,t&&(e&&(r.globals.zoomed=!1,this.ctx.updateHelpers.revertDefaultAxisMinMax()),this.ctx.updateHelpers._updateSeries(i,r.config.chart.animations.dynamicAnimation.enabled))}},{key:"emptyCollapsedSeries",value:function(t){for(var e=this.w,n=0;n-1&&(t[n].data=[]);return t}},{key:"highlightSeries",value:function(t){var e=this.w,n=this.getSeriesByName(t),r=parseInt(null==n?void 0:n.getAttribute("data:realIndex"),10),i=e.globals.dom.baseEl.querySelectorAll(".apexcharts-series, .apexcharts-datalabels, .apexcharts-yaxis"),a=null,o=null,s=null;if(e.globals.axisCharts||"radialBar"===e.config.chart.type)if(e.globals.axisCharts){a=e.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(r,"']")),o=e.globals.dom.baseEl.querySelector(".apexcharts-datalabels[data\\:realIndex='".concat(r,"']"));var l=e.globals.seriesYAxisReverseMap[r];s=e.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(l,"']"))}else a=e.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(r+1,"']"));else a=e.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(r+1,"'] path"));for(var c=0;c=t.from&&(a0&&void 0!==arguments[0]?arguments[0]:"asc",e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=this.w,r=0;if(n.config.series.length>1)for(var i=n.config.series.map((function(t,r){return t.data&&t.data.length>0&&-1===n.globals.collapsedSeriesIndices.indexOf(r)&&(!n.globals.comboCharts||0===e.length||e.length&&e.indexOf(n.config.series[r].type)>-1)?r:-1})),a="asc"===t?0:i.length-1;"asc"===t?a=0;"asc"===t?a++:a--)if(-1!==i[a]){r=i[a];break}return r}},{key:"getBarSeriesIndices",value:function(){return this.w.globals.comboCharts?this.w.config.series.map((function(t,e){return"bar"===t.type||"column"===t.type?e:-1})).filter((function(t){return-1!==t})):this.w.config.series.map((function(t,e){return e}))}},{key:"getPreviousPaths",value:function(){var t=this.w;function e(e,n,r){for(var i=e[n].childNodes,a={type:r,paths:[],realIndex:e[n].getAttribute("data:realIndex")},o=0;o0)for(var r=function(e){for(var n=t.globals.dom.baseEl.querySelectorAll(".apexcharts-".concat(t.config.chart.type," .apexcharts-series[data\\:realIndex='").concat(e,"'] rect")),r=[],i=function(t){var e=function(e){return n[t].getAttribute(e)},i={x:parseFloat(e("x")),y:parseFloat(e("y")),width:parseFloat(e("width")),height:parseFloat(e("height"))};r.push({rect:i,color:n[t].getAttribute("color")})},a=0;a0)for(var r=0;r0?t:[]}));return t}}]),t}(),Z=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.twoDSeries=[],this.threeDSeries=[],this.twoDSeriesX=[],this.seriesGoals=[],this.coreUtils=new D(this.ctx)}return l(t,[{key:"isMultiFormat",value:function(){return this.isFormatXY()||this.isFormat2DArray()}},{key:"isFormatXY",value:function(){var t=this.w.config.series.slice(),e=new q(this.ctx);if(this.activeSeriesIndex=e.getActiveConfigSeriesIndex(),void 0!==t[this.activeSeriesIndex].data&&t[this.activeSeriesIndex].data.length>0&&null!==t[this.activeSeriesIndex].data[0]&&void 0!==t[this.activeSeriesIndex].data[0].x&&null!==t[this.activeSeriesIndex].data[0])return!0}},{key:"isFormat2DArray",value:function(){var t=this.w.config.series.slice(),e=new q(this.ctx);if(this.activeSeriesIndex=e.getActiveConfigSeriesIndex(),void 0!==t[this.activeSeriesIndex].data&&t[this.activeSeriesIndex].data.length>0&&void 0!==t[this.activeSeriesIndex].data[0]&&null!==t[this.activeSeriesIndex].data[0]&&t[this.activeSeriesIndex].data[0].constructor===Array)return!0}},{key:"handleFormat2DArray",value:function(t,e){for(var n=this.w.config,r=this.w.globals,i="boxPlot"===n.chart.type||"boxPlot"===n.series[e].type,a=0;a=5?this.twoDSeries.push(S.parseNumber(t[e].data[a][4])):this.twoDSeries.push(S.parseNumber(t[e].data[a][1])),r.dataFormatXNumeric=!0),"datetime"===n.xaxis.type){var o=new Date(t[e].data[a][0]);o=new Date(o).getTime(),this.twoDSeriesX.push(o)}else this.twoDSeriesX.push(t[e].data[a][0]);for(var s=0;s-1&&(a=this.activeSeriesIndex);for(var o=0;o1&&void 0!==arguments[1]?arguments[1]:this.ctx,r=this.w.config,i=this.w.globals,a=new O(n),o=r.labels.length>0?r.labels.slice():r.xaxis.categories.slice();i.isRangeBar="rangeBar"===r.chart.type&&i.isBarHorizontal,i.hasXaxisGroups="category"===r.xaxis.type&&r.xaxis.group.groups.length>0,i.hasXaxisGroups&&(i.groups=r.xaxis.group.groups),t.forEach((function(t,e){void 0!==t.name?i.seriesNames.push(t.name):i.seriesNames.push("series-"+parseInt(e+1,10))})),this.coreUtils.setSeriesYAxisMappings();var s=[],l=b(new Set(r.series.map((function(t){return t.group}))));r.series.forEach((function(t,e){var n=l.indexOf(t.group);s[n]||(s[n]=[]),s[n].push(i.seriesNames[e])})),i.seriesGroups=s;for(var c=function(){for(var t=0;t0&&(this.twoDSeriesX=o,i.seriesX.push(this.twoDSeriesX))),i.labels.push(this.twoDSeriesX);var h=t[u].data.map((function(t){return S.parseNumber(t)}));i.series.push(h)}i.seriesZ.push(this.threeDSeries),void 0!==t[u].color?i.seriesColors.push(t[u].color):i.seriesColors.push(void 0)}return this.w}},{key:"parseDataNonAxisCharts",value:function(t){var e=this.w.globals,n=this.w.config;e.series=t.slice(),e.seriesNames=n.labels.slice();for(var r=0;r0?n.labels=e.xaxis.categories:e.labels.length>0?n.labels=e.labels.slice():this.fallbackToCategory?(n.labels=n.labels[0],n.seriesRange.length&&(n.seriesRange.map((function(t){t.forEach((function(t){n.labels.indexOf(t.x)<0&&t.x&&n.labels.push(t.x)}))})),n.labels=Array.from(new Set(n.labels.map(JSON.stringify)),JSON.parse)),e.xaxis.convertedCatToNumeric&&(new z(e).convertCatToNumericXaxis(e,this.ctx,n.seriesX[0]),this._generateExternalLabels(t))):this._generateExternalLabels(t)}},{key:"_generateExternalLabels",value:function(t){var e=this.w.globals,n=this.w.config,r=[];if(e.axisCharts){if(e.series.length>0)if(this.isFormatXY())for(var i=n.series.map((function(t,e){return t.data.filter((function(t,e,n){return n.findIndex((function(e){return e.x===t.x}))===e}))})),a=i.reduce((function(t,e,n,r){return r[t].length>e.length?t:n}),0),o=0;o0&&i==n.length&&e.push(r)})),t.globals.ignoreYAxisIndexes=e.map((function(t){return t}))}}]),t}(),K=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"scaleSvgNode",value:function(t,e){var n=parseFloat(t.getAttributeNS(null,"width")),r=parseFloat(t.getAttributeNS(null,"height"));t.setAttributeNS(null,"width",n*e),t.setAttributeNS(null,"height",r*e),t.setAttributeNS(null,"viewBox","0 0 "+n+" "+r)}},{key:"getSvgString",value:function(){var t=this;return new Promise((function(e){var n=t.w,r=n.config.chart.toolbar.export.width,i=n.config.chart.toolbar.export.scale||r/n.globals.svgWidth;i||(i=1);var a=t.w.globals.dom.Paper.svg(),o=t.w.globals.dom.Paper.node.cloneNode(!0);1!==i&&t.scaleSvgNode(o,i),t.convertImagesToBase64(o).then((function(){a=(new XMLSerializer).serializeToString(o),e(a.replace(/ /g," "))}))}))}},{key:"convertImagesToBase64",value:function(t){var e=this,n=t.getElementsByTagName("image"),r=Array.from(n).map((function(t){var n=t.getAttributeNS("http://www.w3.org/1999/xlink","href");return n&&!n.startsWith("data:")?e.getBase64FromUrl(n).then((function(e){t.setAttributeNS("http://www.w3.org/1999/xlink","href",e)})).catch((function(t){console.error("Error converting image to base64:",t)})):Promise.resolve()}));return Promise.all(r)}},{key:"getBase64FromUrl",value:function(t){return new Promise((function(e,n){var r=new Image;r.crossOrigin="Anonymous",r.onload=function(){var t=document.createElement("canvas");t.width=r.width,t.height=r.height,t.getContext("2d").drawImage(r,0,0),e(t.toDataURL())},r.onerror=n,r.src=t}))}},{key:"cleanup",value:function(){var t=this.w,e=t.globals.dom.baseEl.getElementsByClassName("apexcharts-xcrosshairs"),n=t.globals.dom.baseEl.getElementsByClassName("apexcharts-ycrosshairs"),r=t.globals.dom.baseEl.querySelectorAll(".apexcharts-zoom-rect, .apexcharts-selection-rect");Array.prototype.forEach.call(r,(function(t){t.setAttribute("width",0)})),e&&e[0]&&(e[0].setAttribute("x",-500),e[0].setAttribute("x1",-500),e[0].setAttribute("x2",-500)),n&&n[0]&&(n[0].setAttribute("y",-100),n[0].setAttribute("y1",-100),n[0].setAttribute("y2",-100))}},{key:"svgUrl",value:function(){var t=this;return new Promise((function(e){t.cleanup(),t.getSvgString().then((function(t){var n=new Blob([t],{type:"image/svg+xml;charset=utf-8"});e(URL.createObjectURL(n))}))}))}},{key:"dataURI",value:function(t){var e=this;return new Promise((function(n){var r=e.w,i=t?t.scale||t.width/r.globals.svgWidth:1;e.cleanup();var a=document.createElement("canvas");a.width=r.globals.svgWidth*i,a.height=parseInt(r.globals.dom.elWrap.style.height,10)*i;var o="transparent"!==r.config.chart.background&&r.config.chart.background?r.config.chart.background:"#fff",s=a.getContext("2d");s.fillStyle=o,s.fillRect(0,0,a.width*i,a.height*i),e.getSvgString().then((function(t){var e="data:image/svg+xml,"+encodeURIComponent(t),r=new Image;r.crossOrigin="anonymous",r.onload=function(){if(s.drawImage(r,0,0),a.msToBlob){var t=a.msToBlob();n({blob:t})}else{var e=a.toDataURL("image/png");n({imgURI:e})}},r.src=e}))}))}},{key:"exportToSVG",value:function(){var t=this;this.svgUrl().then((function(e){t.triggerDownload(e,t.w.config.chart.toolbar.export.svg.filename,".svg")}))}},{key:"exportToPng",value:function(){var t=this,e=this.w.config.chart.toolbar.export.scale,n=this.w.config.chart.toolbar.export.width,r=e?{scale:e}:n?{width:n}:void 0;this.dataURI(r).then((function(e){var n=e.imgURI,r=e.blob;r?navigator.msSaveOrOpenBlob(r,t.w.globals.chartID+".png"):t.triggerDownload(n,t.w.config.chart.toolbar.export.png.filename,".png")}))}},{key:"exportToCSV",value:function(t){var e=this,n=t.series,r=t.fileName,i=t.columnDelimiter,a=void 0===i?",":i,o=t.lineDelimiter,s=void 0===o?"\n":o,l=this.w;n||(n=l.config.series);var c,u,h=[],d=[],f="",p=l.globals.series.map((function(t,e){return-1===l.globals.collapsedSeriesIndices.indexOf(e)?t:[]})),v=function(t){return"function"==typeof l.config.chart.toolbar.export.csv.categoryFormatter?l.config.chart.toolbar.export.csv.categoryFormatter(t):"datetime"===l.config.xaxis.type&&String(t).length>=10?new Date(t).toDateString():S.isNumber(t)?t:t.split(a).join("")},g=function(t){return"function"==typeof l.config.chart.toolbar.export.csv.valueFormatter?l.config.chart.toolbar.export.csv.valueFormatter(t):t},m=Math.max.apply(Math,b(n.map((function(t){return t.data?t.data.length:0})))),y=new Z(this.ctx),x=new I(this.ctx),w=function(t){var n="";if(l.globals.axisCharts){if("category"===l.config.xaxis.type||l.config.xaxis.convertedCatToNumeric)if(l.globals.isBarHorizontal){var r=l.globals.yLabelFormatters[0],i=new q(e.ctx).getActiveConfigSeriesIndex();n=r(l.globals.labels[t],{seriesIndex:i,dataPointIndex:t,w:l})}else n=x.getLabel(l.globals.labels,l.globals.timescaleLabels,0,t).text;"datetime"===l.config.xaxis.type&&(l.config.xaxis.categories.length?n=l.config.xaxis.categories[t]:l.config.labels.length&&(n=l.config.labels[t]))}else n=l.config.labels[t];return null===n?"nullvalue":(Array.isArray(n)&&(n=n.join(" ")),S.isNumber(n)?n:n.split(a).join(""))},k=function(t,e){if(h.length&&0===e&&d.push(h.join(a)),t.data){t.data=t.data.length&&t.data||b(Array(m)).map((function(){return""}));for(var r=0;r0&&!r.globals.isBarHorizontal&&(this.xaxisLabels=r.globals.timescaleLabels.slice()),r.config.xaxis.overwriteCategories&&(this.xaxisLabels=r.config.xaxis.overwriteCategories),this.drawnLabels=[],this.drawnLabelsRects=[],"top"===r.config.xaxis.position?this.offY=0:this.offY=r.globals.gridHeight,this.offY=this.offY+r.config.xaxis.axisBorder.offsetY,this.isCategoryBarHorizontal="bar"===r.config.chart.type&&r.config.plotOptions.bar.horizontal,this.xaxisFontSize=r.config.xaxis.labels.style.fontSize,this.xaxisFontFamily=r.config.xaxis.labels.style.fontFamily,this.xaxisForeColors=r.config.xaxis.labels.style.colors,this.xaxisBorderWidth=r.config.xaxis.axisBorder.width,this.isCategoryBarHorizontal&&(this.xaxisBorderWidth=r.config.yaxis[0].axisBorder.width.toString()),this.xaxisBorderWidth.indexOf("%")>-1?this.xaxisBorderWidth=r.globals.gridWidth*parseInt(this.xaxisBorderWidth,10)/100:this.xaxisBorderWidth=parseInt(this.xaxisBorderWidth,10),this.xaxisBorderHeight=r.config.xaxis.axisBorder.height,this.yaxis=r.config.yaxis[0]}return l(t,[{key:"drawXaxis",value:function(){var t=this.w,e=new _(this.ctx),n=e.group({class:"apexcharts-xaxis",transform:"translate(".concat(t.config.xaxis.offsetX,", ").concat(t.config.xaxis.offsetY,")")}),r=e.group({class:"apexcharts-xaxis-texts-g",transform:"translate(".concat(t.globals.translateXAxisX,", ").concat(t.globals.translateXAxisY,")")});n.add(r);for(var i=[],a=0;a6&&void 0!==arguments[6]?arguments[6]:{},c=[],u=[],h=this.w,d=l.xaxisFontSize||this.xaxisFontSize,f=l.xaxisFontFamily||this.xaxisFontFamily,p=l.xaxisForeColors||this.xaxisForeColors,v=l.fontWeight||h.config.xaxis.labels.style.fontWeight,g=l.cssClass||h.config.xaxis.labels.style.cssClass,m=h.globals.padHorizontal,y=r.length,b="category"===h.config.xaxis.type?h.globals.dataPoints:y;if(0===b&&y>b&&(b=y),i){var x=b>1?b-1:b;o=h.globals.gridWidth/Math.min(x,y-1),m=m+a(0,o)/2+h.config.xaxis.labels.offsetX}else o=h.globals.gridWidth/b,m=m+a(0,o)+h.config.xaxis.labels.offsetX;for(var w=function(i){var l=m-a(i,o)/2+h.config.xaxis.labels.offsetX;0===i&&1===y&&o/2===m&&1===b&&(l=h.globals.gridWidth/2);var x=s.axesUtils.getLabel(r,h.globals.timescaleLabels,l,i,c,d,t),w=28;if(h.globals.rotateXLabels&&t&&(w=22),h.config.xaxis.title.text&&"top"===h.config.xaxis.position&&(w+=parseFloat(h.config.xaxis.title.style.fontSize)+2),t||(w=w+parseFloat(d)+(h.globals.xAxisLabelsHeight-h.globals.xAxisGroupLabelsHeight)+(h.globals.rotateXLabels?10:0)),x=void 0!==h.config.xaxis.tickAmount&&"dataPoints"!==h.config.xaxis.tickAmount&&"datetime"!==h.config.xaxis.type?s.axesUtils.checkLabelBasedOnTickamount(i,x,y):s.axesUtils.checkForOverflowingLabels(i,x,y,c,u),h.config.xaxis.labels.show){var k=e.drawText({x:x.x,y:s.offY+h.config.xaxis.labels.offsetY+w-("top"===h.config.xaxis.position?h.globals.xAxisHeight+h.config.xaxis.axisTicks.height-2:0),text:x.text,textAnchor:"middle",fontWeight:x.isBold?600:v,fontSize:d,fontFamily:f,foreColor:Array.isArray(p)?t&&h.config.xaxis.convertedCatToNumeric?p[h.globals.minX+i-1]:p[i]:p,isPlainText:!1,cssClass:(t?"apexcharts-xaxis-label ":"apexcharts-xaxis-group-label ")+g});if(n.add(k),k.on("click",(function(t){if("function"==typeof h.config.chart.events.xAxisLabelClick){var e=Object.assign({},h,{labelIndex:i});h.config.chart.events.xAxisLabelClick(t,s.ctx,e)}})),t){var S=document.createElementNS(h.globals.SVGNS,"title");S.textContent=Array.isArray(x.text)?x.text.join(" "):x.text,k.node.appendChild(S),""!==x.text&&(c.push(x.text),u.push(x))}}ir.globals.gridWidth)){var a=this.offY+r.config.xaxis.axisTicks.offsetY;if(e=e+a+r.config.xaxis.axisTicks.height,"top"===r.config.xaxis.position&&(e=a-r.config.xaxis.axisTicks.height),r.config.xaxis.axisTicks.show){var o=new _(this.ctx).drawLine(t+r.config.xaxis.axisTicks.offsetX,a+r.config.xaxis.offsetY,i+r.config.xaxis.axisTicks.offsetX,e+r.config.xaxis.offsetY,r.config.xaxis.axisTicks.color);n.add(o),o.node.classList.add("apexcharts-xaxis-tick")}}}},{key:"getXAxisTicksPositions",value:function(){var t=this.w,e=[],n=this.xaxisLabels.length,r=t.globals.padHorizontal;if(t.globals.timescaleLabels.length>0)for(var i=0;i0){var c=i[i.length-1].getBBox(),u=i[0].getBBox();c.x<-20&&i[i.length-1].parentNode.removeChild(i[i.length-1]),u.x+u.width>t.globals.gridWidth&&!t.globals.isBarHorizontal&&i[0].parentNode.removeChild(i[0]);for(var h=0;h0&&(this.xaxisLabels=n.globals.timescaleLabels.slice())}return l(t,[{key:"drawGridArea",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=this.w,n=new _(this.ctx);t||(t=n.group({class:"apexcharts-grid"}));var r=n.drawLine(e.globals.padHorizontal,1,e.globals.padHorizontal,e.globals.gridHeight,"transparent"),i=n.drawLine(e.globals.padHorizontal,e.globals.gridHeight,e.globals.gridWidth,e.globals.gridHeight,"transparent");return t.add(i),t.add(r),t}},{key:"drawGrid",value:function(){if(this.w.globals.axisCharts){var t=this.renderGrid();return this.drawGridArea(t.el),t}return null}},{key:"createGridMask",value:function(){var t=this.w,e=t.globals,n=new _(this.ctx),r=Array.isArray(t.config.stroke.width)?Math.max.apply(Math,b(t.config.stroke.width)):t.config.stroke.width,i=function(t){var n=document.createElementNS(e.SVGNS,"clipPath");return n.setAttribute("id",t),n};e.dom.elGridRectMask=i("gridRectMask".concat(e.cuid)),e.dom.elGridRectBarMask=i("gridRectBarMask".concat(e.cuid)),e.dom.elGridRectMarkerMask=i("gridRectMarkerMask".concat(e.cuid)),e.dom.elForecastMask=i("forecastMask".concat(e.cuid)),e.dom.elNonForecastMask=i("nonForecastMask".concat(e.cuid));var a=0,o=0;(["bar","rangeBar","candlestick","boxPlot"].includes(t.config.chart.type)||t.globals.comboBarCount>0)&&t.globals.isXNumeric&&!t.globals.isBarHorizontal&&(a=Math.max(t.config.grid.padding.left,e.barPadForNumericAxis),o=Math.max(t.config.grid.padding.right,e.barPadForNumericAxis)),e.dom.elGridRect=n.drawRect(0,0,e.gridWidth,e.gridHeight,0,"#fff"),e.dom.elGridRectBar=n.drawRect(-r/2-a-2,-r/2-2,e.gridWidth+r+o+a+4,e.gridHeight+r+4,0,"#fff");var s=t.globals.markers.largestSize;e.dom.elGridRectMarker=n.drawRect(-s,-s,e.gridWidth+2*s,e.gridHeight+2*s,0,"#fff"),e.dom.elGridRectMask.appendChild(e.dom.elGridRect.node),e.dom.elGridRectBarMask.appendChild(e.dom.elGridRectBar.node),e.dom.elGridRectMarkerMask.appendChild(e.dom.elGridRectMarker.node);var l=e.dom.baseEl.querySelector("defs");l.appendChild(e.dom.elGridRectMask),l.appendChild(e.dom.elGridRectBarMask),l.appendChild(e.dom.elGridRectMarkerMask),l.appendChild(e.dom.elForecastMask),l.appendChild(e.dom.elNonForecastMask)}},{key:"_drawGridLines",value:function(t){var e=t.i,n=t.x1,r=t.y1,i=t.x2,a=t.y2,o=t.xCount,s=t.parent,l=this.w;if(!(0===e&&l.globals.skipFirstTimelinelabel||e===o-1&&l.globals.skipLastTimelinelabel&&!l.config.xaxis.labels.formatter||"radar"===l.config.chart.type)){l.config.grid.xaxis.lines.show&&this._drawGridLine({i:e,x1:n,y1:r,x2:i,y2:a,xCount:o,parent:s});var c=0;if(l.globals.hasXaxisGroups&&"between"===l.config.xaxis.tickPlacement){var u=l.globals.groups;if(u){for(var h=0,d=0;h0&&"datetime"!==t.config.xaxis.type&&(i=e.yAxisScale[r].result.length-1)),this._drawXYLines({xCount:i,tickAmount:l})):(i=l,l=e.xTickAmount,this._drawInvertedXYLines({xCount:i,tickAmount:l}));return this.drawGridBands(i,l),{el:this.elg,elGridBorders:this.elGridBorders,xAxisTickWidth:e.gridWidth/i}}},{key:"drawGridBands",value:function(t,e){var n,r,i=this,a=this.w;if((null===(n=a.config.grid.row.colors)||void 0===n?void 0:n.length)>0&&function(t,n,r,o,s,l){for(var c=0,u=0;c=a.config.grid[t].colors.length&&(u=0),i._drawGridBandRect({c:u,x1:r,y1:o,x2:s,y2:l,type:t}),o+=a.globals.gridHeight/e}("row",e,0,0,a.globals.gridWidth,a.globals.gridHeight/e),(null===(r=a.config.grid.column.colors)||void 0===r?void 0:r.length)>0){var o=a.globals.isBarHorizontal||"on"!==a.config.xaxis.tickPlacement||"category"!==a.config.xaxis.type&&!a.config.xaxis.convertedCatToNumeric?t:t-1;a.globals.isXNumeric&&(o=a.globals.xAxisScale.result.length-1);for(var s=a.globals.padHorizontal,l=a.globals.padHorizontal+a.globals.gridWidth/o,c=a.globals.gridHeight,u=0,h=0;u=a.config.grid.column.colors.length&&(h=0),"datetime"===a.config.xaxis.type&&(s=this.xaxisLabels[u].position,l=((null===(d=this.xaxisLabels[u+1])||void 0===d?void 0:d.position)||a.globals.gridWidth)-this.xaxisLabels[u].position),this._drawGridBandRect({c:h,x1:s,y1:0,x2:l,y2:c,type:"column"}),s+=a.globals.gridWidth/o}}}}]),t}(),tt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.coreUtils=new D(this.ctx)}return l(t,[{key:"niceScale",value:function(t,e){var n,r,i,a,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,s=1e-11,l=this.w,c=l.globals;c.isBarHorizontal?(n=l.config.xaxis,r=Math.max((c.svgWidth-100)/25,2)):(n=l.config.yaxis[o],r=Math.max((c.svgHeight-100)/15,2)),S.isNumber(r)||(r=10),i=void 0!==n.min&&null!==n.min,a=void 0!==n.max&&null!==n.min;var u=void 0!==n.stepSize&&null!==n.stepSize,h=void 0!==n.tickAmount&&null!==n.tickAmount,d=h?n.tickAmount:c.niceScaleDefaultTicks[Math.min(Math.round(r/2),c.niceScaleDefaultTicks.length-1)];if(c.isMultipleYAxis&&!h&&c.multiAxisTickAmount>0&&(d=c.multiAxisTickAmount,h=!0),d="dataPoints"===d?c.dataPoints-1:Math.abs(Math.round(d)),(t===Number.MIN_VALUE&&0===e||!S.isNumber(t)&&!S.isNumber(e)||t===Number.MIN_VALUE&&e===-Number.MAX_VALUE)&&(t=S.isNumber(n.min)?n.min:0,e=S.isNumber(n.max)?n.max:t+d,c.allSeriesCollapsed=!1),t>e){console.warn("axis.min cannot be greater than axis.max: swapping min and max");var f=e;e=t,t=f}else t===e&&(t=0===t?0:t-1,e=0===e?2:e+1);var p=[];d<1&&(d=1);var v=d,g=Math.abs(e-t);!i&&t>0&&t/g<.15&&(t=0,i=!0),!a&&e<0&&-e/g<.15&&(e=0,a=!0);var m=(g=Math.abs(e-t))/v,y=m,b=Math.floor(Math.log10(y)),x=Math.pow(10,b),w=Math.ceil(y/x);if(m=y=(w=c.niceScaleAllowedMagMsd[0===c.yValueDecimal?0:1][w])*x,c.isBarHorizontal&&n.stepSize&&"datetime"!==n.type?(m=n.stepSize,u=!0):u&&(m=n.stepSize),u&&n.forceNiceScale){var k=Math.floor(Math.log10(m));m*=Math.pow(10,b-k)}if(i&&a){var C=g/v;if(h)if(u)if(0!=S.mod(g,m)){var A=S.getGCD(m,C);m=C/A<10?A:C}else 0==S.mod(m,C)?m=C:(C=m,h=!1);else m=C;else if(u)0==S.mod(g,m)?C=m:m=C;else if(0==S.mod(g,m))C=m;else{C=g/(v=Math.ceil(g/m));var _=S.getGCD(g,m);g/_r&&(t=e-m*d,t+=m*Math.floor((D-t)/m))}else if(i)if(h)e=t+m*v;else{var T=e;e=m*Math.ceil(e/m),Math.abs(e-t)/S.getGCD(g,m)>r&&(e=t+m*d,e+=m*Math.ceil((T-e)/m))}}else if(c.isMultipleYAxis&&h){var E=m*Math.floor(t/m),O=E+m*v;O0&&t16&&S.getPrimeFactors(v).length<2&&v++,!h&&n.forceNiceScale&&0===c.yValueDecimal&&v>g&&(v=g,m=Math.round(g/v)),v>r&&(!h&&!u||n.forceNiceScale)){var P=S.getPrimeFactors(v),I=P.length-1,M=v;t:for(var V=0;Vz);return{result:p,niceMin:p[0],niceMax:p[p.length-1]}}},{key:"linearScale",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:10,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:void 0,a=Math.abs(e-t),o=[];if(t===e)return{result:o=[t],niceMin:o[0],niceMax:o[o.length-1]};"dataPoints"===(n=this._adjustTicksForSmallRange(n,r,a))&&(n=this.w.globals.dataPoints-1),i||(i=a/n),i=Math.round(10*(i+Number.EPSILON))/10,n===Number.MAX_VALUE&&(n=5,i=1);for(var s=t;n>=0;)o.push(s),s=S.preciseAddition(s,i),n-=1;return{result:o,niceMin:o[0],niceMax:o[o.length-1]}}},{key:"logarithmicScaleNice",value:function(t,e,n){e<=0&&(e=Math.max(t,n)),t<=0&&(t=Math.min(e,n));for(var r=[],i=Math.ceil(Math.log(e)/Math.log(n)+1),a=Math.floor(Math.log(t)/Math.log(n));a5?(r.allSeriesCollapsed=!1,r.yAxisScale[t]=a.forceNiceScale?this.logarithmicScaleNice(e,n,a.logBase):this.logarithmicScale(e,n,a.logBase)):n!==-Number.MAX_VALUE&&S.isNumber(n)&&e!==Number.MAX_VALUE&&S.isNumber(e)?(r.allSeriesCollapsed=!1,r.yAxisScale[t]=this.niceScale(e,n,t)):r.yAxisScale[t]=this.niceScale(Number.MIN_VALUE,0,t)}},{key:"setXScale",value:function(t,e){var n=this.w,r=n.globals,i=Math.abs(e-t);if(e!==-Number.MAX_VALUE&&S.isNumber(e)){var a=r.xTickAmount+1;i<10&&i>1&&(a=i),r.xAxisScale=this.linearScale(t,e,a,0,n.config.xaxis.stepSize)}else r.xAxisScale=this.linearScale(0,10,10);return r.xAxisScale}},{key:"scaleMultipleYAxes",value:function(){var t=this,e=this.w.config,n=this.w.globals;this.coreUtils.setSeriesYAxisMappings();var r=n.seriesYAxisMap,i=n.minYArr,a=n.maxYArr;n.allSeriesCollapsed=!0,n.barGroups=[],r.forEach((function(r,o){var s=[];r.forEach((function(t){var n=e.series[t].group;s.indexOf(n)<0&&s.push(n)})),r.length>0?function(){var l,c,u=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=u,f=h;if(e.chart.stacked)!function(){var t=new Array(n.dataPoints).fill(0),i=[],a=[],p=[];s.forEach((function(){i.push(t.map((function(){return Number.MIN_VALUE}))),a.push(t.map((function(){return Number.MIN_VALUE}))),p.push(t.map((function(){return Number.MIN_VALUE})))}));for(var v=function(t){!l&&e.series[r[t]].type&&(l=e.series[r[t]].type);var u=r[t];c=e.series[u].group?e.series[u].group:"axis-".concat(o),!(n.collapsedSeriesIndices.indexOf(u)<0&&n.ancillaryCollapsedSeriesIndices.indexOf(u)<0)||(n.allSeriesCollapsed=!1,s.forEach((function(t,r){if(e.series[u].group===t)for(var o=0;o=0?a[r][o]+=s:p[r][o]+=s,i[r][o]+=s,d=Math.min(d,s),f=Math.max(f,s)}}))),"bar"!==l&&"column"!==l||n.barGroups.push(c)},g=0;g1&&void 0!==arguments[1]?arguments[1]:Number.MAX_VALUE,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:-Number.MAX_VALUE,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,i=this.w.config,a=this.w.globals,o=-Number.MAX_VALUE,s=Number.MIN_VALUE;null===r&&(r=t+1);var l=a.series,c=l,u=l;"candlestick"===i.chart.type?(c=a.seriesCandleL,u=a.seriesCandleH):"boxPlot"===i.chart.type?(c=a.seriesCandleO,u=a.seriesCandleC):a.isRangeData&&(c=a.seriesRangeStart,u=a.seriesRangeEnd);var h=!1;if(a.seriesX.length>=r){var d,f=null===(d=a.brushSource)||void 0===d?void 0:d.w.config.chart.brush;(i.chart.zoom.enabled&&i.chart.zoom.autoScaleYaxis||null!=f&&f.enabled&&null!=f&&f.autoScaleYaxis)&&(h=!0)}for(var p=t;pg&&a.seriesX[p][m]>i.xaxis.max;m--);}for(var y=g;y<=m&&yc[p][y]&&c[p][y]<0&&(s=c[p][y])}else a.hasNullValues=!0}"bar"!==v&&"column"!==v||(s<0&&o<0&&(o=0,n=Math.max(n,0)),s===Number.MIN_VALUE&&(s=0,e=Math.min(e,0)))}return"rangeBar"===i.chart.type&&a.seriesRangeStart.length&&a.isBarHorizontal&&(s=e),"bar"===i.chart.type&&(s<0&&o<0&&(o=0),s===Number.MIN_VALUE&&(s=0)),{minY:s,maxY:o,lowestY:e,highestY:n}}},{key:"setYRange",value:function(){var t=this.w.globals,e=this.w.config;t.maxY=-Number.MAX_VALUE,t.minY=Number.MIN_VALUE;var n,r=Number.MAX_VALUE;if(t.isMultipleYAxis){r=Number.MAX_VALUE;for(var i=0;it.dataPoints&&0!==t.dataPoints&&(r=t.dataPoints-1);else if("dataPoints"===e.xaxis.tickAmount){if(t.series.length>1&&(r=t.series[t.maxValsInArrayIndex].length-1),t.isXNumeric){var i=t.maxX-t.minX;i<30&&(r=i-1)}}else r=e.xaxis.tickAmount;if(t.xTickAmount=r,void 0!==e.xaxis.max&&"number"==typeof e.xaxis.max&&(t.maxX=e.xaxis.max),void 0!==e.xaxis.min&&"number"==typeof e.xaxis.min&&(t.minX=e.xaxis.min),void 0!==e.xaxis.range&&(t.minX=t.maxX-e.xaxis.range),t.minX!==Number.MAX_VALUE&&t.maxX!==-Number.MAX_VALUE)if(e.xaxis.convertedCatToNumeric&&!t.dataFormatXNumeric){for(var a=[],o=t.minX-1;o0&&(t.xAxisScale=this.scales.linearScale(1,t.labels.length,r-1,0,e.xaxis.stepSize),t.seriesX=t.labels.slice());n&&(t.labels=t.xAxisScale.result.slice())}return t.isBarHorizontal&&t.labels.length&&(t.xTickAmount=t.labels.length),this._handleSingleDataPoint(),this._getMinXDiff(),{minX:t.minX,maxX:t.maxX}}},{key:"setZRange",value:function(){var t=this.w.globals;if(t.isDataXYZ)for(var e=0;e0){var i=e-r[n-1];i>0&&(t.minXDiff=Math.min(i,t.minXDiff))}})),1!==t.dataPoints&&t.minXDiff!==Number.MAX_VALUE||(t.minXDiff=.5)}))}},{key:"_setStackedMinMax",value:function(){var t=this,e=this.w.globals;if(e.series.length){var n=e.seriesGroups;n.length||(n=[this.w.globals.seriesNames.map((function(t){return t}))]);var r={},i={};n.forEach((function(n){r[n]=[],i[n]=[],t.w.config.series.map((function(t,r){return n.indexOf(e.seriesNames[r])>-1?r:null})).filter((function(t){return null!==t})).forEach((function(a){for(var o=0;o0?r[n][o]+=parseFloat(e.series[a][o])+1e-4:i[n][o]+=parseFloat(e.series[a][o]))}}))})),Object.entries(r).forEach((function(t){var n=y(t,1)[0];r[n].forEach((function(t,a){e.maxY=Math.max(e.maxY,r[n][a]),e.minY=Math.min(e.minY,i[n][a])}))}))}}}]),t}(),nt=function(){function t(e,n){o(this,t),this.ctx=e,this.elgrid=n,this.w=e.w;var r=this.w;this.xaxisFontSize=r.config.xaxis.labels.style.fontSize,this.axisFontFamily=r.config.xaxis.labels.style.fontFamily,this.xaxisForeColors=r.config.xaxis.labels.style.colors,this.isCategoryBarHorizontal="bar"===r.config.chart.type&&r.config.plotOptions.bar.horizontal,this.xAxisoffX="bottom"===r.config.xaxis.position?r.globals.gridHeight:0,this.drawnLabels=[],this.axesUtils=new I(e)}return l(t,[{key:"drawYaxis",value:function(t){var e=this.w,n=new _(this.ctx),r=e.config.yaxis[t].labels.style,i=r.fontSize,a=r.fontFamily,o=r.fontWeight,s=n.group({class:"apexcharts-yaxis",rel:t,transform:"translate(".concat(e.globals.translateYAxisX[t],", 0)")});if(this.axesUtils.isYAxisHidden(t))return s;var l=n.group({class:"apexcharts-yaxis-texts-g"});s.add(l);var c=e.globals.yAxisScale[t].result.length-1,u=e.globals.gridHeight/c,h=e.globals.yLabelFormatters[t],d=this.axesUtils.checkForReversedLabels(t,e.globals.yAxisScale[t].result.slice());if(e.config.yaxis[t].labels.show){var f=e.globals.translateY+e.config.yaxis[t].labels.offsetY;e.globals.isBarHorizontal?f=0:"heatmap"===e.config.chart.type&&(f-=u/2),f+=parseInt(i,10)/3;for(var p=c;p>=0;p--){var v=h(d[p],p,e),g=e.config.yaxis[t].labels.padding;e.config.yaxis[t].opposite&&0!==e.config.yaxis.length&&(g*=-1);var m=this.getTextAnchor(e.config.yaxis[t].labels.align,e.config.yaxis[t].opposite),y=this.axesUtils.getYAxisForeColor(r.colors,t),b=Array.isArray(y)?y[p]:y,x=S.listToArray(e.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis[rel='".concat(t,"'] .apexcharts-yaxis-label tspan"))).map((function(t){return t.textContent})),w=n.drawText({x:g,y:f,text:x.includes(v)&&!e.config.yaxis[t].labels.showDuplicates?"":v,textAnchor:m,fontSize:i,fontFamily:a,fontWeight:o,maxWidth:e.config.yaxis[t].labels.maxWidth,foreColor:b,isPlainText:!1,cssClass:"apexcharts-yaxis-label ".concat(r.cssClass)});l.add(w),this.addTooltip(w,v),0!==e.config.yaxis[t].labels.rotate&&this.rotateLabel(n,w,firstLabel,e.config.yaxis[t].labels.rotate),f+=u}}return this.addYAxisTitle(n,s,t),this.addAxisBorder(n,s,t,c,u),s}},{key:"getTextAnchor",value:function(t,e){return"left"===t?"start":"center"===t?"middle":"right"===t?"end":e?"start":"end"}},{key:"addTooltip",value:function(t,e){var n=document.createElementNS(this.w.globals.SVGNS,"title");n.textContent=Array.isArray(e)?e.join(" "):e,t.node.appendChild(n)}},{key:"rotateLabel",value:function(t,e,n,r){var i=t.rotateAroundCenter(n.node),a=t.rotateAroundCenter(e.node);e.node.setAttribute("transform","rotate(".concat(r," ").concat(i.x," ").concat(a.y,")"))}},{key:"addYAxisTitle",value:function(t,e,n){var r=this.w;if(void 0!==r.config.yaxis[n].title.text){var i=t.group({class:"apexcharts-yaxis-title"}),a=r.config.yaxis[n].opposite?r.globals.translateYAxisX[n]:0,o=t.drawText({x:a,y:r.globals.gridHeight/2+r.globals.translateY+r.config.yaxis[n].title.offsetY,text:r.config.yaxis[n].title.text,textAnchor:"end",foreColor:r.config.yaxis[n].title.style.color,fontSize:r.config.yaxis[n].title.style.fontSize,fontWeight:r.config.yaxis[n].title.style.fontWeight,fontFamily:r.config.yaxis[n].title.style.fontFamily,cssClass:"apexcharts-yaxis-title-text ".concat(r.config.yaxis[n].title.style.cssClass)});i.add(o),e.add(i)}}},{key:"addAxisBorder",value:function(t,e,n,r,i){var a=this.w,o=a.config.yaxis[n].axisBorder,s=31+o.offsetX;if(a.config.yaxis[n].opposite&&(s=-31-o.offsetX),o.show){var l=t.drawLine(s,a.globals.translateY+o.offsetY-2,s,a.globals.gridHeight+a.globals.translateY+o.offsetY+2,o.color,0,o.width);e.add(l)}a.config.yaxis[n].axisTicks.show&&this.axesUtils.drawYAxisTicks(s,r,o,a.config.yaxis[n].axisTicks,n,i,e)}},{key:"drawYaxisInversed",value:function(t){var e=this.w,n=new _(this.ctx),r=n.group({class:"apexcharts-xaxis apexcharts-yaxis-inversed"}),i=n.group({class:"apexcharts-xaxis-texts-g",transform:"translate(".concat(e.globals.translateXAxisX,", ").concat(e.globals.translateXAxisY,")")});r.add(i);var a=e.globals.yAxisScale[t].result.length-1,o=e.globals.gridWidth/a+.1,s=o+e.config.xaxis.labels.offsetX,l=e.globals.xLabelFormatter,c=this.axesUtils.checkForReversedLabels(t,e.globals.yAxisScale[t].result.slice()),u=e.globals.timescaleLabels;if(u.length>0&&(this.xaxisLabels=u.slice(),a=(c=u.slice()).length),e.config.xaxis.labels.show)for(var h=u.length?0:a;u.length?h=0;u.length?h++:h--){var d=l(c[h],h,e),f=e.globals.gridWidth+e.globals.padHorizontal-(s-o+e.config.xaxis.labels.offsetX);if(u.length){var p=this.axesUtils.getLabel(c,u,f,h,this.drawnLabels,this.xaxisFontSize);f=p.x,d=p.text,this.drawnLabels.push(p.text),0===h&&e.globals.skipFirstTimelinelabel&&(d=""),h===c.length-1&&e.globals.skipLastTimelinelabel&&(d="")}var v=n.drawText({x:f,y:this.xAxisoffX+e.config.xaxis.labels.offsetY+30-("top"===e.config.xaxis.position?e.globals.xAxisHeight+e.config.xaxis.axisTicks.height-2:0),text:d,textAnchor:"middle",foreColor:Array.isArray(this.xaxisForeColors)?this.xaxisForeColors[t]:this.xaxisForeColors,fontSize:this.xaxisFontSize,fontFamily:this.xaxisFontFamily,fontWeight:e.config.xaxis.labels.style.fontWeight,isPlainText:!1,cssClass:"apexcharts-xaxis-label ".concat(e.config.xaxis.labels.style.cssClass)});i.add(v),v.tspan(d),this.addTooltip(v,d),s+=o}return this.inversedYAxisTitleText(r),this.inversedYAxisBorder(r),r}},{key:"inversedYAxisBorder",value:function(t){var e=this.w,n=new _(this.ctx),r=e.config.xaxis.axisBorder;if(r.show){var i=0;"bar"===e.config.chart.type&&e.globals.isXNumeric&&(i-=15);var a=n.drawLine(e.globals.padHorizontal+i+r.offsetX,this.xAxisoffX,e.globals.gridWidth,this.xAxisoffX,r.color,0,r.height);this.elgrid&&this.elgrid.elGridBorders&&e.config.grid.show?this.elgrid.elGridBorders.add(a):t.add(a)}}},{key:"inversedYAxisTitleText",value:function(t){var e=this.w,n=new _(this.ctx);if(void 0!==e.config.xaxis.title.text){var r=n.group({class:"apexcharts-xaxis-title apexcharts-yaxis-title-inversed"}),i=n.drawText({x:e.globals.gridWidth/2+e.config.xaxis.title.offsetX,y:this.xAxisoffX+parseFloat(this.xaxisFontSize)+parseFloat(e.config.xaxis.title.style.fontSize)+e.config.xaxis.title.offsetY+20,text:e.config.xaxis.title.text,textAnchor:"middle",fontSize:e.config.xaxis.title.style.fontSize,fontFamily:e.config.xaxis.title.style.fontFamily,fontWeight:e.config.xaxis.title.style.fontWeight,foreColor:e.config.xaxis.title.style.color,cssClass:"apexcharts-xaxis-title-text ".concat(e.config.xaxis.title.style.cssClass)});r.add(i),t.add(r)}}},{key:"yAxisTitleRotate",value:function(t,e){var n=this.w,r=new _(this.ctx),i=n.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(t,"'] .apexcharts-yaxis-texts-g")),a=i?i.getBoundingClientRect():{width:0,height:0},o=n.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(t,"'] .apexcharts-yaxis-title text")),s=o?o.getBoundingClientRect():{width:0,height:0};if(o){var l=this.xPaddingForYAxisTitle(t,a,s,e);o.setAttribute("x",l.xPos-(e?10:0));var c=r.rotateAroundCenter(o);o.setAttribute("transform","rotate(".concat(e?-1*n.config.yaxis[t].title.rotate:n.config.yaxis[t].title.rotate," ").concat(c.x," ").concat(c.y,")"))}}},{key:"xPaddingForYAxisTitle",value:function(t,e,n,r){var i=this.w,a=0,o=10;return void 0===i.config.yaxis[t].title.text||t<0?{xPos:a,padd:0}:(r?a=e.width+i.config.yaxis[t].title.offsetX+n.width/2+o/2:(a=-1*e.width+i.config.yaxis[t].title.offsetX+o/2+n.width/2,i.globals.isBarHorizontal&&(o=25,a=-1*e.width-i.config.yaxis[t].title.offsetX-o)),{xPos:a,padd:o})}},{key:"setYAxisXPosition",value:function(t,e){var n=this.w,r=0,i=0,a=18,o=1;n.config.yaxis.length>1&&(this.multipleYs=!0),n.config.yaxis.forEach((function(s,l){var c=n.globals.ignoreYAxisIndexes.includes(l)||!s.show||s.floating||0===t[l].width,u=t[l].width+e[l].width;s.opposite?n.globals.isBarHorizontal?(i=n.globals.gridWidth+n.globals.translateX-1,n.globals.translateYAxisX[l]=i-s.labels.offsetX):(i=n.globals.gridWidth+n.globals.translateX+o,c||(o+=u+20),n.globals.translateYAxisX[l]=i-s.labels.offsetX+20):(r=n.globals.translateX-a,c||(a+=u+20),n.globals.translateYAxisX[l]=r+s.labels.offsetX)}))}},{key:"setYAxisTextAlignments",value:function(){var t=this.w;S.listToArray(t.globals.dom.baseEl.getElementsByClassName("apexcharts-yaxis")).forEach((function(e,n){var r=t.config.yaxis[n];if(r&&!r.floating&&void 0!==r.labels.align){var i=t.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(n,"'] .apexcharts-yaxis-texts-g")),a=S.listToArray(t.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis[rel='".concat(n,"'] .apexcharts-yaxis-label"))),o=i.getBoundingClientRect();a.forEach((function(t){t.setAttribute("text-anchor",r.labels.align)})),"left"!==r.labels.align||r.opposite?"center"===r.labels.align?i.setAttribute("transform","translate(".concat(o.width/2*(r.opposite?1:-1),", 0)")):"right"===r.labels.align&&r.opposite&&i.setAttribute("transform","translate(".concat(o.width,", 0)")):i.setAttribute("transform","translate(-".concat(o.width,", 0)"))}}))}}]),t}(),rt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.documentEvent=S.bind(this.documentEvent,this)}return l(t,[{key:"addEventListener",value:function(t,e){var n=this.w;n.globals.events.hasOwnProperty(t)?n.globals.events[t].push(e):n.globals.events[t]=[e]}},{key:"removeEventListener",value:function(t,e){var n=this.w;if(n.globals.events.hasOwnProperty(t)){var r=n.globals.events[t].indexOf(e);-1!==r&&n.globals.events[t].splice(r,1)}}},{key:"fireEvent",value:function(t,e){var n=this.w;if(n.globals.events.hasOwnProperty(t)){e&&e.length||(e=[]);for(var r=n.globals.events[t],i=r.length,a=0;a0&&(e=this.w.config.chart.locales.concat(window.Apex.chart.locales));var n=e.filter((function(e){return e.name===t}))[0];if(!n)throw new Error("Wrong locale name provided. Please make sure you set the correct locale name in options");var r=S.extend(L,n);this.w.globals.locale=r.options}}]),t}(),at=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"drawAxis",value:function(t,e){var n,r,i=this,a=this.w.globals,o=this.w.config,s=new J(this.ctx,e),l=new nt(this.ctx,e);a.axisCharts&&"radar"!==t&&(a.isBarHorizontal?(r=l.drawYaxisInversed(0),n=s.drawXaxisInversed(0),a.dom.elGraphical.add(n),a.dom.elGraphical.add(r)):(n=s.drawXaxis(),a.dom.elGraphical.add(n),o.yaxis.map((function(t,e){if(-1===a.ignoreYAxisIndexes.indexOf(e)&&(r=l.drawYaxis(e),a.dom.Paper.add(r),"back"===i.w.config.grid.position)){var n=a.dom.Paper.children()[1];n.remove(),a.dom.Paper.add(n)}}))))}}]),t}(),ot=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"drawXCrosshairs",value:function(){var t=this.w,e=new _(this.ctx),n=new A(this.ctx),r=t.config.xaxis.crosshairs.fill.gradient,i=t.config.xaxis.crosshairs.dropShadow,a=t.config.xaxis.crosshairs.fill.type,o=r.colorFrom,s=r.colorTo,l=r.opacityFrom,c=r.opacityTo,u=r.stops,h=i.enabled,d=i.left,f=i.top,p=i.blur,v=i.color,g=i.opacity,m=t.config.xaxis.crosshairs.fill.color;if(t.config.xaxis.crosshairs.show){"gradient"===a&&(m=e.drawGradient("vertical",o,s,l,c,null,u,null));var y=e.drawRect();1===t.config.xaxis.crosshairs.width&&(y=e.drawLine());var b=t.globals.gridHeight;(!S.isNumber(b)||b<0)&&(b=0);var x=t.config.xaxis.crosshairs.width;(!S.isNumber(x)||x<0)&&(x=0),y.attr({class:"apexcharts-xcrosshairs",x:0,y:0,y2:b,width:x,height:b,fill:m,filter:"none","fill-opacity":t.config.xaxis.crosshairs.opacity,stroke:t.config.xaxis.crosshairs.stroke.color,"stroke-width":t.config.xaxis.crosshairs.stroke.width,"stroke-dasharray":t.config.xaxis.crosshairs.stroke.dashArray}),h&&(y=n.dropShadow(y,{left:d,top:f,blur:p,color:v,opacity:g})),t.globals.dom.elGraphical.add(y)}}},{key:"drawYCrosshairs",value:function(){var t=this.w,e=new _(this.ctx),n=t.config.yaxis[0].crosshairs,r=t.globals.barPadForNumericAxis;if(t.config.yaxis[0].crosshairs.show){var i=e.drawLine(-r,0,t.globals.gridWidth+r,0,n.stroke.color,n.stroke.dashArray,n.stroke.width);i.attr({class:"apexcharts-ycrosshairs"}),t.globals.dom.elGraphical.add(i)}var a=e.drawLine(-r,0,t.globals.gridWidth+r,0,n.stroke.color,0,0);a.attr({class:"apexcharts-ycrosshairs-hidden"}),t.globals.dom.elGraphical.add(a)}}]),t}(),st=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"checkResponsiveConfig",value:function(t){var e=this,n=this.w,r=n.config;if(0!==r.responsive.length){var i=r.responsive.slice();i.sort((function(t,e){return t.breakpoint>e.breakpoint?1:e.breakpoint>t.breakpoint?-1:0})).reverse();var a=new $({}),o=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=i[0].breakpoint,o=window.innerWidth>0?window.innerWidth:screen.width;if(o>r){var s=S.clone(n.globals.initialConfig);s.series=S.clone(n.config.series);var l=D.extendArrayProps(a,s,n);t=S.extend(l,t),t=S.extend(n.config,t),e.overrideResponsiveOptions(t)}else for(var c=0;c0&&"function"==typeof t[0]?(this.isColorFn=!0,n.config.series.map((function(r,i){var a=t[i]||t[0];return"function"==typeof a?a({value:n.globals.axisCharts?n.globals.series[i][0]||0:n.globals.series[i],seriesIndex:i,dataPointIndex:i,w:e.w}):a}))):t:this.predefined()}},{key:"applySeriesColors",value:function(t,e){t.forEach((function(t,n){t&&(e[n]=t)}))}},{key:"getMonochromeColors",value:function(t,e,n){var r=t.color,i=t.shadeIntensity,a=t.shadeTo,o=this.isBarDistributed||this.isHeatmapDistributed?e[0].length*e.length:e.length,s=1/(o/i),l=0;return Array.from({length:o},(function(){var t="dark"===a?n.shadeColor(-1*l,r):n.shadeColor(l,r);return l+=s,t}))}},{key:"applyColorTypes",value:function(t,e){var n=this,r=this.w;t.forEach((function(t){r.globals[t].colors=void 0===r.config[t].colors?n.isColorFn?r.config.colors:e:r.config[t].colors.slice(),n.pushExtraColors(r.globals[t].colors)}))}},{key:"applyDataLabelsColors",value:function(t){var e=this.w;e.globals.dataLabels.style.colors=void 0===e.config.dataLabels.style.colors?t:e.config.dataLabels.style.colors.slice(),this.pushExtraColors(e.globals.dataLabels.style.colors,50)}},{key:"applyRadarPolygonsColors",value:function(){var t=this.w;t.globals.radarPolygons.fill.colors=void 0===t.config.plotOptions.radar.polygons.fill.colors?["dark"===t.config.theme.mode?"#424242":"none"]:t.config.plotOptions.radar.polygons.fill.colors.slice(),this.pushExtraColors(t.globals.radarPolygons.fill.colors,20)}},{key:"applyMarkersColors",value:function(t){var e=this.w;e.globals.markers.colors=void 0===e.config.markers.colors?t:e.config.markers.colors.slice(),this.pushExtraColors(e.globals.markers.colors)}},{key:"pushExtraColors",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=this.w,i=e||r.globals.series.length;if(null===n&&(n=this.isBarDistributed||this.isHeatmapDistributed||"heatmap"===r.config.chart.type&&r.config.plotOptions.heatmap&&r.config.plotOptions.heatmap.colorScale.inverse),n&&r.globals.series.length&&(i=r.globals.series[r.globals.maxValsInArrayIndex].length*r.globals.series.length),t.lengtht.globals.svgWidth&&(this.dCtx.lgRect.width=t.globals.svgWidth/1.5),this.dCtx.lgRect}},{key:"getDatalabelsRect",value:function(){var t=this,e=this.w,n=[];e.config.series.forEach((function(i,a){i.data.forEach((function(i,o){var s;s=e.globals.series[a][o],r=e.config.dataLabels.formatter(s,{ctx:t.dCtx.ctx,seriesIndex:a,dataPointIndex:o,w:e}),n.push(r)}))}));var r=S.getLargestStringFromArr(n),i=new _(this.dCtx.ctx),a=e.config.dataLabels.style,o=i.getTextRects(r,parseInt(a.fontSize),a.fontFamily);return{width:1.05*o.width,height:o.height}}},{key:"getLargestStringFromMultiArr",value:function(t,e){var n=t;if(this.w.globals.isMultiLineX){var r=e.map((function(t,e){return Array.isArray(t)?t.length:1})),i=Math.max.apply(Math,b(r));n=e[r.indexOf(i)]}return n}}]),t}(),ht=function(){function t(e){o(this,t),this.w=e.w,this.dCtx=e}return l(t,[{key:"getxAxisLabelsCoords",value:function(){var t,e=this.w,n=e.globals.labels.slice();if(e.config.xaxis.convertedCatToNumeric&&0===n.length&&(n=e.globals.categoryLabels),e.globals.timescaleLabels.length>0){var r=this.getxAxisTimeScaleLabelsCoords();t={width:r.width,height:r.height},e.globals.rotateXLabels=!1}else{this.dCtx.lgWidthForSideLegends="left"!==e.config.legend.position&&"right"!==e.config.legend.position||e.config.legend.floating?0:this.dCtx.lgRect.width;var i=e.globals.xLabelFormatter,a=S.getLargestStringFromArr(n),o=this.dCtx.dimHelpers.getLargestStringFromMultiArr(a,n);e.globals.isBarHorizontal&&(o=a=e.globals.yAxisScale[0].result.reduce((function(t,e){return t.length>e.length?t:e}),0));var s=new P(this.dCtx.ctx),l=a;a=s.xLabelFormat(i,a,l,{i:void 0,dateFormatter:new O(this.dCtx.ctx).formatDate,w:e}),o=s.xLabelFormat(i,o,l,{i:void 0,dateFormatter:new O(this.dCtx.ctx).formatDate,w:e}),(e.config.xaxis.convertedCatToNumeric&&void 0===a||""===String(a).trim())&&(o=a="1");var c=new _(this.dCtx.ctx),u=c.getTextRects(a,e.config.xaxis.labels.style.fontSize),h=u;if(a!==o&&(h=c.getTextRects(o,e.config.xaxis.labels.style.fontSize)),(t={width:u.width>=h.width?u.width:h.width,height:u.height>=h.height?u.height:h.height}).width*n.length>e.globals.svgWidth-this.dCtx.lgWidthForSideLegends-this.dCtx.yAxisWidth-this.dCtx.gridPad.left-this.dCtx.gridPad.right&&0!==e.config.xaxis.labels.rotate||e.config.xaxis.labels.rotateAlways){if(!e.globals.isBarHorizontal){e.globals.rotateXLabels=!0;var d=function(t){return c.getTextRects(t,e.config.xaxis.labels.style.fontSize,e.config.xaxis.labels.style.fontFamily,"rotate(".concat(e.config.xaxis.labels.rotate," 0 0)"),!1)};u=d(a),a!==o&&(h=d(o)),t.height=(u.height>h.height?u.height:h.height)/1.5,t.width=u.width>h.width?u.width:h.width}}else e.globals.rotateXLabels=!1}return e.config.xaxis.labels.show||(t={width:0,height:0}),{width:t.width,height:t.height}}},{key:"getxAxisGroupLabelsCoords",value:function(){var t,e=this.w;if(!e.globals.hasXaxisGroups)return{width:0,height:0};var n,r=(null===(t=e.config.xaxis.group.style)||void 0===t?void 0:t.fontSize)||e.config.xaxis.labels.style.fontSize,i=e.globals.groups.map((function(t){return t.title})),a=S.getLargestStringFromArr(i),o=this.dCtx.dimHelpers.getLargestStringFromMultiArr(a,i),s=new _(this.dCtx.ctx),l=s.getTextRects(a,r),c=l;return a!==o&&(c=s.getTextRects(o,r)),n={width:l.width>=c.width?l.width:c.width,height:l.height>=c.height?l.height:c.height},e.config.xaxis.labels.show||(n={width:0,height:0}),{width:n.width,height:n.height}}},{key:"getxAxisTitleCoords",value:function(){var t=this.w,e=0,n=0;if(void 0!==t.config.xaxis.title.text){var r=new _(this.dCtx.ctx).getTextRects(t.config.xaxis.title.text,t.config.xaxis.title.style.fontSize);e=r.width,n=r.height}return{width:e,height:n}}},{key:"getxAxisTimeScaleLabelsCoords",value:function(){var t,e=this.w;this.dCtx.timescaleLabels=e.globals.timescaleLabels.slice();var n=this.dCtx.timescaleLabels.map((function(t){return t.value})),r=n.reduce((function(t,e){return void 0===t?(console.error("You have possibly supplied invalid Date format. Please supply a valid JavaScript Date"),0):t.length>e.length?t:e}),0);return 1.05*(t=new _(this.dCtx.ctx).getTextRects(r,e.config.xaxis.labels.style.fontSize)).width*n.length>e.globals.gridWidth&&0!==e.config.xaxis.labels.rotate&&(e.globals.overlappingXLabels=!0),t}},{key:"additionalPaddingXLabels",value:function(t){var e=this,n=this.w,r=n.globals,i=n.config,a=i.xaxis.type,o=t.width;r.skipLastTimelinelabel=!1,r.skipFirstTimelinelabel=!1;var s=n.config.yaxis[0].opposite&&n.globals.isBarHorizontal,l=function(t,s){i.yaxis.length>1&&function(t){return-1!==r.collapsedSeriesIndices.indexOf(t)}(s)||function(t){if(e.dCtx.timescaleLabels&&e.dCtx.timescaleLabels.length){var s=e.dCtx.timescaleLabels[0],l=e.dCtx.timescaleLabels[e.dCtx.timescaleLabels.length-1].position+o/1.75-e.dCtx.yAxisWidthRight,c=s.position-o/1.75+e.dCtx.yAxisWidthLeft,u="right"===n.config.legend.position&&e.dCtx.lgRect.width>0?e.dCtx.lgRect.width:0;l>r.svgWidth-r.translateX-u&&(r.skipLastTimelinelabel=!0),c<-(t.show&&!t.floating||"bar"!==i.chart.type&&"candlestick"!==i.chart.type&&"rangeBar"!==i.chart.type&&"boxPlot"!==i.chart.type?10:o/1.75)&&(r.skipFirstTimelinelabel=!0)}else"datetime"===a?e.dCtx.gridPad.right(null===(r=String(u(e,s)))||void 0===r?void 0:r.length)?t:e}),h),f=d=u(d,s);if(void 0!==d&&0!==d.length||(d=l.niceMax),e.globals.isBarHorizontal){r=0;var p=e.globals.labels.slice();d=S.getLargestStringFromArr(p),d=u(d,{seriesIndex:o,dataPointIndex:-1,w:e}),f=t.dCtx.dimHelpers.getLargestStringFromMultiArr(d,p)}var v=new _(t.dCtx.ctx),g="rotate(".concat(a.labels.rotate," 0 0)"),m=v.getTextRects(d,a.labels.style.fontSize,a.labels.style.fontFamily,g,!1),y=m;d!==f&&(y=v.getTextRects(f,a.labels.style.fontSize,a.labels.style.fontFamily,g,!1)),n.push({width:(c>y.width||c>m.width?c:y.width>m.width?y.width:m.width)+r,height:y.height>m.height?y.height:m.height})}else n.push({width:0,height:0})})),n}},{key:"getyAxisTitleCoords",value:function(){var t=this,e=this.w,n=[];return e.config.yaxis.map((function(e,r){if(e.show&&void 0!==e.title.text){var i=new _(t.dCtx.ctx),a="rotate(".concat(e.title.rotate," 0 0)"),o=i.getTextRects(e.title.text,e.title.style.fontSize,e.title.style.fontFamily,a,!1);n.push({width:o.width,height:o.height})}else n.push({width:0,height:0})})),n}},{key:"getTotalYAxisWidth",value:function(){var t=this.w,e=0,n=0,r=0,i=t.globals.yAxisScale.length>1?10:0,a=new I(this.dCtx.ctx),o=function(o,s){var l=t.config.yaxis[s].floating,c=0;o.width>0&&!l?(c=o.width+i,function(e){return t.globals.ignoreYAxisIndexes.indexOf(e)>-1}(s)&&(c=c-o.width-i)):c=l||a.isYAxisHidden(s)?0:5,t.config.yaxis[s].opposite?r+=c:n+=c,e+=c};return t.globals.yLabelsCoords.map((function(t,e){o(t,e)})),t.globals.yTitleCoords.map((function(t,e){o(t,e)})),t.globals.isBarHorizontal&&!t.config.yaxis[0].floating&&(e=t.globals.yLabelsCoords[0].width+t.globals.yTitleCoords[0].width+15),this.dCtx.yAxisWidthLeft=n,this.dCtx.yAxisWidthRight=r,e}}]),t}(),ft=function(){function t(e){o(this,t),this.w=e.w,this.dCtx=e}return l(t,[{key:"gridPadForColumnsInNumericAxis",value:function(t){var e=this.w,n=e.config,r=e.globals;if(r.noData||r.collapsedSeries.length+r.ancillaryCollapsedSeries.length===n.series.length)return 0;var i=function(t){return["bar","rangeBar","candlestick","boxPlot"].includes(t)},a=n.chart.type,o=0,s=i(a)?n.series.length:1;r.comboBarCount>0&&(s=r.comboBarCount),r.collapsedSeries.forEach((function(t){i(t.type)&&(s-=1)})),n.chart.stacked&&(s=1);var l=i(a)||r.comboBarCount>0,c=Math.abs(r.initialMaxX-r.initialMinX);if(l&&r.isXNumeric&&!r.isBarHorizontal&&s>0&&0!==c){c<=3&&(c=r.dataPoints);var u=c/t,h=r.minXDiff&&r.minXDiff/u>0?r.minXDiff/u:0;h>t/2&&(h/=2),(o=h*parseInt(n.plotOptions.bar.columnWidth,10)/100)<1&&(o=1),r.barPadForNumericAxis=o}return o}},{key:"gridPadFortitleSubtitle",value:function(){var t=this,e=this.w,n=e.globals,r=this.dCtx.isSparkline||!n.axisCharts?0:10;["title","subtitle"].forEach((function(i){void 0!==e.config[i].text?r+=e.config[i].margin:r+=t.dCtx.isSparkline||!n.axisCharts?0:5})),!e.config.legend.show||"bottom"!==e.config.legend.position||e.config.legend.floating||n.axisCharts||(r+=10);var i=this.dCtx.dimHelpers.getTitleSubtitleCoords("title"),a=this.dCtx.dimHelpers.getTitleSubtitleCoords("subtitle");n.gridHeight-=i.height+a.height+r,n.translateY+=i.height+a.height+r}},{key:"setGridXPosForDualYAxis",value:function(t,e){var n=this.w,r=new I(this.dCtx.ctx);n.config.yaxis.forEach((function(i,a){-1!==n.globals.ignoreYAxisIndexes.indexOf(a)||i.floating||r.isYAxisHidden(a)||(i.opposite&&(n.globals.translateX-=e[a].width+t[a].width+parseInt(i.labels.style.fontSize,10)/1.2+12),n.globals.translateX<2&&(n.globals.translateX=2))}))}}]),t}(),pt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.lgRect={},this.yAxisWidth=0,this.yAxisWidthLeft=0,this.yAxisWidthRight=0,this.xAxisHeight=0,this.isSparkline=this.w.config.chart.sparkline.enabled,this.dimHelpers=new ut(this),this.dimYAxis=new dt(this),this.dimXAxis=new ht(this),this.dimGrid=new ft(this),this.lgWidthForSideLegends=0,this.gridPad=this.w.config.grid.padding,this.xPadRight=0,this.xPadLeft=0}return l(t,[{key:"plotCoords",value:function(){var t=this,e=this.w,n=e.globals;this.lgRect=this.dimHelpers.getLegendsRect(),this.datalabelsCoords={width:0,height:0};var r=Array.isArray(e.config.stroke.width)?Math.max.apply(Math,b(e.config.stroke.width)):e.config.stroke.width;this.isSparkline&&((e.config.markers.discrete.length>0||e.config.markers.size>0)&&Object.entries(this.gridPad).forEach((function(e){var n=y(e,2),r=n[0],i=n[1];t.gridPad[r]=Math.max(i,t.w.globals.markers.largestSize/1.5)})),this.gridPad.top=Math.max(r/2,this.gridPad.top),this.gridPad.bottom=Math.max(r/2,this.gridPad.bottom)),n.axisCharts?this.setDimensionsForAxisCharts():this.setDimensionsForNonAxisCharts(),this.dimGrid.gridPadFortitleSubtitle(),n.gridHeight=n.gridHeight-this.gridPad.top-this.gridPad.bottom,n.gridWidth=n.gridWidth-this.gridPad.left-this.gridPad.right-this.xPadRight-this.xPadLeft;var i=this.dimGrid.gridPadForColumnsInNumericAxis(n.gridWidth);n.gridWidth=n.gridWidth-2*i,n.translateX=n.translateX+this.gridPad.left+this.xPadLeft+(i>0?i:0),n.translateY=n.translateY+this.gridPad.top}},{key:"setDimensionsForAxisCharts",value:function(){var t=this,e=this.w,n=e.globals,r=this.dimYAxis.getyAxisLabelsCoords(),i=this.dimYAxis.getyAxisTitleCoords();n.isSlopeChart&&(this.datalabelsCoords=this.dimHelpers.getDatalabelsRect()),e.globals.yLabelsCoords=[],e.globals.yTitleCoords=[],e.config.yaxis.map((function(t,n){e.globals.yLabelsCoords.push({width:r[n].width,index:n}),e.globals.yTitleCoords.push({width:i[n].width,index:n})})),this.yAxisWidth=this.dimYAxis.getTotalYAxisWidth();var a=this.dimXAxis.getxAxisLabelsCoords(),o=this.dimXAxis.getxAxisGroupLabelsCoords(),s=this.dimXAxis.getxAxisTitleCoords();this.conditionalChecksForAxisCoords(a,s,o),n.translateXAxisY=e.globals.rotateXLabels?this.xAxisHeight/8:-4,n.translateXAxisX=e.globals.rotateXLabels&&e.globals.isXNumeric&&e.config.xaxis.labels.rotate<=-45?-this.xAxisWidth/4:0,e.globals.isBarHorizontal&&(n.rotateXLabels=!1,n.translateXAxisY=parseInt(e.config.xaxis.labels.style.fontSize,10)/1.5*-1),n.translateXAxisY=n.translateXAxisY+e.config.xaxis.labels.offsetY,n.translateXAxisX=n.translateXAxisX+e.config.xaxis.labels.offsetX;var l=this.yAxisWidth,c=this.xAxisHeight;n.xAxisLabelsHeight=this.xAxisHeight-s.height,n.xAxisGroupLabelsHeight=n.xAxisLabelsHeight-a.height,n.xAxisLabelsWidth=this.xAxisWidth,n.xAxisHeight=this.xAxisHeight;var u=10;("radar"===e.config.chart.type||this.isSparkline)&&(l=0,c=0),this.isSparkline&&(this.lgRect={height:0,width:0}),(this.isSparkline||"treemap"===e.config.chart.type)&&(l=0,c=0,u=0),this.isSparkline||"treemap"===e.config.chart.type||this.dimXAxis.additionalPaddingXLabels(a);var h=function(){n.translateX=l+t.datalabelsCoords.width,n.gridHeight=n.svgHeight-t.lgRect.height-c-(t.isSparkline||"treemap"===e.config.chart.type?0:e.globals.rotateXLabels?10:15),n.gridWidth=n.svgWidth-l-2*t.datalabelsCoords.width};switch("top"===e.config.xaxis.position&&(u=n.xAxisHeight-e.config.xaxis.axisTicks.height-5),e.config.legend.position){case"bottom":n.translateY=u,h();break;case"top":n.translateY=this.lgRect.height+u,h();break;case"left":n.translateY=u,n.translateX=this.lgRect.width+l+this.datalabelsCoords.width,n.gridHeight=n.svgHeight-c-12,n.gridWidth=n.svgWidth-this.lgRect.width-l-2*this.datalabelsCoords.width;break;case"right":n.translateY=u,n.translateX=l+this.datalabelsCoords.width,n.gridHeight=n.svgHeight-c-12,n.gridWidth=n.svgWidth-this.lgRect.width-l-2*this.datalabelsCoords.width-5;break;default:throw new Error("Legend position not supported")}this.dimGrid.setGridXPosForDualYAxis(i,r),new nt(this.ctx).setYAxisXPosition(r,i)}},{key:"setDimensionsForNonAxisCharts",value:function(){var t=this.w,e=t.globals,n=t.config,r=0;t.config.legend.show&&!t.config.legend.floating&&(r=20);var i="pie"===n.chart.type||"polarArea"===n.chart.type||"donut"===n.chart.type?"pie":"radialBar",a=n.plotOptions[i].offsetY,o=n.plotOptions[i].offsetX;if(!n.legend.show||n.legend.floating){e.gridHeight=e.svgHeight;var s=e.dom.elWrap.getBoundingClientRect().width;return e.gridWidth=Math.min(s,e.gridHeight),e.translateY=a,void(e.translateX=o+(e.svgWidth-e.gridWidth)/2)}switch(n.legend.position){case"bottom":e.gridHeight=e.svgHeight-this.lgRect.height,e.gridWidth=e.svgWidth,e.translateY=a-10,e.translateX=o+(e.svgWidth-e.gridWidth)/2;break;case"top":e.gridHeight=e.svgHeight-this.lgRect.height,e.gridWidth=e.svgWidth,e.translateY=this.lgRect.height+a+10,e.translateX=o+(e.svgWidth-e.gridWidth)/2;break;case"left":e.gridWidth=e.svgWidth-this.lgRect.width-r,e.gridHeight="auto"!==n.chart.height?e.svgHeight:e.gridWidth,e.translateY=a,e.translateX=o+this.lgRect.width+r;break;case"right":e.gridWidth=e.svgWidth-this.lgRect.width-r-5,e.gridHeight="auto"!==n.chart.height?e.svgHeight:e.gridWidth,e.translateY=a,e.translateX=o+10;break;default:throw new Error("Legend position not supported")}}},{key:"conditionalChecksForAxisCoords",value:function(t,e,n){var r=this.w,i=r.globals.hasXaxisGroups?2:1,a=n.height+t.height+e.height,o=r.globals.isMultiLineX?1.2:r.globals.LINE_HEIGHT_RATIO,s=r.globals.rotateXLabels?22:10,l=r.globals.rotateXLabels&&"bottom"===r.config.legend.position?10:0;this.xAxisHeight=a*o+i*s+l,this.xAxisWidth=t.width,this.xAxisHeight-e.height>r.config.xaxis.labels.maxHeight&&(this.xAxisHeight=r.config.xaxis.labels.maxHeight),r.config.xaxis.labels.minHeight&&this.xAxisHeightu&&(this.yAxisWidth=u)}}]),t}(),vt=function(){function t(e){o(this,t),this.w=e.w,this.lgCtx=e}return l(t,[{key:"getLegendStyles",value:function(){var t,e,n,r=document.createElement("style");r.setAttribute("type","text/css");var i=(null===(t=this.lgCtx.ctx)||void 0===t||null===(e=t.opts)||void 0===e||null===(n=e.chart)||void 0===n?void 0:n.nonce)||this.w.config.chart.nonce;i&&r.setAttribute("nonce",i);var a=document.createTextNode("\n .apexcharts-flip-y {\n transform: scaleY(-1) translateY(-100%);\n transform-origin: top;\n transform-box: fill-box;\n }\n .apexcharts-flip-x {\n transform: scaleX(-1);\n transform-origin: center;\n transform-box: fill-box;\n }\n .apexcharts-legend {\n display: flex;\n overflow: auto;\n padding: 0 10px;\n }\n .apexcharts-legend.apx-legend-position-bottom, .apexcharts-legend.apx-legend-position-top {\n flex-wrap: wrap\n }\n .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n flex-direction: column;\n bottom: 0;\n }\n .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-left, .apexcharts-legend.apx-legend-position-top.apexcharts-align-left, .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n justify-content: flex-start;\n }\n .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-center, .apexcharts-legend.apx-legend-position-top.apexcharts-align-center {\n justify-content: center;\n }\n .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-right, .apexcharts-legend.apx-legend-position-top.apexcharts-align-right {\n justify-content: flex-end;\n }\n .apexcharts-legend-series {\n cursor: pointer;\n line-height: normal;\n display: flex;\n align-items: center;\n }\n .apexcharts-legend-text {\n position: relative;\n font-size: 14px;\n }\n .apexcharts-legend-text *, .apexcharts-legend-marker * {\n pointer-events: none;\n }\n .apexcharts-legend-marker {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n margin-right: 1px;\n }\n\n .apexcharts-legend-series.apexcharts-no-click {\n cursor: auto;\n }\n .apexcharts-legend .apexcharts-hidden-zero-series, .apexcharts-legend .apexcharts-hidden-null-series {\n display: none !important;\n }\n .apexcharts-inactive-legend {\n opacity: 0.45;\n }");return r.appendChild(a),r}},{key:"getLegendDimensions",value:function(){var t=this.w.globals.dom.baseEl.querySelector(".apexcharts-legend").getBoundingClientRect(),e=t.width;return{clwh:t.height,clww:e}}},{key:"appendToForeignObject",value:function(){this.w.globals.dom.elLegendForeign.appendChild(this.getLegendStyles())}},{key:"toggleDataSeries",value:function(t,e){var n=this,r=this.w;if(r.globals.axisCharts||"radialBar"===r.config.chart.type){r.globals.resized=!0;var i=null,a=null;r.globals.risingSeries=[],r.globals.axisCharts?(i=r.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(t,"']")),a=parseInt(i.getAttribute("data:realIndex"),10)):(i=r.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(t+1,"']")),a=parseInt(i.getAttribute("rel"),10)-1),e?[{cs:r.globals.collapsedSeries,csi:r.globals.collapsedSeriesIndices},{cs:r.globals.ancillaryCollapsedSeries,csi:r.globals.ancillaryCollapsedSeriesIndices}].forEach((function(t){n.riseCollapsedSeries(t.cs,t.csi,a)})):this.hideSeries({seriesEl:i,realIndex:a})}else{var o=r.globals.dom.Paper.select(" .apexcharts-series[rel='".concat(t+1,"'] path")),s=r.config.chart.type;if("pie"===s||"polarArea"===s||"donut"===s){var l=r.config.plotOptions.pie.donut.labels;new _(this.lgCtx.ctx).pathMouseDown(o.members[0],null),this.lgCtx.ctx.pie.printDataLabelsInner(o.members[0].node,l)}o.fire("click")}}},{key:"getSeriesAfterCollapsing",value:function(t){var e=t.realIndex,n=this.w,r=n.globals,i=S.clone(n.config.series);if(r.axisCharts){var a=n.config.yaxis[r.seriesYAxisReverseMap[e]],o={index:e,data:i[e].data.slice(),type:i[e].type||n.config.chart.type};if(a&&a.show&&a.showAlways)r.ancillaryCollapsedSeriesIndices.indexOf(e)<0&&(r.ancillaryCollapsedSeries.push(o),r.ancillaryCollapsedSeriesIndices.push(e));else if(r.collapsedSeriesIndices.indexOf(e)<0){r.collapsedSeries.push(o),r.collapsedSeriesIndices.push(e);var s=r.risingSeries.indexOf(e);r.risingSeries.splice(s,1)}}else r.collapsedSeries.push({index:e,data:i[e]}),r.collapsedSeriesIndices.push(e);return r.allSeriesCollapsed=r.collapsedSeries.length+r.ancillaryCollapsedSeries.length===n.config.series.length,this._getSeriesBasedOnCollapsedState(i)}},{key:"hideSeries",value:function(t){for(var e=t.seriesEl,n=t.realIndex,r=this.w,i=this.getSeriesAfterCollapsing({realIndex:n}),a=e.childNodes,o=0;o0){for(var a=0;a1;if(this.legendHelpers.appendToForeignObject(),(r||!e.axisCharts)&&n.legend.show){for(;e.dom.elLegendWrap.firstChild;)e.dom.elLegendWrap.removeChild(e.dom.elLegendWrap.firstChild);this.drawLegends(),"bottom"===n.legend.position||"top"===n.legend.position?this.legendAlignHorizontal():"right"!==n.legend.position&&"left"!==n.legend.position||this.legendAlignVertical()}}},{key:"createLegendMarker",value:function(t){var e=t.i,n=t.fillcolor,r=this.w,i=document.createElement("span");i.classList.add("apexcharts-legend-marker");var a=r.config.legend.markers.shape||r.config.markers.shape,o=a;Array.isArray(a)&&(o=a[e]);var s=Array.isArray(r.config.legend.markers.size)?parseFloat(r.config.legend.markers.size[e]):parseFloat(r.config.legend.markers.size),l=Array.isArray(r.config.legend.markers.offsetX)?parseFloat(r.config.legend.markers.offsetX[e]):parseFloat(r.config.legend.markers.offsetX),c=Array.isArray(r.config.legend.markers.offsetY)?parseFloat(r.config.legend.markers.offsetY[e]):parseFloat(r.config.legend.markers.offsetY),u=Array.isArray(r.config.legend.markers.strokeWidth)?parseFloat(r.config.legend.markers.strokeWidth[e]):parseFloat(r.config.legend.markers.strokeWidth),h=i.style;if(h.height=2*(s+u)+"px",h.width=2*(s+u)+"px",h.left=l+"px",h.top=c+"px",r.config.legend.markers.customHTML)h.background="transparent",h.color=n[e],Array.isArray(r.config.legend.markers.customHTML)?r.config.legend.markers.customHTML[e]&&(i.innerHTML=r.config.legend.markers.customHTML[e]()):i.innerHTML=r.config.legend.markers.customHTML();else{var d=new X(this.ctx).getMarkerConfig({cssClass:"apexcharts-legend-marker apexcharts-marker apexcharts-marker-".concat(o),seriesIndex:e,strokeWidth:u,size:s}),f=SVG(i).size("100%","100%"),p=new _(this.ctx).drawMarker(0,0,g(g({},d),{},{pointFillColor:Array.isArray(n)?n[e]:d.pointFillColor,shape:o}));SVG.select(".apexcharts-legend-marker.apexcharts-marker").members.forEach((function(t){t.node.classList.contains("apexcharts-marker-triangle")?t.node.style.transform="translate(50%, 45%)":t.node.style.transform="translate(50%, 50%)"})),f.add(p)}return i}},{key:"drawLegends",value:function(){var t=this,e=this.w,n=e.config.legend.fontFamily,r=e.globals.seriesNames,i=e.config.legend.markers.fillColors?e.config.legend.markers.fillColors.slice():e.globals.colors.slice();if("heatmap"===e.config.chart.type){var a=e.config.plotOptions.heatmap.colorScale.ranges;r=a.map((function(t){return t.name?t.name:t.from+" - "+t.to})),i=a.map((function(t){return t.color}))}else this.isBarsDistributed&&(r=e.globals.labels.slice());e.config.legend.customLegendItems.length&&(r=e.config.legend.customLegendItems);for(var o=e.globals.legendFormatter,s=e.config.legend.inverseOrder,l=s?r.length-1:0;s?l>=0:l<=r.length-1;s?l--:l++){var c,u=o(r[l],{seriesIndex:l,w:e}),h=!1,d=!1;if(e.globals.collapsedSeries.length>0)for(var f=0;f0)for(var p=0;p0?l-10:0)+(c>0?c-10:0)}r.style.position="absolute",a=a+t+n.config.legend.offsetX,o=o+e+n.config.legend.offsetY,r.style.left=a+"px",r.style.top=o+"px","right"===n.config.legend.position&&(r.style.left="auto",r.style.right=25+n.config.legend.offsetX+"px"),["width","height"].forEach((function(t){r.style[t]&&(r.style[t]=parseInt(n.config.legend[t],10)+"px")}))}},{key:"legendAlignHorizontal",value:function(){var t=this.w;t.globals.dom.elLegendWrap.style.right=0;var e=new pt(this.ctx),n=e.dimHelpers.getTitleSubtitleCoords("title"),r=e.dimHelpers.getTitleSubtitleCoords("subtitle"),i=0;"top"===t.config.legend.position&&(i=n.height+r.height+t.config.title.margin+t.config.subtitle.margin-10),this.setLegendWrapXY(20,i)}},{key:"legendAlignVertical",value:function(){var t=this.w,e=this.legendHelpers.getLegendDimensions(),n=0;"left"===t.config.legend.position&&(n=20),"right"===t.config.legend.position&&(n=t.globals.svgWidth-e.clww-10),this.setLegendWrapXY(n,20)}},{key:"onLegendHovered",value:function(t){var e=this.w,n=t.target.classList.contains("apexcharts-legend-series")||t.target.classList.contains("apexcharts-legend-text")||t.target.classList.contains("apexcharts-legend-marker");if("heatmap"===e.config.chart.type||this.isBarsDistributed){if(n){var r=parseInt(t.target.getAttribute("rel"),10)-1;this.ctx.events.fireEvent("legendHover",[this.ctx,r,this.w]),new q(this.ctx).highlightRangeInSeries(t,t.target)}}else!t.target.classList.contains("apexcharts-inactive-legend")&&n&&new q(this.ctx).toggleSeriesOnHover(t,t.target)}},{key:"onLegendClick",value:function(t){var e=this.w;if(!e.config.legend.customLegendItems.length&&(t.target.classList.contains("apexcharts-legend-series")||t.target.classList.contains("apexcharts-legend-text")||t.target.classList.contains("apexcharts-legend-marker"))){var n=parseInt(t.target.getAttribute("rel"),10)-1,r="true"===t.target.getAttribute("data:collapsed"),i=this.w.config.chart.events.legendClick;"function"==typeof i&&i(this.ctx,n,this.w),this.ctx.events.fireEvent("legendClick",[this.ctx,n,this.w]);var a=this.w.config.legend.markers.onClick;"function"==typeof a&&t.target.classList.contains("apexcharts-legend-marker")&&(a(this.ctx,n,this.w),this.ctx.events.fireEvent("legendMarkerClick",[this.ctx,n,this.w])),"treemap"!==e.config.chart.type&&"heatmap"!==e.config.chart.type&&!this.isBarsDistributed&&e.config.legend.onItemClick.toggleDataSeries&&this.legendHelpers.toggleDataSeries(n,r)}}}]),t}(),mt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w;var n=this.w;this.ev=this.w.config.chart.events,this.selectedClass="apexcharts-selected",this.localeValues=this.w.globals.locale.toolbar,this.minX=n.globals.minX,this.maxX=n.globals.maxX}return l(t,[{key:"createToolbar",value:function(){var t=this,e=this.w,n=function(){return document.createElement("div")},r=n();if(r.setAttribute("class","apexcharts-toolbar"),r.style.top=e.config.chart.toolbar.offsetY+"px",r.style.right=3-e.config.chart.toolbar.offsetX+"px",e.globals.dom.elWrap.appendChild(r),this.elZoom=n(),this.elZoomIn=n(),this.elZoomOut=n(),this.elPan=n(),this.elSelection=n(),this.elZoomReset=n(),this.elMenuIcon=n(),this.elMenu=n(),this.elCustomIcons=[],this.t=e.config.chart.toolbar.tools,Array.isArray(this.t.customIcons))for(var i=0;i\n \n \n\n'),o("zoomOut",this.elZoomOut,'\n \n \n\n');var s=function(n){t.t[n]&&e.config.chart[n].enabled&&a.push({el:"zoom"===n?t.elZoom:t.elSelection,icon:"string"==typeof t.t[n]?t.t[n]:"zoom"===n?'\n \n \n \n':'\n \n \n',title:t.localeValues["zoom"===n?"selectionZoom":"selection"],class:e.globals.isTouchDevice?"apexcharts-element-hidden":"apexcharts-".concat(n,"-icon")})};s("zoom"),s("selection"),this.t.pan&&e.config.chart.zoom.enabled&&a.push({el:this.elPan,icon:"string"==typeof this.t.pan?this.t.pan:'\n \n \n \n \n \n \n \n',title:this.localeValues.pan,class:e.globals.isTouchDevice?"apexcharts-element-hidden":"apexcharts-pan-icon"}),o("reset",this.elZoomReset,'\n \n \n'),this.t.download&&a.push({el:this.elMenuIcon,icon:"string"==typeof this.t.download?this.t.download:'',title:this.localeValues.menu,class:"apexcharts-menu-icon"});for(var l=0;lthis.wheelDelay&&(this.executeMouseWheelZoom(t),n.globals.lastWheelExecution=r),this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout((function(){r-n.globals.lastWheelExecution>e.wheelDelay&&(e.executeMouseWheelZoom(t),n.globals.lastWheelExecution=r)}),this.debounceDelay)}},{key:"executeMouseWheelZoom",value:function(t){var e,n=this.w;this.minX=n.globals.isRangeBar?n.globals.minY:n.globals.minX,this.maxX=n.globals.isRangeBar?n.globals.maxY:n.globals.maxX;var r=null===(e=this.gridRect)||void 0===e?void 0:e.getBoundingClientRect();if(r){var i,a,o,s=(t.clientX-r.left)/r.width,l=this.minX,c=this.maxX,u=c-l;if(t.deltaY<0){var h=l+s*u;a=h-(i=.5*u)/2,o=h+i/2}else a=l-(i=1.5*u)/2,o=c+i/2;if(!n.globals.isRangeBar){a=Math.max(a,n.globals.initialMinX),o=Math.min(o,n.globals.initialMaxX);var d=.01*(n.globals.initialMaxX-n.globals.initialMinX);if(o-a0&&e.height>0&&this.slDraggableRect.selectize({points:"l, r",pointSize:8,pointType:"rect"}).resize({constraint:{minX:0,minY:0,maxX:t.globals.gridWidth,maxY:t.globals.gridHeight}}).on("resizing",this.selectionDragging.bind(this,"resizing"))}}},{key:"preselectedSelection",value:function(){var t=this.w,e=this.xyRatios;if(!t.globals.zoomEnabled)if(void 0!==t.globals.selection&&null!==t.globals.selection)this.drawSelectionRect(t.globals.selection);else if(void 0!==t.config.chart.selection.xaxis.min&&void 0!==t.config.chart.selection.xaxis.max){var n=(t.config.chart.selection.xaxis.min-t.globals.minX)/e.xRatio,r=t.globals.gridWidth-(t.globals.maxX-t.config.chart.selection.xaxis.max)/e.xRatio-n;t.globals.isRangeBar&&(n=(t.config.chart.selection.xaxis.min-t.globals.yAxisScale[0].niceMin)/e.invertedYRatio,r=(t.config.chart.selection.xaxis.max-t.config.chart.selection.xaxis.min)/e.invertedYRatio);var i={x:n,y:0,width:r,height:t.globals.gridHeight,translateX:0,translateY:0,selectionEnabled:!0};this.drawSelectionRect(i),this.makeSelectionRectDraggable(),"function"==typeof t.config.chart.events.selection&&t.config.chart.events.selection(this.ctx,{xaxis:{min:t.config.chart.selection.xaxis.min,max:t.config.chart.selection.xaxis.max},yaxis:{}})}}},{key:"drawSelectionRect",value:function(t){var e=t.x,n=t.y,r=t.width,i=t.height,a=t.translateX,o=void 0===a?0:a,s=t.translateY,l=void 0===s?0:s,c=this.w,u=this.zoomRect,h=this.selectionRect;if(this.dragged||null!==c.globals.selection){var d={transform:"translate("+o+", "+l+")"};c.globals.zoomEnabled&&this.dragged&&(r<0&&(r=1),u.attr({x:e,y:n,width:r,height:i,fill:c.config.chart.zoom.zoomedArea.fill.color,"fill-opacity":c.config.chart.zoom.zoomedArea.fill.opacity,stroke:c.config.chart.zoom.zoomedArea.stroke.color,"stroke-width":c.config.chart.zoom.zoomedArea.stroke.width,"stroke-opacity":c.config.chart.zoom.zoomedArea.stroke.opacity}),_.setAttrs(u.node,d)),c.globals.selectionEnabled&&(h.attr({x:e,y:n,width:r>0?r:0,height:i>0?i:0,fill:c.config.chart.selection.fill.color,"fill-opacity":c.config.chart.selection.fill.opacity,stroke:c.config.chart.selection.stroke.color,"stroke-width":c.config.chart.selection.stroke.width,"stroke-dasharray":c.config.chart.selection.stroke.dashArray,"stroke-opacity":c.config.chart.selection.stroke.opacity}),_.setAttrs(h.node,d))}}},{key:"hideSelectionRect",value:function(t){t&&t.attr({x:0,y:0,width:0,height:0})}},{key:"selectionDrawing",value:function(t){var e=t.context,n=t.zoomtype,r=this.w,i=e,a=this.gridRect.getBoundingClientRect(),o=i.startX-1,s=i.startY,l=!1,c=!1,u=i.clientX-a.left-o,h=i.clientY-a.top-s,d={};return Math.abs(u+o)>r.globals.gridWidth?u=r.globals.gridWidth-o:i.clientX-a.left<0&&(u=o),o>i.clientX-a.left&&(l=!0,u=Math.abs(u)),s>i.clientY-a.top&&(c=!0,h=Math.abs(h)),d="x"===n?{x:l?o-u:o,y:0,width:u,height:r.globals.gridHeight}:"y"===n?{x:0,y:c?s-h:s,width:r.globals.gridWidth,height:h}:{x:l?o-u:o,y:c?s-h:s,width:u,height:h},i.drawSelectionRect(d),i.selectionDragging("resizing"),d}},{key:"selectionDragging",value:function(t,e){var n=this,r=this.w,i=this.xyRatios,a=this.selectionRect,o=0;"resizing"===t&&(o=30);var s=function(t){return parseFloat(a.node.getAttribute(t))},l={x:s("x"),y:s("y"),width:s("width"),height:s("height")};r.globals.selection=l,"function"==typeof r.config.chart.events.selection&&r.globals.selectionEnabled&&(clearTimeout(this.w.globals.selectionResizeTimer),this.w.globals.selectionResizeTimer=window.setTimeout((function(){var t,e,o,s,l=n.gridRect.getBoundingClientRect(),c=a.node.getBoundingClientRect();r.globals.isRangeBar?(t=r.globals.yAxisScale[0].niceMin+(c.left-l.left)*i.invertedYRatio,e=r.globals.yAxisScale[0].niceMin+(c.right-l.left)*i.invertedYRatio,o=0,s=1):(t=r.globals.xAxisScale.niceMin+(c.left-l.left)*i.xRatio,e=r.globals.xAxisScale.niceMin+(c.right-l.left)*i.xRatio,o=r.globals.yAxisScale[0].niceMin+(l.bottom-c.bottom)*i.yRatio[0],s=r.globals.yAxisScale[0].niceMax-(c.top-l.top)*i.yRatio[0]);var u={xaxis:{min:t,max:e},yaxis:{min:o,max:s}};r.config.chart.events.selection(n.ctx,u),r.config.chart.brush.enabled&&void 0!==r.config.chart.events.brushScrolled&&r.config.chart.events.brushScrolled(n.ctx,u)}),o))}},{key:"selectionDrawn",value:function(t){var e=t.context,n=t.zoomtype,r=this.w,i=e,a=this.xyRatios,o=this.ctx.toolbar;if(i.startX>i.endX){var s=i.startX;i.startX=i.endX,i.endX=s}if(i.startY>i.endY){var l=i.startY;i.startY=i.endY,i.endY=l}var c=void 0,u=void 0;r.globals.isRangeBar?(c=r.globals.yAxisScale[0].niceMin+i.startX*a.invertedYRatio,u=r.globals.yAxisScale[0].niceMin+i.endX*a.invertedYRatio):(c=r.globals.xAxisScale.niceMin+i.startX*a.xRatio,u=r.globals.xAxisScale.niceMin+i.endX*a.xRatio);var h=[],d=[];if(r.config.yaxis.forEach((function(t,e){var n=r.globals.seriesYAxisMap[e][0];h.push(r.globals.yAxisScale[e].niceMax-a.yRatio[n]*i.startY),d.push(r.globals.yAxisScale[e].niceMax-a.yRatio[n]*i.endY)})),i.dragged&&(i.dragX>10||i.dragY>10)&&c!==u)if(r.globals.zoomEnabled){var f=S.clone(r.globals.initialConfig.yaxis),p=S.clone(r.globals.initialConfig.xaxis);if(r.globals.zoomed=!0,r.config.xaxis.convertedCatToNumeric&&(c=Math.floor(c),u=Math.floor(u),c<1&&(c=1,u=r.globals.dataPoints),u-c<2&&(u=c+1)),"xy"!==n&&"x"!==n||(p={min:c,max:u}),"xy"!==n&&"y"!==n||f.forEach((function(t,e){f[e].min=d[e],f[e].max=h[e]})),o){var v=o.getBeforeZoomRange(p,f);v&&(p=v.xaxis?v.xaxis:p,f=v.yaxis?v.yaxis:f)}var g={xaxis:p};r.config.chart.group||(g.yaxis=f),i.ctx.updateHelpers._updateOptions(g,!1,i.w.config.chart.animations.dynamicAnimation.enabled),"function"==typeof r.config.chart.events.zoomed&&o.zoomCallback(p,f)}else if(r.globals.selectionEnabled){var m,y=null;m={min:c,max:u},"xy"!==n&&"y"!==n||(y=S.clone(r.config.yaxis)).forEach((function(t,e){y[e].min=d[e],y[e].max=h[e]})),r.globals.selection=i.selection,"function"==typeof r.config.chart.events.selection&&r.config.chart.events.selection(i.ctx,{xaxis:m,yaxis:y})}}},{key:"panDragging",value:function(t){var e=t.context,n=this.w,r=e;if(void 0!==n.globals.lastClientPosition.x){var i=n.globals.lastClientPosition.x-r.clientX,a=n.globals.lastClientPosition.y-r.clientY;Math.abs(i)>Math.abs(a)&&i>0?this.moveDirection="left":Math.abs(i)>Math.abs(a)&&i<0?this.moveDirection="right":Math.abs(a)>Math.abs(i)&&a>0?this.moveDirection="up":Math.abs(a)>Math.abs(i)&&a<0&&(this.moveDirection="down")}n.globals.lastClientPosition={x:r.clientX,y:r.clientY};var o=n.globals.isRangeBar?n.globals.minY:n.globals.minX,s=n.globals.isRangeBar?n.globals.maxY:n.globals.maxX;n.config.xaxis.convertedCatToNumeric||r.panScrolled(o,s)}},{key:"delayedPanScrolled",value:function(){var t=this.w,e=t.globals.minX,n=t.globals.maxX,r=(t.globals.maxX-t.globals.minX)/2;"left"===this.moveDirection?(e=t.globals.minX+r,n=t.globals.maxX+r):"right"===this.moveDirection&&(e=t.globals.minX-r,n=t.globals.maxX-r),e=Math.floor(e),n=Math.floor(n),this.updateScrolledChart({xaxis:{min:e,max:n}},e,n)}},{key:"panScrolled",value:function(t,e){var n=this.w,r=this.xyRatios,i=S.clone(n.globals.initialConfig.yaxis),a=r.xRatio,o=n.globals.minX,s=n.globals.maxX;n.globals.isRangeBar&&(a=r.invertedYRatio,o=n.globals.minY,s=n.globals.maxY),"left"===this.moveDirection?(t=o+n.globals.gridWidth/15*a,e=s+n.globals.gridWidth/15*a):"right"===this.moveDirection&&(t=o-n.globals.gridWidth/15*a,e=s-n.globals.gridWidth/15*a),n.globals.isRangeBar||(tn.globals.initialMaxX)&&(t=o,e=s);var l={xaxis:{min:t,max:e}};n.config.chart.group||(l.yaxis=i),this.updateScrolledChart(l,t,e)}},{key:"updateScrolledChart",value:function(t,e,n){var r=this.w;this.ctx.updateHelpers._updateOptions(t,!1,!1),"function"==typeof r.config.chart.events.scrolled&&r.config.chart.events.scrolled(this.ctx,{xaxis:{min:e,max:n}})}}]),n}(mt),bt=function(){function t(e){o(this,t),this.w=e.w,this.ttCtx=e,this.ctx=e.ctx}return l(t,[{key:"getNearestValues",value:function(t){var e=t.hoverArea,n=t.elGrid,r=t.clientX,i=t.clientY,a=this.w,o=n.getBoundingClientRect(),s=o.width,l=o.height,c=s/(a.globals.dataPoints-1),u=l/a.globals.dataPoints,h=this.hasBars();!a.globals.comboCharts&&!h||a.config.xaxis.convertedCatToNumeric||(c=s/a.globals.dataPoints);var d=r-o.left-a.globals.barPadForNumericAxis,f=i-o.top;d<0||f<0||d>s||f>l?(e.classList.remove("hovering-zoom"),e.classList.remove("hovering-pan")):a.globals.zoomEnabled?(e.classList.remove("hovering-pan"),e.classList.add("hovering-zoom")):a.globals.panEnabled&&(e.classList.remove("hovering-zoom"),e.classList.add("hovering-pan"));var p=Math.round(d/c),v=Math.floor(f/u);h&&!a.config.xaxis.convertedCatToNumeric&&(p=Math.ceil(d/c),p-=1);var g=null,m=null,y=a.globals.seriesXvalues.map((function(t){return t.filter((function(t){return S.isNumber(t)}))})),b=a.globals.seriesYvalues.map((function(t){return t.filter((function(t){return S.isNumber(t)}))}));if(a.globals.isXNumeric){var x=this.ttCtx.getElGrid().getBoundingClientRect(),w=d*(x.width/s),k=f*(x.height/l);g=(m=this.closestInMultiArray(w,k,y,b)).index,p=m.j,null!==g&&(y=a.globals.seriesXvalues[g],p=(m=this.closestInArray(w,y)).index)}return a.globals.capturedSeriesIndex=null===g?-1:g,(!p||p<1)&&(p=0),a.globals.isBarHorizontal?a.globals.capturedDataPointIndex=v:a.globals.capturedDataPointIndex=p,{capturedSeries:g,j:a.globals.isBarHorizontal?v:p,hoverX:d,hoverY:f}}},{key:"closestInMultiArray",value:function(t,e,n,r){var i=this.w,a=0,o=null,s=-1;i.globals.series.length>1?a=this.getFirstActiveXArray(n):o=0;var l=n[a][0],c=Math.abs(t-l);if(n.forEach((function(e){e.forEach((function(e,n){var r=Math.abs(t-e);r<=c&&(c=r,s=n)}))})),-1!==s){var u=r[a][s],h=Math.abs(e-u);o=a,r.forEach((function(t,n){var r=Math.abs(e-t[s]);r<=h&&(h=r,o=n)}))}return{index:o,j:s}}},{key:"getFirstActiveXArray",value:function(t){for(var e=this.w,n=0,r=t.map((function(t,e){return t.length>0?e:-1})),i=0;i0)for(var r=0;r *")):this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-series-markers-wrap > *")}},{key:"getAllMarkers",value:function(){var t=this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-series-markers-wrap");(t=b(t)).sort((function(t,e){var n=Number(t.getAttribute("data:realIndex")),r=Number(e.getAttribute("data:realIndex"));return rn?-1:0}));var e=[];return t.forEach((function(t){e.push(t.querySelector(".apexcharts-marker"))})),e}},{key:"hasMarkers",value:function(t){return this.getElMarkers(t).length>0}},{key:"getPathFromPoint",value:function(t,e){var n=Number(t.getAttribute("cx")),r=Number(t.getAttribute("cy")),i=t.getAttribute("shape");return new _(this.ctx).getMarkerPath(n,r,i,e)}},{key:"getElBars",value:function(){return this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-bar-series, .apexcharts-candlestick-series, .apexcharts-boxPlot-series, .apexcharts-rangebar-series")}},{key:"hasBars",value:function(){return this.getElBars().length>0}},{key:"getHoverMarkerSize",value:function(t){var e=this.w,n=e.config.markers.hover.size;return void 0===n&&(n=e.globals.markers.size[t]+e.config.markers.hover.sizeOffset),n}},{key:"toggleAllTooltipSeriesGroups",value:function(t){var e=this.w,n=this.ttCtx;0===n.allTooltipSeriesGroups.length&&(n.allTooltipSeriesGroups=e.globals.dom.baseEl.querySelectorAll(".apexcharts-tooltip-series-group"));for(var r=n.allTooltipSeriesGroups,i=0;i ').concat(n.attrs.name,""),e+="
".concat(n.val,"
")})),y.innerHTML=t+"",b.innerHTML=e+""};o?l.globals.seriesGoals[e][n]&&Array.isArray(l.globals.seriesGoals[e][n])?x():(y.innerHTML="",b.innerHTML=""):x()}else y.innerHTML="",b.innerHTML="";if(null!==p&&(r[e].querySelector(".apexcharts-tooltip-text-z-label").innerHTML=l.config.tooltip.z.title,r[e].querySelector(".apexcharts-tooltip-text-z-value").innerHTML=void 0!==p?p:""),o&&v[0]){if(l.config.tooltip.hideEmptySeries){var w=r[e].querySelector(".apexcharts-tooltip-marker"),k=r[e].querySelector(".apexcharts-tooltip-text");0==parseFloat(u)?(w.style.display="none",k.style.display="none"):(w.style.display="block",k.style.display="block")}null==u||l.globals.ancillaryCollapsedSeriesIndices.indexOf(e)>-1||l.globals.collapsedSeriesIndices.indexOf(e)>-1||Array.isArray(c.tConfig.enabledOnSeries)&&-1===c.tConfig.enabledOnSeries.indexOf(e)?v[0].parentNode.style.display="none":v[0].parentNode.style.display=l.config.tooltip.items.display}else Array.isArray(c.tConfig.enabledOnSeries)&&-1===c.tConfig.enabledOnSeries.indexOf(e)&&(v[0].parentNode.style.display="none")}},{key:"toggleActiveInactiveSeries",value:function(t,e){var n=this.w;if(t)this.tooltipUtil.toggleAllTooltipSeriesGroups("enable");else{this.tooltipUtil.toggleAllTooltipSeriesGroups("disable");var r=n.globals.dom.baseEl.querySelector(".apexcharts-tooltip-series-group-".concat(e));r&&(r.classList.add("apexcharts-active"),r.style.display=n.config.tooltip.items.display)}}},{key:"getValuesToPrint",value:function(t){var e=t.i,n=t.j,r=this.w,i=this.ctx.series.filteredSeriesX(),a="",o="",s=null,l=null,c={series:r.globals.series,seriesIndex:e,dataPointIndex:n,w:r},u=r.globals.ttZFormatter;null===n?l=r.globals.series[e]:r.globals.isXNumeric&&"treemap"!==r.config.chart.type?(a=i[e][n],0===i[e].length&&(a=i[this.tooltipUtil.getFirstActiveXArray(i)][n])):a=new Z(this.ctx).isFormatXY()?void 0!==r.config.series[e].data[n]?r.config.series[e].data[n].x:"":void 0!==r.globals.labels[n]?r.globals.labels[n]:"";var h=a;return a=r.globals.isXNumeric&&"datetime"===r.config.xaxis.type?new P(this.ctx).xLabelFormat(r.globals.ttKeyFormatter,h,h,{i:void 0,dateFormatter:new O(this.ctx).formatDate,w:this.w}):r.globals.isBarHorizontal?r.globals.yLabelFormatters[0](h,c):r.globals.xLabelFormatter(h,c),void 0!==r.config.tooltip.x.formatter&&(a=r.globals.ttKeyFormatter(h,c)),r.globals.seriesZ.length>0&&r.globals.seriesZ[e].length>0&&(s=u(r.globals.seriesZ[e][n],r)),o="function"==typeof r.config.xaxis.tooltip.formatter?r.globals.xaxisTooltipFormatter(h,c):a,{val:Array.isArray(l)?l.join(" "):l,xVal:Array.isArray(a)?a.join(" "):a,xAxisTTVal:Array.isArray(o)?o.join(" "):o,zVal:s}}},{key:"handleCustomTooltip",value:function(t){var e=t.i,n=t.j,r=t.y1,i=t.y2,a=t.w,o=this.ttCtx.getElTooltip(),s=a.config.tooltip.custom;Array.isArray(s)&&s[e]&&(s=s[e]),o.innerHTML=s({ctx:this.ctx,series:a.globals.series,seriesIndex:e,dataPointIndex:n,y1:r,y2:i,w:a})}}]),t}(),wt=function(){function t(e){o(this,t),this.ttCtx=e,this.ctx=e.ctx,this.w=e.w}return l(t,[{key:"moveXCrosshairs",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=this.ttCtx,r=this.w,i=n.getElXCrosshairs(),a=t-n.xcrosshairsWidth/2,o=r.globals.labels.slice().length;if(null!==e&&(a=r.globals.gridWidth/o*e),null===i||r.globals.isBarHorizontal||(i.setAttribute("x",a),i.setAttribute("x1",a),i.setAttribute("x2",a),i.setAttribute("y2",r.globals.gridHeight),i.classList.add("apexcharts-active")),a<0&&(a=0),a>r.globals.gridWidth&&(a=r.globals.gridWidth),n.isXAxisTooltipEnabled){var s=a;"tickWidth"!==r.config.xaxis.crosshairs.width&&"barWidth"!==r.config.xaxis.crosshairs.width||(s=a+n.xcrosshairsWidth/2),this.moveXAxisTooltip(s)}}},{key:"moveYCrosshairs",value:function(t){var e=this.ttCtx;null!==e.ycrosshairs&&_.setAttrs(e.ycrosshairs,{y1:t,y2:t}),null!==e.ycrosshairsHidden&&_.setAttrs(e.ycrosshairsHidden,{y1:t,y2:t})}},{key:"moveXAxisTooltip",value:function(t){var e=this.w,n=this.ttCtx;if(null!==n.xaxisTooltip&&0!==n.xcrosshairsWidth){n.xaxisTooltip.classList.add("apexcharts-active");var r,i=n.xaxisOffY+e.config.xaxis.tooltip.offsetY+e.globals.translateY+1+e.config.xaxis.offsetY;if(t-=n.xaxisTooltip.getBoundingClientRect().width/2,!isNaN(t))t+=e.globals.translateX,r=new _(this.ctx).getTextRects(n.xaxisTooltipText.innerHTML),n.xaxisTooltipText.style.minWidth=r.width+"px",n.xaxisTooltip.style.left=t+"px",n.xaxisTooltip.style.top=i+"px"}}},{key:"moveYAxisTooltip",value:function(t){var e=this.w,n=this.ttCtx;null===n.yaxisTTEls&&(n.yaxisTTEls=e.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxistooltip"));var r=parseInt(n.ycrosshairsHidden.getAttribute("y1"),10),i=e.globals.translateY+r,a=n.yaxisTTEls[t].getBoundingClientRect().height,o=e.globals.translateYAxisX[t]-2;e.config.yaxis[t].opposite&&(o-=26),i-=a/2,-1===e.globals.ignoreYAxisIndexes.indexOf(t)?(n.yaxisTTEls[t].classList.add("apexcharts-active"),n.yaxisTTEls[t].style.top=i+"px",n.yaxisTTEls[t].style.left=o+e.config.yaxis[t].tooltip.offsetX+"px"):n.yaxisTTEls[t].classList.remove("apexcharts-active")}},{key:"moveTooltip",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=this.w,i=this.ttCtx,a=i.getElTooltip(),o=i.tooltipRect,s=null!==n?parseFloat(n):1,l=parseFloat(t)+s+5,c=parseFloat(e)+s/2;if(l>r.globals.gridWidth/2&&(l=l-o.ttWidth-s-10),l>r.globals.gridWidth-o.ttWidth-10&&(l=r.globals.gridWidth-o.ttWidth),l<-20&&(l=-20),r.config.tooltip.followCursor){var u=i.getElGrid().getBoundingClientRect();(l=i.e.clientX-u.left)>r.globals.gridWidth/2&&(l-=i.tooltipRect.ttWidth),(c=i.e.clientY+r.globals.translateY-u.top)>r.globals.gridHeight/2&&(c-=i.tooltipRect.ttHeight)}else r.globals.isBarHorizontal||o.ttHeight/2+c>r.globals.gridHeight&&(c=r.globals.gridHeight-o.ttHeight+r.globals.translateY);isNaN(l)||(l+=r.globals.translateX,a.style.left=l+"px",a.style.top=c+"px")}},{key:"moveMarkers",value:function(t,e){var n=this.w,r=this.ttCtx;if(n.globals.markers.size[t]>0)for(var i=n.globals.dom.baseEl.querySelectorAll(" .apexcharts-series[data\\:realIndex='".concat(t,"'] .apexcharts-marker")),a=0;a0){var f=d.getAttribute("shape"),p=l.getMarkerPath(i,a,f,1.5*u);d.setAttribute("d",p)}this.moveXCrosshairs(i),s.fixedTooltip||this.moveTooltip(i,a,u)}}},{key:"moveDynamicPointsOnHover",value:function(t){var e,n=this.ttCtx,r=n.w,i=0,a=0,o=r.globals.pointsArray,s=new q(this.ctx),l=new _(this.ctx);e=s.getActiveConfigSeriesIndex("asc",["line","area","scatter","bubble"]);var c=n.tooltipUtil.getHoverMarkerSize(e);o[e]&&(i=o[e][t][0],a=o[e][t][1]);var u=n.tooltipUtil.getAllMarkers();if(null!==u)for(var h=0;h0){var m=l.getMarkerPath(i,f,v,c);u[h].setAttribute("d",m)}else u[h].setAttribute("d","")}}this.moveXCrosshairs(i),n.fixedTooltip||this.moveTooltip(i,a||r.globals.gridHeight,c)}},{key:"moveStickyTooltipOverBars",value:function(t,e){var n=this.w,r=this.ttCtx,i=n.globals.columnSeries?n.globals.columnSeries.length:n.globals.series.length,a=i>=2&&i%2==0?Math.floor(i/2):Math.floor(i/2)+1;n.globals.isBarHorizontal&&(a=new q(this.ctx).getActiveConfigSeriesIndex("desc")+1);var o=n.globals.dom.baseEl.querySelector(".apexcharts-bar-series .apexcharts-series[rel='".concat(a,"'] path[j='").concat(t,"'], .apexcharts-candlestick-series .apexcharts-series[rel='").concat(a,"'] path[j='").concat(t,"'], .apexcharts-boxPlot-series .apexcharts-series[rel='").concat(a,"'] path[j='").concat(t,"'], .apexcharts-rangebar-series .apexcharts-series[rel='").concat(a,"'] path[j='").concat(t,"']"));o||"number"!=typeof e||(o=n.globals.dom.baseEl.querySelector(".apexcharts-bar-series .apexcharts-series[data\\:realIndex='".concat(e,"'] path[j='").concat(t,"'],\n .apexcharts-candlestick-series .apexcharts-series[data\\:realIndex='").concat(e,"'] path[j='").concat(t,"'],\n .apexcharts-boxPlot-series .apexcharts-series[data\\:realIndex='").concat(e,"'] path[j='").concat(t,"'],\n .apexcharts-rangebar-series .apexcharts-series[data\\:realIndex='").concat(e,"'] path[j='").concat(t,"']")));var s=o?parseFloat(o.getAttribute("cx")):0,l=o?parseFloat(o.getAttribute("cy")):0,c=o?parseFloat(o.getAttribute("barWidth")):0,u=r.getElGrid().getBoundingClientRect(),h=o&&(o.classList.contains("apexcharts-candlestick-area")||o.classList.contains("apexcharts-boxPlot-area"));n.globals.isXNumeric?(o&&!h&&(s-=i%2!=0?c/2:0),o&&h&&n.globals.comboCharts&&(s-=c/2)):n.globals.isBarHorizontal||(s=r.xAxisTicksPositions[t-1]+r.dataPointsDividedWidth/2,isNaN(s)&&(s=r.xAxisTicksPositions[t]-r.dataPointsDividedWidth/2)),n.globals.isBarHorizontal?l-=r.tooltipRect.ttHeight:n.config.tooltip.followCursor?l=r.e.clientY-u.top-r.tooltipRect.ttHeight/2:l+r.tooltipRect.ttHeight+15>n.globals.gridHeight&&(l=n.globals.gridHeight),n.globals.isBarHorizontal||this.moveXCrosshairs(s),r.fixedTooltip||this.moveTooltip(s,l||n.globals.gridHeight)}}]),t}(),kt=function(){function t(e){o(this,t),this.w=e.w,this.ttCtx=e,this.ctx=e.ctx,this.tooltipPosition=new wt(e)}return l(t,[{key:"drawDynamicPoints",value:function(){var t=this.w,e=new _(this.ctx),n=new X(this.ctx),r=t.globals.dom.baseEl.querySelectorAll(".apexcharts-series");r=b(r),t.config.chart.stacked&&r.sort((function(t,e){return parseFloat(t.getAttribute("data:realIndex"))-parseFloat(e.getAttribute("data:realIndex"))}));for(var i=0;i2&&void 0!==arguments[2]?arguments[2]:null,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,i=this.w;"bubble"!==i.config.chart.type&&this.newPointSize(t,e);var a=e.getAttribute("cx"),o=e.getAttribute("cy");if(null!==n&&null!==r&&(a=n,o=r),this.tooltipPosition.moveXCrosshairs(a),!this.fixedTooltip){if("radar"===i.config.chart.type){var s=this.ttCtx.getElGrid().getBoundingClientRect();a=this.ttCtx.e.clientX-s.left}this.tooltipPosition.moveTooltip(a,o,i.config.markers.hover.size)}}},{key:"enlargePoints",value:function(t){for(var e=this.w,n=this,r=this.ttCtx,i=t,a=e.globals.dom.baseEl.querySelectorAll(".apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker"),o=e.config.markers.hover.size,s=0;s=0){var r=this.ttCtx.tooltipUtil.getPathFromPoint(t[e],n);t[e].setAttribute("d",r)}else t[e].setAttribute("d","M0,0")}}}]),t}(),St=function(){function t(e){o(this,t),this.w=e.w;var n=this.w;this.ttCtx=e,this.isVerticalGroupedRangeBar=!n.globals.isBarHorizontal&&"rangeBar"===n.config.chart.type&&n.config.plotOptions.bar.rangeBarGroupRows}return l(t,[{key:"getAttr",value:function(t,e){return parseFloat(t.target.getAttribute(e))}},{key:"handleHeatTreeTooltip",value:function(t){var e=t.e,n=t.opt,r=t.x,i=t.y,a=t.type,o=this.ttCtx,s=this.w;if(e.target.classList.contains("apexcharts-".concat(a,"-rect"))){var l=this.getAttr(e,"i"),c=this.getAttr(e,"j"),u=this.getAttr(e,"cx"),h=this.getAttr(e,"cy"),d=this.getAttr(e,"width"),f=this.getAttr(e,"height");if(o.tooltipLabels.drawSeriesTexts({ttItems:n.ttItems,i:l,j:c,shared:!1,e:e}),s.globals.capturedSeriesIndex=l,s.globals.capturedDataPointIndex=c,r=u+o.tooltipRect.ttWidth/2+d,i=h+o.tooltipRect.ttHeight/2-f/2,o.tooltipPosition.moveXCrosshairs(u+d/2),r>s.globals.gridWidth/2&&(r=u-o.tooltipRect.ttWidth/2+d),o.w.config.tooltip.followCursor){var p=s.globals.dom.elWrap.getBoundingClientRect();r=s.globals.clientX-p.left-(r>s.globals.gridWidth/2?o.tooltipRect.ttWidth:0),i=s.globals.clientY-p.top-(i>s.globals.gridHeight/2?o.tooltipRect.ttHeight:0)}}return{x:r,y:i}}},{key:"handleMarkerTooltip",value:function(t){var e,n,r=t.e,i=t.opt,a=t.x,o=t.y,s=this.w,l=this.ttCtx;if(r.target.classList.contains("apexcharts-marker")){var c=parseInt(i.paths.getAttribute("cx"),10),u=parseInt(i.paths.getAttribute("cy"),10),h=parseFloat(i.paths.getAttribute("val"));if(n=parseInt(i.paths.getAttribute("rel"),10),e=parseInt(i.paths.parentNode.parentNode.parentNode.getAttribute("rel"),10)-1,l.intersect){var d=S.findAncestor(i.paths,"apexcharts-series");d&&(e=parseInt(d.getAttribute("data:realIndex"),10))}if(l.tooltipLabels.drawSeriesTexts({ttItems:i.ttItems,i:e,j:n,shared:!l.showOnIntersect&&s.config.tooltip.shared,e:r}),"mouseup"===r.type&&l.markerClick(r,e,n),s.globals.capturedSeriesIndex=e,s.globals.capturedDataPointIndex=n,a=c,o=u+s.globals.translateY-1.4*l.tooltipRect.ttHeight,l.w.config.tooltip.followCursor){var f=l.getElGrid().getBoundingClientRect();o=l.e.clientY+s.globals.translateY-f.top}h<0&&(o=u),l.marker.enlargeCurrentPoint(n,i.paths,a,o)}return{x:a,y:o}}},{key:"handleBarTooltip",value:function(t){var e,n,r=t.e,i=t.opt,a=this.w,o=this.ttCtx,s=o.getElTooltip(),l=0,c=0,u=0,h=this.getBarTooltipXY({e:r,opt:i});e=h.i;var d=h.j;a.globals.capturedSeriesIndex=e,a.globals.capturedDataPointIndex=d,a.globals.isBarHorizontal&&o.tooltipUtil.hasBars()||!a.config.tooltip.shared?(c=h.x,u=h.y,n=Array.isArray(a.config.stroke.width)?a.config.stroke.width[e]:a.config.stroke.width,l=c):a.globals.comboCharts||a.config.tooltip.shared||(l/=2),isNaN(u)&&(u=a.globals.svgHeight-o.tooltipRect.ttHeight);var f=parseInt(i.paths.parentNode.getAttribute("data:realIndex"),10);if(a.globals.isMultipleYAxis?a.config.yaxis[f]&&a.config.yaxis[f].reversed:a.config.yaxis[0].reversed,c+o.tooltipRect.ttWidth>a.globals.gridWidth?c-=o.tooltipRect.ttWidth:c<0&&(c=0),o.w.config.tooltip.followCursor){var p=o.getElGrid().getBoundingClientRect();u=o.e.clientY-p.top}null===o.tooltip&&(o.tooltip=a.globals.dom.baseEl.querySelector(".apexcharts-tooltip")),a.config.tooltip.shared||(a.globals.comboBarCount>0?o.tooltipPosition.moveXCrosshairs(l+n/2):o.tooltipPosition.moveXCrosshairs(l)),!o.fixedTooltip&&(!a.config.tooltip.shared||a.globals.isBarHorizontal&&o.tooltipUtil.hasBars())&&(u=u+a.globals.translateY-o.tooltipRect.ttHeight/2,s.style.left=c+a.globals.translateX+"px",s.style.top=u+"px")}},{key:"getBarTooltipXY",value:function(t){var e=this,n=t.e,r=t.opt,i=this.w,a=null,o=this.ttCtx,s=0,l=0,c=0,u=0,h=0,d=n.target.classList;if(d.contains("apexcharts-bar-area")||d.contains("apexcharts-candlestick-area")||d.contains("apexcharts-boxPlot-area")||d.contains("apexcharts-rangebar-area")){var f=n.target,p=f.getBoundingClientRect(),v=r.elGrid.getBoundingClientRect(),g=p.height;h=p.height;var m=p.width,y=parseInt(f.getAttribute("cx"),10),b=parseInt(f.getAttribute("cy"),10);u=parseFloat(f.getAttribute("barWidth"));var x="touchmove"===n.type?n.touches[0].clientX:n.clientX;a=parseInt(f.getAttribute("j"),10),s=parseInt(f.parentNode.getAttribute("rel"),10)-1;var w=f.getAttribute("data-range-y1"),k=f.getAttribute("data-range-y2");i.globals.comboCharts&&(s=parseInt(f.parentNode.getAttribute("data:realIndex"),10));var S=function(t){return i.globals.isXNumeric?y-m/2:e.isVerticalGroupedRangeBar?y+m/2:y-o.dataPointsDividedWidth+m/2},C=function(){return b-o.dataPointsDividedHeight+g/2-o.tooltipRect.ttHeight/2};o.tooltipLabels.drawSeriesTexts({ttItems:r.ttItems,i:s,j:a,y1:w?parseInt(w,10):null,y2:k?parseInt(k,10):null,shared:!o.showOnIntersect&&i.config.tooltip.shared,e:n}),i.config.tooltip.followCursor?i.globals.isBarHorizontal?(l=x-v.left+15,c=C()):(l=S(),c=n.clientY-v.top-o.tooltipRect.ttHeight/2-15):i.globals.isBarHorizontal?((l=y)0&&n.setAttribute("width",e.xcrosshairsWidth)}},{key:"handleYCrosshair",value:function(){var t=this.w,e=this.ttCtx;e.ycrosshairs=t.globals.dom.baseEl.querySelector(".apexcharts-ycrosshairs"),e.ycrosshairsHidden=t.globals.dom.baseEl.querySelector(".apexcharts-ycrosshairs-hidden")}},{key:"drawYaxisTooltipText",value:function(t,e,n){var r=this.ttCtx,i=this.w,a=i.globals,o=a.seriesYAxisMap[t];if(r.yaxisTooltips[t]&&o.length>0){var s=a.yLabelFormatters[t],l=r.getElGrid().getBoundingClientRect(),c=o[0],u=0;n.yRatio.length>1&&(u=c);var h=(e-l.top)*n.yRatio[u],d=a.maxYArr[c]-a.minYArr[c],f=a.minYArr[c]+(d-h);i.config.yaxis[t].reversed&&(f=a.maxYArr[c]-(d-h)),r.tooltipPosition.moveYCrosshairs(e-l.top),r.yaxisTooltipText[t].innerHTML=s(f),r.tooltipPosition.moveYAxisTooltip(t)}}}]),t}(),At=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w;var n=this.w;this.tConfig=n.config.tooltip,this.tooltipUtil=new bt(this),this.tooltipLabels=new xt(this),this.tooltipPosition=new wt(this),this.marker=new kt(this),this.intersect=new St(this),this.axesTooltip=new Ct(this),this.showOnIntersect=this.tConfig.intersect,this.showTooltipTitle=this.tConfig.x.show,this.fixedTooltip=this.tConfig.fixed.enabled,this.xaxisTooltip=null,this.yaxisTTEls=null,this.isBarShared=!n.globals.isBarHorizontal&&this.tConfig.shared,this.lastHoverTime=Date.now()}return l(t,[{key:"getElTooltip",value:function(t){return t||(t=this),t.w.globals.dom.baseEl?t.w.globals.dom.baseEl.querySelector(".apexcharts-tooltip"):null}},{key:"getElXCrosshairs",value:function(){return this.w.globals.dom.baseEl.querySelector(".apexcharts-xcrosshairs")}},{key:"getElGrid",value:function(){return this.w.globals.dom.baseEl.querySelector(".apexcharts-grid")}},{key:"drawTooltip",value:function(t){var e=this.w;this.xyRatios=t,this.isXAxisTooltipEnabled=e.config.xaxis.tooltip.enabled&&e.globals.axisCharts,this.yaxisTooltips=e.config.yaxis.map((function(t,n){return!!(t.show&&t.tooltip.enabled&&e.globals.axisCharts)})),this.allTooltipSeriesGroups=[],e.globals.axisCharts||(this.showTooltipTitle=!1);var n=document.createElement("div");if(n.classList.add("apexcharts-tooltip"),e.config.tooltip.cssClass&&n.classList.add(e.config.tooltip.cssClass),n.classList.add("apexcharts-theme-".concat(this.tConfig.theme)),e.globals.dom.elWrap.appendChild(n),e.globals.axisCharts){this.axesTooltip.drawXaxisTooltip(),this.axesTooltip.drawYaxisTooltip(),this.axesTooltip.setXCrosshairWidth(),this.axesTooltip.handleYCrosshair();var r=new J(this.ctx);this.xAxisTicksPositions=r.getXAxisTicksPositions()}if(!e.globals.comboCharts&&!this.tConfig.intersect&&"rangeBar"!==e.config.chart.type||this.tConfig.shared||(this.showOnIntersect=!0),0!==e.config.markers.size&&0!==e.globals.markers.largestSize||this.marker.drawDynamicPoints(this),e.globals.collapsedSeries.length!==e.globals.series.length){this.dataPointsDividedHeight=e.globals.gridHeight/e.globals.dataPoints,this.dataPointsDividedWidth=e.globals.gridWidth/e.globals.dataPoints,this.showTooltipTitle&&(this.tooltipTitle=document.createElement("div"),this.tooltipTitle.classList.add("apexcharts-tooltip-title"),this.tooltipTitle.style.fontFamily=this.tConfig.style.fontFamily||e.config.chart.fontFamily,this.tooltipTitle.style.fontSize=this.tConfig.style.fontSize,n.appendChild(this.tooltipTitle));var i=e.globals.series.length;(e.globals.xyCharts||e.globals.comboCharts)&&this.tConfig.shared&&(i=this.showOnIntersect?1:e.globals.series.length),this.legendLabels=e.globals.dom.baseEl.querySelectorAll(".apexcharts-legend-text"),this.ttItems=this.createTTElements(i),this.addSVGEvents()}}},{key:"createTTElements",value:function(t){for(var e=this,n=this.w,r=[],i=this.getElTooltip(),a=function(a){var o=document.createElement("div");o.classList.add("apexcharts-tooltip-series-group","apexcharts-tooltip-series-group-".concat(a)),o.style.order=n.config.tooltip.inverseOrder?t-a:a+1;var s=document.createElement("span");s.classList.add("apexcharts-tooltip-marker"),s.style.backgroundColor=n.globals.colors[a],o.appendChild(s);var l=document.createElement("div");l.classList.add("apexcharts-tooltip-text"),l.style.fontFamily=e.tConfig.style.fontFamily||n.config.chart.fontFamily,l.style.fontSize=e.tConfig.style.fontSize,["y","goals","z"].forEach((function(t){var e=document.createElement("div");e.classList.add("apexcharts-tooltip-".concat(t,"-group"));var n=document.createElement("span");n.classList.add("apexcharts-tooltip-text-".concat(t,"-label")),e.appendChild(n);var r=document.createElement("span");r.classList.add("apexcharts-tooltip-text-".concat(t,"-value")),e.appendChild(r),l.appendChild(e)})),o.appendChild(l),i.appendChild(o),r.push(o)},o=0;o0&&this.addPathsEventListeners(f,u),this.tooltipUtil.hasBars()&&!this.tConfig.shared&&this.addDatapointEventsListeners(u)}}},{key:"drawFixedTooltipRect",value:function(){var t=this.w,e=this.getElTooltip(),n=e.getBoundingClientRect(),r=n.width+10,i=n.height+10,a=this.tConfig.fixed.offsetX,o=this.tConfig.fixed.offsetY,s=this.tConfig.fixed.position.toLowerCase();return s.indexOf("right")>-1&&(a=a+t.globals.svgWidth-r+10),s.indexOf("bottom")>-1&&(o=o+t.globals.svgHeight-i-10),e.style.left=a+"px",e.style.top=o+"px",{x:a,y:o,ttWidth:r,ttHeight:i}}},{key:"addDatapointEventsListeners",value:function(t){var e=this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-series-markers .apexcharts-marker, .apexcharts-bar-area, .apexcharts-candlestick-area, .apexcharts-boxPlot-area, .apexcharts-rangebar-area");this.addPathsEventListeners(e,t)}},{key:"addPathsEventListeners",value:function(t,e){for(var n=this,r=function(r){var i={paths:t[r],tooltipEl:e.tooltipEl,tooltipY:e.tooltipY,tooltipX:e.tooltipX,elGrid:e.elGrid,hoverArea:e.hoverArea,ttItems:e.ttItems};["mousemove","mouseup","touchmove","mouseout","touchend"].map((function(e){return t[r].addEventListener(e,n.onSeriesHover.bind(n,i),{capture:!1,passive:!0})}))},i=0;i=100?this.seriesHover(t,e):(clearTimeout(this.seriesHoverTimeout),this.seriesHoverTimeout=setTimeout((function(){n.seriesHover(t,e)}),100-r))}},{key:"seriesHover",value:function(t,e){var n=this;this.lastHoverTime=Date.now();var r=[],i=this.w;i.config.chart.group&&(r=this.ctx.getGroupedCharts()),i.globals.axisCharts&&(i.globals.minX===-1/0&&i.globals.maxX===1/0||0===i.globals.dataPoints)||(r.length?r.forEach((function(r){var i=n.getElTooltip(r),a={paths:t.paths,tooltipEl:i,tooltipY:t.tooltipY,tooltipX:t.tooltipX,elGrid:t.elGrid,hoverArea:t.hoverArea,ttItems:r.w.globals.tooltip.ttItems};r.w.globals.minX===n.w.globals.minX&&r.w.globals.maxX===n.w.globals.maxX&&r.w.globals.tooltip.seriesHoverByContext({chartCtx:r,ttCtx:r.w.globals.tooltip,opt:a,e:e})})):this.seriesHoverByContext({chartCtx:this.ctx,ttCtx:this.w.globals.tooltip,opt:t,e:e}))}},{key:"seriesHoverByContext",value:function(t){var e=t.chartCtx,n=t.ttCtx,r=t.opt,i=t.e,a=e.w,o=this.getElTooltip(e);o&&(n.tooltipRect={x:0,y:0,ttWidth:o.getBoundingClientRect().width,ttHeight:o.getBoundingClientRect().height},n.e=i,!n.tooltipUtil.hasBars()||a.globals.comboCharts||n.isBarShared||this.tConfig.onDatasetHover.highlightDataSeries&&new q(e).toggleSeriesOnHover(i,i.target.parentNode),n.fixedTooltip&&n.drawFixedTooltipRect(),a.globals.axisCharts?n.axisChartsTooltips({e:i,opt:r,tooltipRect:n.tooltipRect}):n.nonAxisChartsTooltips({e:i,opt:r,tooltipRect:n.tooltipRect}))}},{key:"axisChartsTooltips",value:function(t){var e,n,r=t.e,i=t.opt,a=this.w,o=i.elGrid.getBoundingClientRect(),s="touchmove"===r.type?r.touches[0].clientX:r.clientX,l="touchmove"===r.type?r.touches[0].clientY:r.clientY;if(this.clientY=l,this.clientX=s,a.globals.capturedSeriesIndex=-1,a.globals.capturedDataPointIndex=-1,lo.top+o.height)this.handleMouseOut(i);else{if(Array.isArray(this.tConfig.enabledOnSeries)&&!a.config.tooltip.shared){var c=parseInt(i.paths.getAttribute("index"),10);if(this.tConfig.enabledOnSeries.indexOf(c)<0)return void this.handleMouseOut(i)}var u=this.getElTooltip(),h=this.getElXCrosshairs(),d=[];a.config.chart.group&&(d=this.ctx.getSyncedCharts());var f=a.globals.xyCharts||"bar"===a.config.chart.type&&!a.globals.isBarHorizontal&&this.tooltipUtil.hasBars()&&this.tConfig.shared||a.globals.comboCharts&&this.tooltipUtil.hasBars();if("mousemove"===r.type||"touchmove"===r.type||"mouseup"===r.type){if(a.globals.collapsedSeries.length+a.globals.ancillaryCollapsedSeries.length===a.globals.series.length)return;null!==h&&h.classList.add("apexcharts-active");var p=this.yaxisTooltips.filter((function(t){return!0===t}));if(null!==this.ycrosshairs&&p.length&&this.ycrosshairs.classList.add("apexcharts-active"),f&&!this.showOnIntersect||d.length>1)this.handleStickyTooltip(r,s,l,i);else if("heatmap"===a.config.chart.type||"treemap"===a.config.chart.type){var v=this.intersect.handleHeatTreeTooltip({e:r,opt:i,x:e,y:n,type:a.config.chart.type});e=v.x,n=v.y,u.style.left=e+"px",u.style.top=n+"px"}else this.tooltipUtil.hasBars()&&this.intersect.handleBarTooltip({e:r,opt:i}),this.tooltipUtil.hasMarkers()&&this.intersect.handleMarkerTooltip({e:r,opt:i,x:e,y:n});if(this.yaxisTooltips.length)for(var g=0;gl.width)this.handleMouseOut(r);else if(null!==s)this.handleStickyCapturedSeries(t,s,r,o);else if(this.tooltipUtil.isXoverlap(o)||i.globals.isBarHorizontal){var c=i.globals.series.findIndex((function(t,e){return!i.globals.collapsedSeriesIndices.includes(e)}));this.create(t,this,c,o,r.ttItems)}}},{key:"handleStickyCapturedSeries",value:function(t,e,n,r){var i=this.w;if(this.tConfig.shared||null!==i.globals.series[e][r]){if(void 0!==i.globals.series[e][r])this.tConfig.shared&&this.tooltipUtil.isXoverlap(r)&&this.tooltipUtil.isInitialSeriesSameLen()?this.create(t,this,e,r,n.ttItems):this.create(t,this,e,r,n.ttItems,!1);else if(this.tooltipUtil.isXoverlap(r)){var a=i.globals.series.findIndex((function(t,e){return!i.globals.collapsedSeriesIndices.includes(e)}));this.create(t,this,a,r,n.ttItems)}}else this.handleMouseOut(n)}},{key:"deactivateHoverFilter",value:function(){for(var t=this.w,e=new _(this.ctx),n=t.globals.dom.Paper.select(".apexcharts-bar-area"),r=0;r5&&void 0!==arguments[5]?arguments[5]:null,S=this.w,C=e;"mouseup"===t.type&&this.markerClick(t,n,r),null===k&&(k=this.tConfig.shared);var A=this.tooltipUtil.hasMarkers(n),D=this.tooltipUtil.getElBars();if(S.config.legend.tooltipHoverFormatter){var T=S.config.legend.tooltipHoverFormatter,E=Array.from(this.legendLabels);E.forEach((function(t){var e=t.getAttribute("data:default-text");t.innerHTML=decodeURIComponent(e)}));for(var O=0;O0?C.marker.enlargePoints(r):C.tooltipPosition.moveDynamicPointsOnHover(r);else if(this.tooltipUtil.hasBars()&&(this.barSeriesHeight=this.tooltipUtil.getBarsHeight(D),this.barSeriesHeight>0)){var j=new _(this.ctx),B=S.globals.dom.Paper.select(".apexcharts-bar-area[j='".concat(r,"']"));this.deactivateHoverFilter(),this.tooltipPosition.moveStickyTooltipOverBars(r,n);for(var R=0;R0&&e.config.plotOptions.bar.hideZeroBarsWhenGrouped&&(d-=c*k)),w&&(d=d+h.height/2-m/2-2);var C=e.globals.series[n][r]<0,A=s;switch(this.barCtx.isReversed&&(A=s+(C?u:-u)),v.position){case"center":f=w?C?A-u/2+b:A+u/2-b:C?A-u/2+h.height/2+b:A+u/2+h.height/2-b;break;case"bottom":f=w?C?A-u+b:A+u-b:C?A-u+h.height+m+b:A+u-h.height/2+m-b;break;case"top":f=w?C?A+b:A-b:C?A-h.height/2-b:A+h.height+b}if(this.barCtx.lastActiveBarSerieIndex===i&&g.enabled){var D=new _(this.barCtx.ctx).getTextRects(this.getStackedTotalDataLabel({realIndex:i,j:r}),p.fontSize);a=C?A-D.height/2-b-g.offsetY+18:A+D.height+b+g.offsetY-18;var T=S;o=x+(e.globals.isXNumeric?-c*e.globals.barGroups.length/2:e.globals.barGroups.length*c/2-(e.globals.barGroups.length-1)*c-T)+g.offsetX}return e.config.chart.stacked||(f<0?f=0+m:f+h.height/3>e.globals.gridHeight&&(f=e.globals.gridHeight-m)),{bcx:l,bcy:s,dataLabelsX:d,dataLabelsY:f,totalDataLabelsX:o,totalDataLabelsY:a,totalDataLabelsAnchor:"middle"}}},{key:"calculateBarsDataLabelsPosition",value:function(t){var e=this.w,n=t.x,r=t.i,i=t.j,a=t.realIndex,o=t.bcy,s=t.barHeight,l=t.barWidth,c=t.textRects,u=t.dataLabelsX,h=t.strokeWidth,d=t.dataLabelsConfig,f=t.barDataLabelsConfig,p=t.barTotalDataLabelsConfig,v=t.offX,g=t.offY,m=e.globals.gridHeight/e.globals.dataPoints;l=Math.abs(l);var y,b,x=o-(this.barCtx.isRangeBar?0:m)+s/2+c.height/2+g-3,w="start",k=e.globals.series[r][i]<0,S=n;switch(this.barCtx.isReversed&&(S=n+(k?-l:l),w=k?"start":"end"),f.position){case"center":u=k?S+l/2-v:Math.max(c.width/2,S-l/2)+v;break;case"bottom":u=k?S+l-h-v:S-l+h+v;break;case"top":u=k?S-h-v:S-h+v}if(this.barCtx.lastActiveBarSerieIndex===a&&p.enabled){var C=new _(this.barCtx.ctx).getTextRects(this.getStackedTotalDataLabel({realIndex:a,j:i}),d.fontSize);k?(y=S-h-v-p.offsetX,w="end"):y=S+v+p.offsetX+(this.barCtx.isReversed?-(l+h):h),b=x-c.height/2+C.height/2+p.offsetY+h}return e.config.chart.stacked||("start"===d.textAnchor?u-c.width<0?u=k?c.width+h:h:u+c.width>e.globals.gridWidth&&(u=k?e.globals.gridWidth-h:e.globals.gridWidth-c.width-h):"middle"===d.textAnchor?u-c.width/2<0?u=c.width/2+h:u+c.width/2>e.globals.gridWidth&&(u=e.globals.gridWidth-c.width/2-h):"end"===d.textAnchor&&(u<1?u=c.width+h:u+1>e.globals.gridWidth&&(u=e.globals.gridWidth-c.width-h))),{bcx:n,bcy:o,dataLabelsX:u,dataLabelsY:x,totalDataLabelsX:y,totalDataLabelsY:b,totalDataLabelsAnchor:w}}},{key:"drawCalculatedDataLabels",value:function(t){var e=t.x,n=t.y,r=t.val,i=t.i,a=t.j,o=t.textRects,s=t.barHeight,l=t.barWidth,c=t.dataLabelsConfig,u=this.w,h="rotate(0)";"vertical"===u.config.plotOptions.bar.dataLabels.orientation&&(h="rotate(-90, ".concat(e,", ").concat(n,")"));var d=new U(this.barCtx.ctx),f=new _(this.barCtx.ctx),p=c.formatter,v=null,m=u.globals.collapsedSeriesIndices.indexOf(i)>-1;if(c.enabled&&!m){v=f.group({class:"apexcharts-data-labels",transform:h});var y="";void 0!==r&&(y=p(r,g(g({},u),{},{seriesIndex:i,dataPointIndex:a,w:u}))),!r&&u.config.plotOptions.bar.hideZeroBarsWhenGrouped&&(y="");var b=u.globals.series[i][a]<0,x=u.config.plotOptions.bar.dataLabels.position;"vertical"===u.config.plotOptions.bar.dataLabels.orientation&&("top"===x&&(c.textAnchor=b?"end":"start"),"center"===x&&(c.textAnchor="middle"),"bottom"===x&&(c.textAnchor=b?"end":"start")),this.barCtx.isRangeBar&&this.barCtx.barOptions.dataLabels.hideOverflowingLabels&&lMath.abs(l)&&(y=""):o.height/1.6>Math.abs(s)&&(y=""));var w=g({},c);this.barCtx.isHorizontal&&r<0&&("start"===c.textAnchor?w.textAnchor="end":"end"===c.textAnchor&&(w.textAnchor="start")),d.plotDataLabelsText({x:e,y:n,text:y,i:i,j:a,parent:v,dataLabelsConfig:w,alwaysDrawDataLabel:!0,offsetCorrection:!0})}return v}},{key:"drawTotalDataLabels",value:function(t){var e=t.x,n=t.y,r=t.val,i=t.realIndex,a=t.textAnchor,o=t.barTotalDataLabelsConfig;this.w;var s,l=new _(this.barCtx.ctx);return o.enabled&&void 0!==e&&void 0!==n&&this.barCtx.lastActiveBarSerieIndex===i&&(s=l.drawText({x:e,y:n,foreColor:o.style.color,text:r,textAnchor:a,fontFamily:o.style.fontFamily,fontSize:o.style.fontSize,fontWeight:o.style.fontWeight})),s}}]),t}(),Dt=function(){function t(e){o(this,t),this.w=e.w,this.barCtx=e}return l(t,[{key:"initVariables",value:function(t){var e=this.w;this.barCtx.series=t,this.barCtx.totalItems=0,this.barCtx.seriesLen=0,this.barCtx.visibleI=-1,this.barCtx.visibleItems=1;for(var n=0;n0&&(this.barCtx.seriesLen=this.barCtx.seriesLen+1,this.barCtx.totalItems+=t[n].length),e.globals.isXNumeric)for(var r=0;re.globals.minX&&e.globals.seriesX[n][r]0&&(r=l.globals.minXDiff/h),(a=r/u*parseInt(this.barCtx.barOptions.columnWidth,10)/100)<1&&(a=1)}-1===String(this.barCtx.barOptions.columnWidth).indexOf("%")&&(a=parseInt(this.barCtx.barOptions.columnWidth,10)),o=l.globals.gridHeight-this.barCtx.baseLineY[this.barCtx.translationsIndex]-(this.barCtx.isReversed?l.globals.gridHeight:0)+(this.barCtx.isReversed?2*this.barCtx.baseLineY[this.barCtx.translationsIndex]:0),t=l.globals.padHorizontal+(r-a*this.barCtx.seriesLen)/2}return l.globals.barHeight=i,l.globals.barWidth=a,{x:t,y:e,yDivision:n,xDivision:r,barHeight:i,barWidth:a,zeroH:o,zeroW:s}}},{key:"initializeStackedPrevVars",value:function(t){t.w.globals.seriesGroups.forEach((function(e){t[e]||(t[e]={}),t[e].prevY=[],t[e].prevX=[],t[e].prevYF=[],t[e].prevXF=[],t[e].prevYVal=[],t[e].prevXVal=[]}))}},{key:"initializeStackedXYVars",value:function(t){t.w.globals.seriesGroups.forEach((function(e){t[e]||(t[e]={}),t[e].xArrj=[],t[e].xArrjF=[],t[e].xArrjVal=[],t[e].yArrj=[],t[e].yArrjF=[],t[e].yArrjVal=[]}))}},{key:"getPathFillColor",value:function(t,e,n,r){var i,a,o,s,l,c=this.w,u=this.barCtx.ctx.fill,h=null,d=this.barCtx.barOptions.distributed?n:e;return this.barCtx.barOptions.colors.ranges.length>0&&this.barCtx.barOptions.colors.ranges.map((function(r){t[e][n]>=r.from&&t[e][n]<=r.to&&(h=r.color)})),null!==(i=c.config.series[e].data[n])&&void 0!==i&&i.fillColor&&(h=c.config.series[e].data[n].fillColor),u.fillPath({seriesNumber:this.barCtx.barOptions.distributed?d:r,dataPointIndex:n,color:h,value:t[e][n],fillConfig:null===(a=c.config.series[e].data[n])||void 0===a?void 0:a.fill,fillType:null!==(o=c.config.series[e].data[n])&&void 0!==o&&null!==(s=o.fill)&&void 0!==s&&s.type?null===(l=c.config.series[e].data[n])||void 0===l?void 0:l.fill.type:Array.isArray(c.config.fill.type)?c.config.fill.type[r]:c.config.fill.type})}},{key:"getStrokeWidth",value:function(t,e,n){var r=0,i=this.w;return this.barCtx.series[t][e]?this.barCtx.isNullValue=!1:this.barCtx.isNullValue=!0,i.config.stroke.show&&(this.barCtx.isNullValue||(r=Array.isArray(this.barCtx.strokeWidth)?this.barCtx.strokeWidth[n]:this.barCtx.strokeWidth)),r}},{key:"createBorderRadiusArr",value:function(t){var e=this.w,n=!this.w.config.chart.stacked||"last"!==e.config.plotOptions.bar.borderRadiusWhenStacked||e.config.plotOptions.bar.borderRadius<=0,r=t.length,i=t[0].length,a=Array.from({length:r},(function(){return Array(i).fill(n?"top":"none")}));if(n)return a;for(var o=0;o0?(s.push(h),u++):d<0&&(l.push(h),u++)}if(s.length>0&&0===l.length)if(1===s.length)a[s[0]][o]="both";else{var f,p=s[0],v=s[s.length-1],g=c(s);try{for(g.s();!(f=g.n()).done;){var m=f.value;a[m][o]=m===p?"bottom":m===v?"top":"none"}}catch(t){g.e(t)}finally{g.f()}}else if(l.length>0&&0===s.length)if(1===l.length)a[l[0]][o]="both";else{var y,b=l[0],x=l[l.length-1],w=c(l);try{for(w.s();!(y=w.n()).done;){var k=y.value;a[k][o]=k===b?"bottom":k===x?"top":"none"}}catch(t){w.e(t)}finally{w.f()}}else if(s.length>0&&l.length>0){var S,C=s[s.length-1],A=c(s);try{for(A.s();!(S=A.n()).done;){var _=S.value;a[_][o]=_===C?"top":"none"}}catch(t){A.e(t)}finally{A.f()}var D,T=l[l.length-1],E=c(l);try{for(E.s();!(D=E.n()).done;){var O=D.value;a[O][o]=O===T?"bottom":"none"}}catch(t){E.e(t)}finally{E.f()}}else 1===u&&(a[s[0]||l[0]][o]="both")}return a}},{key:"barBackground",value:function(t){var e=t.j,n=t.i,r=t.x1,i=t.x2,a=t.y1,o=t.y2,s=t.elSeries,l=this.w,c=new _(this.barCtx.ctx),u=new q(this.barCtx.ctx).getActiveConfigSeriesIndex();if(this.barCtx.barOptions.colors.backgroundBarColors.length>0&&u===n){e>=this.barCtx.barOptions.colors.backgroundBarColors.length&&(e%=this.barCtx.barOptions.colors.backgroundBarColors.length);var h=this.barCtx.barOptions.colors.backgroundBarColors[e],d=c.drawRect(void 0!==r?r:0,void 0!==a?a:0,void 0!==i?i:l.globals.gridWidth,void 0!==o?o:l.globals.gridHeight,this.barCtx.barOptions.colors.backgroundBarRadius,h,this.barCtx.barOptions.colors.backgroundBarOpacity);s.add(d),d.node.classList.add("apexcharts-backgroundBar")}}},{key:"getColumnPaths",value:function(t){var e,n=t.barWidth,r=t.barXPosition,i=t.y1,a=t.y2,o=t.strokeWidth,s=t.isReversed,l=t.series,c=t.seriesGroup,u=t.realIndex,h=t.i,d=t.j,f=t.w,p=new _(this.barCtx.ctx);(o=Array.isArray(o)?o[u]:o)||(o=0);var v=n,g=r;null!==(e=f.config.series[u].data[d])&&void 0!==e&&e.columnWidthOffset&&(g=r-f.config.series[u].data[d].columnWidthOffset/2,v=n+f.config.series[u].data[d].columnWidthOffset);var m=o/2,y=g+m,b=g+v-m,x=(l[h][d]>=0?1:-1)*(s?-1:1);i+=.001-m*x,a+=.001+m*x;var w=p.move(y,i),k=p.move(y,i),S=p.line(b,i);if(f.globals.previousPaths.length>0&&(k=this.barCtx.getPreviousPath(u,d,!1)),w=w+p.line(y,a)+p.line(b,a)+S+("around"===f.config.plotOptions.bar.borderRadiusApplication||"both"===this.arrBorderRadius[u][d]?" Z":" z"),k=k+p.line(y,i)+S+S+S+S+S+p.line(y,i)+("around"===f.config.plotOptions.bar.borderRadiusApplication||"both"===this.arrBorderRadius[u][d]?" Z":" z"),"none"!==this.arrBorderRadius[u][d]&&(w=p.roundPathCorners(w,f.config.plotOptions.bar.borderRadius)),f.config.chart.stacked){var C=this.barCtx;(C=this.barCtx[c]).yArrj.push(a-m*x),C.yArrjF.push(Math.abs(i-a+o*x)),C.yArrjVal.push(this.barCtx.series[h][d])}return{pathTo:w,pathFrom:k}}},{key:"getBarpaths",value:function(t){var e,n=t.barYPosition,r=t.barHeight,i=t.x1,a=t.x2,o=t.strokeWidth,s=t.isReversed,l=t.series,c=t.seriesGroup,u=t.realIndex,h=t.i,d=t.j,f=t.w,p=new _(this.barCtx.ctx);(o=Array.isArray(o)?o[u]:o)||(o=0);var v=n,g=r;null!==(e=f.config.series[u].data[d])&&void 0!==e&&e.barHeightOffset&&(v=n-f.config.series[u].data[d].barHeightOffset/2,g=r+f.config.series[u].data[d].barHeightOffset);var m=o/2,y=v+m,b=v+g-m,x=(l[h][d]>=0?1:-1)*(s?-1:1);i+=.001+m*x,a+=.001-m*x;var w=p.move(i,y),k=p.move(i,y);f.globals.previousPaths.length>0&&(k=this.barCtx.getPreviousPath(u,d,!1));var S=p.line(i,b);if(w=w+p.line(a,y)+p.line(a,b)+S+("around"===f.config.plotOptions.bar.borderRadiusApplication||"both"===this.arrBorderRadius[u][d]?" Z":" z"),k=k+p.line(i,y)+S+S+S+S+S+p.line(i,y)+("around"===f.config.plotOptions.bar.borderRadiusApplication||"both"===this.arrBorderRadius[u][d]?" Z":" z"),"none"!==this.arrBorderRadius[u][d]&&(w=p.roundPathCorners(w,f.config.plotOptions.bar.borderRadius)),f.config.chart.stacked){var C=this.barCtx;(C=this.barCtx[c]).xArrj.push(a+m*x),C.xArrjF.push(Math.abs(i-a-o*x)),C.xArrjVal.push(this.barCtx.series[h][d])}return{pathTo:w,pathFrom:k}}},{key:"checkZeroSeries",value:function(t){for(var e=t.series,n=this.w,r=0;r2&&void 0!==arguments[2]&&!arguments[2]?null:e;return null!=t&&(n=e+t/this.barCtx.invertedYRatio-2*(this.barCtx.isReversed?t/this.barCtx.invertedYRatio:0)),n}},{key:"getYForValue",value:function(t,e,n){var r=arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?null:e;return null!=t&&(r=e-t/this.barCtx.yRatio[n]+2*(this.barCtx.isReversed?t/this.barCtx.yRatio[n]:0)),r}},{key:"getGoalValues",value:function(t,e,n,r,i,a){var o=this,s=this.w,l=[],c=function(r,i){var s;l.push((h(s={},t,"x"===t?o.getXForValue(r,e,!1):o.getYForValue(r,n,a,!1)),h(s,"attrs",i),s))};if(s.globals.seriesGoals[r]&&s.globals.seriesGoals[r][i]&&Array.isArray(s.globals.seriesGoals[r][i])&&s.globals.seriesGoals[r][i].forEach((function(t){c(t.value,t)})),this.barCtx.barOptions.isDumbbell&&s.globals.seriesRange.length){var u=this.barCtx.barOptions.dumbbellColors?this.barCtx.barOptions.dumbbellColors:s.globals.colors,d={strokeHeight:"x"===t?0:s.globals.markers.size[r],strokeWidth:"x"===t?s.globals.markers.size[r]:0,strokeDashArray:0,strokeLineCap:"round",strokeColor:Array.isArray(u[r])?u[r][0]:u[r]};c(s.globals.seriesRangeStart[r][i],d),c(s.globals.seriesRangeEnd[r][i],g(g({},d),{},{strokeColor:Array.isArray(u[r])?u[r][1]:u[r]}))}return l}},{key:"drawGoalLine",value:function(t){var e=t.barXPosition,n=t.barYPosition,r=t.goalX,i=t.goalY,a=t.barWidth,o=t.barHeight,s=new _(this.barCtx.ctx),l=s.group({className:"apexcharts-bar-goals-groups"});l.node.classList.add("apexcharts-element-hidden"),this.barCtx.w.globals.delayedElements.push({el:l.node}),l.attr("clip-path","url(#gridRectMarkerMask".concat(this.barCtx.w.globals.cuid,")"));var c=null;return this.barCtx.isHorizontal?Array.isArray(r)&&r.forEach((function(t){if(t.x>=-1&&t.x<=s.w.globals.gridWidth+1){var e=void 0!==t.attrs.strokeHeight?t.attrs.strokeHeight:o/2,r=n+e+o/2;c=s.drawLine(t.x,r-2*e,t.x,r,t.attrs.strokeColor?t.attrs.strokeColor:void 0,t.attrs.strokeDashArray,t.attrs.strokeWidth?t.attrs.strokeWidth:2,t.attrs.strokeLineCap),l.add(c)}})):Array.isArray(i)&&i.forEach((function(t){if(t.y>=-1&&t.y<=s.w.globals.gridHeight+1){var n=void 0!==t.attrs.strokeWidth?t.attrs.strokeWidth:a/2,r=e+n+a/2;c=s.drawLine(r-2*n,t.y,r,t.y,t.attrs.strokeColor?t.attrs.strokeColor:void 0,t.attrs.strokeDashArray,t.attrs.strokeHeight?t.attrs.strokeHeight:2,t.attrs.strokeLineCap),l.add(c)}})),l}},{key:"drawBarShadow",value:function(t){var e=t.prevPaths,n=t.currPaths,r=t.color,i=this.w,a=e.x,o=e.x1,s=e.barYPosition,l=n.x,c=n.x1,u=n.barYPosition,h=s+n.barHeight,d=new _(this.barCtx.ctx),f=new S,p=d.move(o,h)+d.line(a,h)+d.line(l,u)+d.line(c,u)+d.line(o,h)+("around"===i.config.plotOptions.bar.borderRadiusApplication||"both"===this.arrBorderRadius[realIndex][j]?" Z":" z");return d.drawPath({d:p,fill:f.shadeColor(.5,S.rgb2hex(r)),stroke:"none",strokeWidth:0,fillOpacity:1,classes:"apexcharts-bar-shadows"})}},{key:"getZeroValueEncounters",value:function(t){var e,n=t.i,r=t.j,i=this.w,a=0,o=0;return(i.config.plotOptions.bar.horizontal?i.globals.series.map((function(t,e){return e})):(null===(e=i.globals.columnSeries)||void 0===e?void 0:e.i.map((function(t){return t})))||[]).forEach((function(t){var e=i.globals.seriesPercent[t][r];e&&a++,t-1})),r=this.barCtx.columnGroupIndices,i=r.indexOf(n);return i<0&&(r.push(n),i=r.length-1),{groupIndex:n,columnGroupIndex:i}}}]),t}(),Tt=function(){function t(e,n){o(this,t),this.ctx=e,this.w=e.w;var r=this.w;this.barOptions=r.config.plotOptions.bar,this.isHorizontal=this.barOptions.horizontal,this.strokeWidth=r.config.stroke.width,this.isNullValue=!1,this.isRangeBar=r.globals.seriesRange.length&&this.isHorizontal,this.isVerticalGroupedRangeBar=!r.globals.isBarHorizontal&&r.globals.seriesRange.length&&r.config.plotOptions.bar.rangeBarGroupRows,this.isFunnel=this.barOptions.isFunnel,this.xyRatios=n,null!==this.xyRatios&&(this.xRatio=n.xRatio,this.yRatio=n.yRatio,this.invertedXRatio=n.invertedXRatio,this.invertedYRatio=n.invertedYRatio,this.baseLineY=n.baseLineY,this.baseLineInvertedY=n.baseLineInvertedY),this.yaxisIndex=0,this.translationsIndex=0,this.seriesLen=0,this.pathArr=[];var i=new q(this.ctx);this.lastActiveBarSerieIndex=i.getActiveConfigSeriesIndex("desc",["bar","column"]),this.columnGroupIndices=[];var a=i.getBarSeriesIndices(),s=new D(this.ctx);this.stackedSeriesTotals=s.getStackedSeriesTotals(this.w.config.series.map((function(t,e){return-1===a.indexOf(e)?e:-1})).filter((function(t){return-1!==t}))),this.barHelpers=new Dt(this)}return l(t,[{key:"draw",value:function(t,e){var n=this.w,r=new _(this.ctx),i=new D(this.ctx,n);t=i.getLogSeries(t),this.series=t,this.yRatio=i.getLogYRatios(this.yRatio),this.barHelpers.initVariables(t);var a=r.group({class:"apexcharts-bar-series apexcharts-plot-series"});n.config.dataLabels.enabled&&this.totalItems>this.barOptions.dataLabels.maxItems&&console.warn("WARNING: DataLabels are enabled but there are too many to display. This may cause performance issue when rendering - ApexCharts");for(var o=0,s=0;o0&&(this.visibleI=this.visibleI+1);var x=0,w=0;this.yRatio.length>1&&(this.yaxisIndex=n.globals.seriesYAxisReverseMap[m],this.translationsIndex=m);var k=this.translationsIndex;this.isReversed=n.config.yaxis[this.yaxisIndex]&&n.config.yaxis[this.yaxisIndex].reversed;var C=this.barHelpers.initialPositions();f=C.y,x=C.barHeight,c=C.yDivision,h=C.zeroW,d=C.x,w=C.barWidth,l=C.xDivision,u=C.zeroH,this.horizontal||v.push(d+w/2);var A=r.group({class:"apexcharts-datalabels","data:realIndex":m});n.globals.delayedElements.push({el:A.node}),A.node.classList.add("apexcharts-element-hidden");var T=r.group({class:"apexcharts-bar-goals-markers"}),E=r.group({class:"apexcharts-bar-shadows"});n.globals.delayedElements.push({el:E.node}),E.node.classList.add("apexcharts-element-hidden");for(var O=0;O0){var L=this.barHelpers.drawBarShadow({color:"string"==typeof V&&-1===(null==V?void 0:V.indexOf("url"))?V:S.hexToRgba(n.globals.colors[o]),prevPaths:this.pathArr[this.pathArr.length-1],currPaths:I});L&&E.add(L)}this.pathArr.push(I);var j=this.barHelpers.drawGoalLine({barXPosition:I.barXPosition,barYPosition:I.barYPosition,goalX:I.goalX,goalY:I.goalY,barHeight:x,barWidth:w});j&&T.add(j),f=I.y,d=I.x,O>0&&v.push(d+w/2),p.push(f),this.renderSeries({realIndex:m,pathFill:V,j:O,i:o,columnGroupIndex:y,pathFrom:I.pathFrom,pathTo:I.pathTo,strokeWidth:P,elSeries:b,x:d,y:f,series:t,barHeight:Math.abs(I.barHeight?I.barHeight:x),barWidth:Math.abs(I.barWidth?I.barWidth:w),elDataLabelsWrap:A,elGoalsMarkers:T,elBarShadows:E,visibleSeries:this.visibleI,type:"bar"})}n.globals.seriesXvalues[m]=v,n.globals.seriesYvalues[m]=p,a.add(b)}return a}},{key:"renderSeries",value:function(t){var e=t.realIndex,n=t.pathFill,r=t.lineFill,i=t.j,a=t.i,o=t.columnGroupIndex,s=t.pathFrom,l=t.pathTo,c=t.strokeWidth,u=t.elSeries,h=t.x,d=t.y,f=t.y1,p=t.y2,v=t.series,g=t.barHeight,m=t.barWidth,y=t.barXPosition,b=t.barYPosition,x=t.elDataLabelsWrap,w=t.elGoalsMarkers,k=t.elBarShadows,S=t.visibleSeries,C=t.type,D=t.classes,T=this.w,E=new _(this.ctx);if(!r){var O="function"==typeof T.globals.stroke.colors[e]?function(t){var e,n=T.config.stroke.colors;return Array.isArray(n)&&n.length>0&&((e=n[t])||(e=""),"function"==typeof e)?e({value:T.globals.series[t][i],dataPointIndex:i,w:T}):e}(e):T.globals.stroke.colors[e];r=this.barOptions.distributed?T.globals.stroke.colors[i]:O}T.config.series[a].data[i]&&T.config.series[a].data[i].strokeColor&&(r=T.config.series[a].data[i].strokeColor),this.isNullValue&&(n="none");var P=i/T.config.chart.animations.animateGradually.delay*(T.config.chart.animations.speed/T.globals.dataPoints)/2.4,I=E.renderPaths({i:a,j:i,realIndex:e,pathFrom:s,pathTo:l,stroke:r,strokeWidth:c,strokeLineCap:T.config.stroke.lineCap,fill:n,animationDelay:P,initialSpeed:T.config.chart.animations.speed,dataChangeSpeed:T.config.chart.animations.dynamicAnimation.speed,className:"apexcharts-".concat(C,"-area ").concat(D),chartType:C});I.attr("clip-path","url(#gridRectBarMask".concat(T.globals.cuid,")"));var M=T.config.forecastDataPoints;M.count>0&&i>=T.globals.dataPoints-M.count&&(I.node.setAttribute("stroke-dasharray",M.dashArray),I.node.setAttribute("stroke-width",M.strokeWidth),I.node.setAttribute("fill-opacity",M.fillOpacity)),void 0!==f&&void 0!==p&&(I.attr("data-range-y1",f),I.attr("data-range-y2",p)),new A(this.ctx).setSelectionFilter(I,e,i),u.add(I);var V=new _t(this).handleBarDataLabels({x:h,y:d,y1:f,y2:p,i:a,j:i,series:v,realIndex:e,columnGroupIndex:o,barHeight:g,barWidth:m,barXPosition:y,barYPosition:b,renderedPath:I,visibleSeries:S});return null!==V.dataLabels&&x.add(V.dataLabels),V.totalDataLabels&&x.add(V.totalDataLabels),u.add(x),w&&u.add(w),k&&u.add(k),u}},{key:"drawBarPaths",value:function(t){var e,n=t.indexes,r=t.barHeight,i=t.strokeWidth,a=t.zeroW,o=t.x,s=t.y,l=t.yDivision,c=t.elSeries,u=this.w,h=n.i,d=n.j;if(u.globals.isXNumeric)e=(s=(u.globals.seriesX[h][d]-u.globals.minX)/this.invertedXRatio-r)+r*this.visibleI;else if(u.config.plotOptions.bar.hideZeroBarsWhenGrouped){var f=0,p=0;u.globals.seriesPercent.forEach((function(t,e){t[d]&&f++,e0&&(r=this.seriesLen*r/f),e=s+r*this.visibleI,e-=r*p}else e=s+r*this.visibleI;this.isFunnel&&(a-=(this.barHelpers.getXForValue(this.series[h][d],a)-a)/2),o=this.barHelpers.getXForValue(this.series[h][d],a);var v=this.barHelpers.getBarpaths({barYPosition:e,barHeight:r,x1:a,x2:o,strokeWidth:i,isReversed:this.isReversed,series:this.series,realIndex:n.realIndex,i:h,j:d,w:u});return u.globals.isXNumeric||(s+=l),this.barHelpers.barBackground({j:d,i:h,y1:e-r*this.visibleI,y2:r*this.seriesLen,elSeries:c}),{pathTo:v.pathTo,pathFrom:v.pathFrom,x1:a,x:o,y:s,goalX:this.barHelpers.getGoalValues("x",a,null,h,d),barYPosition:e,barHeight:r}}},{key:"drawColumnPaths",value:function(t){var e,n=t.indexes,r=t.x,i=t.y,a=t.xDivision,o=t.barWidth,s=t.zeroH,l=t.strokeWidth,c=t.elSeries,u=this.w,h=n.realIndex,d=n.translationsIndex,f=n.i,p=n.j,v=n.bc;if(u.globals.isXNumeric){var g=this.getBarXForNumericXAxis({x:r,j:p,realIndex:h,barWidth:o});r=g.x,e=g.barXPosition}else if(u.config.plotOptions.bar.hideZeroBarsWhenGrouped){var m=this.barHelpers.getZeroValueEncounters({i:f,j:p}),y=m.nonZeroColumns,b=m.zeroEncounters;y>0&&(o=this.seriesLen*o/y),e=r+o*this.visibleI,e-=o*b}else e=r+o*this.visibleI;i=this.barHelpers.getYForValue(this.series[f][p],s,d);var x=this.barHelpers.getColumnPaths({barXPosition:e,barWidth:o,y1:s,y2:i,strokeWidth:l,isReversed:this.isReversed,series:this.series,realIndex:h,i:f,j:p,w:u});return u.globals.isXNumeric||(r+=a),this.barHelpers.barBackground({bc:v,j:p,i:f,x1:e-l/2-o*this.visibleI,x2:o*this.seriesLen+l/2,elSeries:c}),{pathTo:x.pathTo,pathFrom:x.pathFrom,x:r,y:i,goalY:this.barHelpers.getGoalValues("y",null,s,f,p,d),barXPosition:e,barWidth:o}}},{key:"getBarXForNumericXAxis",value:function(t){var e=t.x,n=t.barWidth,r=t.realIndex,i=t.j,a=this.w,o=r;return a.globals.seriesX[r].length||(o=a.globals.maxValsInArrayIndex),a.globals.seriesX[o][i]&&(e=(a.globals.seriesX[o][i]-a.globals.minX)/this.xRatio-n*this.seriesLen/2),{barXPosition:e+n*this.visibleI,x:e}}},{key:"getPreviousPath",value:function(t,e){for(var n,r=this.w,i=0;i0&&parseInt(a.realIndex,10)===parseInt(t,10)&&void 0!==r.globals.previousPaths[i].paths[e]&&(n=r.globals.previousPaths[i].paths[e].d)}return n}}]),t}(),Et=function(t){f(n,t);var e=u(n);function n(){return o(this,n),e.apply(this,arguments)}return l(n,[{key:"draw",value:function(t,e){var n=this,r=this.w;this.graphics=new _(this.ctx),this.bar=new Tt(this.ctx,this.xyRatios);var i=new D(this.ctx,r);t=i.getLogSeries(t),this.yRatio=i.getLogYRatios(this.yRatio),this.barHelpers.initVariables(t),"100%"===r.config.chart.stackType&&(t=r.globals.comboCharts?e.map((function(t){return r.globals.seriesPercent[t]})):r.globals.seriesPercent.slice()),this.series=t,this.barHelpers.initializeStackedPrevVars(this);for(var a=this.graphics.group({class:"apexcharts-bar-series apexcharts-plot-series"}),o=0,s=0,l=function(i,l){var c=void 0,u=void 0,h=void 0,d=void 0,f=r.globals.comboCharts?e[i]:i,p=n.barHelpers.getGroupIndex(f),v=p.groupIndex,m=p.columnGroupIndex;n.groupCtx=n[r.globals.seriesGroups[v]];var y=[],b=[],x=0;n.yRatio.length>1&&(n.yaxisIndex=r.globals.seriesYAxisReverseMap[f][0],x=f),n.isReversed=r.config.yaxis[n.yaxisIndex]&&r.config.yaxis[n.yaxisIndex].reversed;var w=n.graphics.group({class:"apexcharts-series",seriesName:S.escapeString(r.globals.seriesNames[f]),rel:i+1,"data:realIndex":f});n.ctx.series.addCollapsedClassToSeries(w,f);var k=n.graphics.group({class:"apexcharts-datalabels","data:realIndex":f}),C=n.graphics.group({class:"apexcharts-bar-goals-markers"}),A=0,_=0,D=n.initialPositions(o,s,c,u,h,d,x);s=D.y,A=D.barHeight,u=D.yDivision,d=D.zeroW,o=D.x,_=D.barWidth,c=D.xDivision,h=D.zeroH,r.globals.barHeight=A,r.globals.barWidth=_,n.barHelpers.initializeStackedXYVars(n),1===n.groupCtx.prevY.length&&n.groupCtx.prevY[0].every((function(t){return isNaN(t)}))&&(n.groupCtx.prevY[0]=n.groupCtx.prevY[0].map((function(){return h})),n.groupCtx.prevYF[0]=n.groupCtx.prevYF[0].map((function(){return 0})));for(var T=0;T0&&(V="apexcharts-flip-x"):"bottom"===n.barHelpers.arrBorderRadius[f][T]&&r.globals.series[f][T]>0&&(V="apexcharts-flip-y"),w=n.renderSeries({realIndex:f,pathFill:M,j:T,i:i,columnGroupIndex:m,pathFrom:P.pathFrom,pathTo:P.pathTo,strokeWidth:E,elSeries:w,x:o,y:s,series:t,barHeight:A,barWidth:_,elDataLabelsWrap:k,elGoalsMarkers:C,type:"bar",visibleSeries:m,classes:V})}r.globals.seriesXvalues[f]=y,r.globals.seriesYvalues[f]=b,n.groupCtx.prevY.push(n.groupCtx.yArrj),n.groupCtx.prevYF.push(n.groupCtx.yArrjF),n.groupCtx.prevYVal.push(n.groupCtx.yArrjVal),n.groupCtx.prevX.push(n.groupCtx.xArrj),n.groupCtx.prevXF.push(n.groupCtx.xArrjF),n.groupCtx.prevXVal.push(n.groupCtx.xArrjVal),a.add(w)},c=0,u=0;c1?l=(n=c.globals.minXDiff/this.xRatio)*parseInt(this.barOptions.columnWidth,10)/100:-1===String(h).indexOf("%")?l=parseInt(h,10):l*=parseInt(h,10)/100,i=this.isReversed?this.baseLineY[o]:c.globals.gridHeight-this.baseLineY[o],t=c.globals.padHorizontal+(n-l)/2}var d=c.globals.barGroups.length||1;return{x:t,y:e,yDivision:r,xDivision:n,barHeight:s/d,barWidth:l/d,zeroH:i,zeroW:a}}},{key:"drawStackedBarPaths",value:function(t){for(var e,n=t.indexes,r=t.barHeight,i=t.strokeWidth,a=t.zeroW,o=t.x,s=t.y,l=t.columnGroupIndex,c=t.seriesGroup,u=t.yDivision,h=t.elSeries,d=this.w,f=s+l*r,p=n.i,v=n.j,g=n.realIndex,m=n.translationsIndex,y=0,b=0;b0){var w=a;this.groupCtx.prevXVal[x-1][v]<0?w=this.series[p][v]>=0?this.groupCtx.prevX[x-1][v]+y-2*(this.isReversed?y:0):this.groupCtx.prevX[x-1][v]:this.groupCtx.prevXVal[x-1][v]>=0&&(w=this.series[p][v]>=0?this.groupCtx.prevX[x-1][v]:this.groupCtx.prevX[x-1][v]-y+2*(this.isReversed?y:0)),e=w}else e=a;o=null===this.series[p][v]?e:e+this.series[p][v]/this.invertedYRatio-2*(this.isReversed?this.series[p][v]/this.invertedYRatio:0);var k=this.barHelpers.getBarpaths({barYPosition:f,barHeight:r,x1:e,x2:o,strokeWidth:i,isReversed:this.isReversed,series:this.series,realIndex:n.realIndex,seriesGroup:c,i:p,j:v,w:d});return this.barHelpers.barBackground({j:v,i:p,y1:f,y2:r,elSeries:h}),s+=u,{pathTo:k.pathTo,pathFrom:k.pathFrom,goalX:this.barHelpers.getGoalValues("x",a,null,p,v,m),barXPosition:e,barYPosition:f,x:o,y:s}}},{key:"drawStackedColumnPaths",value:function(t){var e=t.indexes,n=t.x,r=t.y,i=t.xDivision,a=t.barWidth,o=t.zeroH,s=t.columnGroupIndex,l=t.seriesGroup,c=t.elSeries,u=this.w,h=e.i,d=e.j,f=e.bc,p=e.realIndex,v=e.translationsIndex;if(u.globals.isXNumeric){var g=u.globals.seriesX[p][d];g||(g=0),n=(g-u.globals.minX)/this.xRatio-a/2*u.globals.barGroups.length}for(var m,y=n+s*a,b=0,x=0;x0&&!u.globals.isXNumeric||w>0&&u.globals.isXNumeric&&u.globals.seriesX[p-1][d]===u.globals.seriesX[p][d]){var k,S,C,A=Math.min(this.yRatio.length+1,p+1);if(void 0!==this.groupCtx.prevY[w-1]&&this.groupCtx.prevY[w-1].length)for(var _=1;_=0?C-b+2*(this.isReversed?b:0):C;break}if((null===(O=this.groupCtx.prevYVal[w-T])||void 0===O?void 0:O[d])>=0){S=this.series[h][d]>=0?C:C+b-2*(this.isReversed?b:0);break}}void 0===S&&(S=u.globals.gridHeight),m=null!==(k=this.groupCtx.prevYF[0])&&void 0!==k&&k.every((function(t){return 0===t}))&&this.groupCtx.prevYF.slice(1,w).every((function(t){return t.every((function(t){return isNaN(t)}))}))?o:S}else m=o;r=this.series[h][d]?m-this.series[h][d]/this.yRatio[v]+2*(this.isReversed?this.series[h][d]/this.yRatio[v]:0):m;var P=this.barHelpers.getColumnPaths({barXPosition:y,barWidth:a,y1:m,y2:r,yRatio:this.yRatio[v],strokeWidth:this.strokeWidth,isReversed:this.isReversed,series:this.series,seriesGroup:l,realIndex:e.realIndex,i:h,j:d,w:u});return this.barHelpers.barBackground({bc:f,j:d,i:h,x1:y,x2:a,elSeries:c}),{pathTo:P.pathTo,pathFrom:P.pathFrom,goalY:this.barHelpers.getGoalValues("y",null,o,h,d),barXPosition:y,x:u.globals.isXNumeric?n:n+i,y:r}}}]),n}(Tt),Ot=function(t){f(n,t);var e=u(n);function n(){return o(this,n),e.apply(this,arguments)}return l(n,[{key:"draw",value:function(t,e,n){var r=this,i=this.w,a=new _(this.ctx),o=i.globals.comboCharts?e:i.config.chart.type,s=new W(this.ctx);this.candlestickOptions=this.w.config.plotOptions.candlestick,this.boxOptions=this.w.config.plotOptions.boxPlot,this.isHorizontal=i.config.plotOptions.bar.horizontal;var l=new D(this.ctx,i);t=l.getLogSeries(t),this.series=t,this.yRatio=l.getLogYRatios(this.yRatio),this.barHelpers.initVariables(t);for(var c=a.group({class:"apexcharts-".concat(o,"-series apexcharts-plot-series")}),u=function(e){r.isBoxPlot="boxPlot"===i.config.chart.type||"boxPlot"===i.config.series[e].type;var o,l,u,h,d=void 0,f=void 0,p=[],v=[],m=i.globals.comboCharts?n[e]:e,y=r.barHelpers.getGroupIndex(m).columnGroupIndex,b=a.group({class:"apexcharts-series",seriesName:S.escapeString(i.globals.seriesNames[m]),rel:e+1,"data:realIndex":m});r.ctx.series.addCollapsedClassToSeries(b,m),t[e].length>0&&(r.visibleI=r.visibleI+1);var x,w,k=0;r.yRatio.length>1&&(r.yaxisIndex=i.globals.seriesYAxisReverseMap[m][0],k=m);var C=r.barHelpers.initialPositions();f=C.y,x=C.barHeight,l=C.yDivision,h=C.zeroW,d=C.x,w=C.barWidth,o=C.xDivision,u=C.zeroH,v.push(d+w/2);for(var A=a.group({class:"apexcharts-datalabels","data:realIndex":m}),_=function(n){var a=r.barHelpers.getStrokeWidth(e,n,m),c=null,S={indexes:{i:e,j:n,realIndex:m,translationsIndex:k},x:d,y:f,strokeWidth:a,elSeries:b};c=r.isHorizontal?r.drawHorizontalBoxPaths(g(g({},S),{},{yDivision:l,barHeight:x,zeroW:h})):r.drawVerticalBoxPaths(g(g({},S),{},{xDivision:o,barWidth:w,zeroH:u})),f=c.y,d=c.x,n>0&&v.push(d+w/2),p.push(f),c.pathTo.forEach((function(o,l){var u=!r.isBoxPlot&&r.candlestickOptions.wick.useFillColor?c.color[l]:i.globals.stroke.colors[e],h=s.fillPath({seriesNumber:m,dataPointIndex:n,color:c.color[l],value:t[e][n]});r.renderSeries({realIndex:m,pathFill:h,lineFill:u,j:n,i:e,pathFrom:c.pathFrom,pathTo:o,strokeWidth:a,elSeries:b,x:d,y:f,series:t,columnGroupIndex:y,barHeight:x,barWidth:w,elDataLabelsWrap:A,visibleSeries:r.visibleI,type:i.config.chart.type})}))},D=0;Dm.c&&(h=!1);var x=Math.min(m.o,m.c),w=Math.max(m.o,m.c),k=m.m;s.globals.isXNumeric&&(n=(s.globals.seriesX[g][u]-s.globals.minX)/this.xRatio-i/2);var S=n+i*this.visibleI;void 0===this.series[c][u]||null===this.series[c][u]?(x=a,w=a):(x=a-x/v,w=a-w/v,y=a-m.h/v,b=a-m.l/v,k=a-m.m/v);var C=l.move(S,a),A=l.move(S+i/2,x);return s.globals.previousPaths.length>0&&(A=this.getPreviousPath(g,u,!0)),C=this.isBoxPlot?[l.move(S,x)+l.line(S+i/2,x)+l.line(S+i/2,y)+l.line(S+i/4,y)+l.line(S+i-i/4,y)+l.line(S+i/2,y)+l.line(S+i/2,x)+l.line(S+i,x)+l.line(S+i,k)+l.line(S,k)+l.line(S,x+o/2),l.move(S,k)+l.line(S+i,k)+l.line(S+i,w)+l.line(S+i/2,w)+l.line(S+i/2,b)+l.line(S+i-i/4,b)+l.line(S+i/4,b)+l.line(S+i/2,b)+l.line(S+i/2,w)+l.line(S,w)+l.line(S,k)+"z"]:[l.move(S,w)+l.line(S+i/2,w)+l.line(S+i/2,y)+l.line(S+i/2,w)+l.line(S+i,w)+l.line(S+i,x)+l.line(S+i/2,x)+l.line(S+i/2,b)+l.line(S+i/2,x)+l.line(S,x)+l.line(S,w-o/2)],A+=l.move(S,x),s.globals.isXNumeric||(n+=r),{pathTo:C,pathFrom:A,x:n,y:w,barXPosition:S,color:this.isBoxPlot?p:h?[d]:[f]}}},{key:"drawHorizontalBoxPaths",value:function(t){var e=t.indexes;t.x;var n=t.y,r=t.yDivision,i=t.barHeight,a=t.zeroW,o=t.strokeWidth,s=this.w,l=new _(this.ctx),c=e.i,u=e.j,h=this.boxOptions.colors.lower;this.isBoxPlot&&(h=[this.boxOptions.colors.lower,this.boxOptions.colors.upper]);var d=this.invertedYRatio,f=e.realIndex,p=this.getOHLCValue(f,u),v=a,g=a,m=Math.min(p.o,p.c),y=Math.max(p.o,p.c),b=p.m;s.globals.isXNumeric&&(n=(s.globals.seriesX[f][u]-s.globals.minX)/this.invertedXRatio-i/2);var x=n+i*this.visibleI;void 0===this.series[c][u]||null===this.series[c][u]?(m=a,y=a):(m=a+m/d,y=a+y/d,v=a+p.h/d,g=a+p.l/d,b=a+p.m/d);var w=l.move(a,x),k=l.move(m,x+i/2);return s.globals.previousPaths.length>0&&(k=this.getPreviousPath(f,u,!0)),w=[l.move(m,x)+l.line(m,x+i/2)+l.line(v,x+i/2)+l.line(v,x+i/2-i/4)+l.line(v,x+i/2+i/4)+l.line(v,x+i/2)+l.line(m,x+i/2)+l.line(m,x+i)+l.line(b,x+i)+l.line(b,x)+l.line(m+o/2,x),l.move(b,x)+l.line(b,x+i)+l.line(y,x+i)+l.line(y,x+i/2)+l.line(g,x+i/2)+l.line(g,x+i-i/4)+l.line(g,x+i/4)+l.line(g,x+i/2)+l.line(y,x+i/2)+l.line(y,x)+l.line(b,x)+"z"],k+=l.move(m,x),s.globals.isXNumeric||(n+=r),{pathTo:w,pathFrom:k,x:y,y:n,barYPosition:x,color:h}}},{key:"getOHLCValue",value:function(t,e){var n=this.w;return{o:this.isBoxPlot?n.globals.seriesCandleH[t][e]:n.globals.seriesCandleO[t][e],h:this.isBoxPlot?n.globals.seriesCandleO[t][e]:n.globals.seriesCandleH[t][e],m:n.globals.seriesCandleM[t][e],l:this.isBoxPlot?n.globals.seriesCandleC[t][e]:n.globals.seriesCandleL[t][e],c:this.isBoxPlot?n.globals.seriesCandleL[t][e]:n.globals.seriesCandleC[t][e]}}}]),n}(Tt),Pt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"checkColorRange",value:function(){var t=this.w,e=!1,n=t.config.plotOptions[t.config.chart.type];return n.colorScale.ranges.length>0&&n.colorScale.ranges.map((function(t,n){t.from<=0&&(e=!0)})),e}},{key:"getShadeColor",value:function(t,e,n,r){var i=this.w,a=1,o=i.config.plotOptions[t].shadeIntensity,s=this.determineColor(t,e,n);i.globals.hasNegs||r?a=i.config.plotOptions[t].reverseNegativeShade?s.percent<0?s.percent/100*(1.25*o):(1-s.percent/100)*(1.25*o):s.percent<=0?1-(1+s.percent/100)*o:(1-s.percent/100)*o:(a=1-s.percent/100,"treemap"===t&&(a=(1-s.percent/100)*(1.25*o)));var l=s.color,c=new S;if(i.config.plotOptions[t].enableShades)if("dark"===this.w.config.theme.mode){var u=c.shadeColor(-1*a,s.color);l=S.hexToRgba(S.isColorHex(u)?u:S.rgb2hex(u),i.config.fill.opacity)}else{var h=c.shadeColor(a,s.color);l=S.hexToRgba(S.isColorHex(h)?h:S.rgb2hex(h),i.config.fill.opacity)}return{color:l,colorProps:s}}},{key:"determineColor",value:function(t,e,n){var r=this.w,i=r.globals.series[e][n],a=r.config.plotOptions[t],o=a.colorScale.inverse?n:e;a.distributed&&"treemap"===r.config.chart.type&&(o=n);var s=r.globals.colors[o],l=null,c=Math.min.apply(Math,b(r.globals.series[e])),u=Math.max.apply(Math,b(r.globals.series[e]));a.distributed||"heatmap"!==t||(c=r.globals.minY,u=r.globals.maxY),void 0!==a.colorScale.min&&(c=a.colorScale.minr.globals.maxY?a.colorScale.max:r.globals.maxY);var h=Math.abs(u)+Math.abs(c),d=100*i/(0===h?h-1e-6:h);return a.colorScale.ranges.length>0&&a.colorScale.ranges.map((function(t,e){if(i>=t.from&&i<=t.to){s=t.color,l=t.foreColor?t.foreColor:null,c=t.from,u=t.to;var n=Math.abs(u)+Math.abs(c);d=100*i/(0===n?n-1e-6:n)}})),{color:s,foreColor:l,percent:d}}},{key:"calculateDataLabels",value:function(t){var e=t.text,n=t.x,r=t.y,i=t.i,a=t.j,o=t.colorProps,s=t.fontSize,l=this.w.config.dataLabels,c=new _(this.ctx),u=new U(this.ctx),h=null;if(l.enabled){h=c.group({class:"apexcharts-data-labels"});var d=l.offsetX,f=l.offsetY,p=n+d,v=r+parseFloat(l.style.fontSize)/3+f;u.plotDataLabelsText({x:p,y:v,text:e,i:i,j:a,color:o.foreColor,parent:h,fontSize:s,dataLabelsConfig:l})}return h}},{key:"addListeners",value:function(t){var e=new _(this.ctx);t.node.addEventListener("mouseenter",e.pathMouseEnter.bind(this,t)),t.node.addEventListener("mouseleave",e.pathMouseLeave.bind(this,t)),t.node.addEventListener("mousedown",e.pathMouseDown.bind(this,t))}}]),t}(),It=function(){function t(e,n){o(this,t),this.ctx=e,this.w=e.w,this.xRatio=n.xRatio,this.yRatio=n.yRatio,this.dynamicAnim=this.w.config.chart.animations.dynamicAnimation,this.helpers=new Pt(e),this.rectRadius=this.w.config.plotOptions.heatmap.radius,this.strokeWidth=this.w.config.stroke.show?this.w.config.stroke.width:0}return l(t,[{key:"draw",value:function(t){var e=this.w,n=new _(this.ctx),r=n.group({class:"apexcharts-heatmap"});r.attr("clip-path","url(#gridRectMask".concat(e.globals.cuid,")"));var i=e.globals.gridWidth/e.globals.dataPoints,a=e.globals.gridHeight/e.globals.series.length,o=0,s=!1;this.negRange=this.helpers.checkColorRange();var l=t.slice();e.config.yaxis[0].reversed&&(s=!0,l.reverse());for(var c=s?0:l.length-1;s?c=0;s?c++:c--){var u=n.group({class:"apexcharts-series apexcharts-heatmap-series",seriesName:S.escapeString(e.globals.seriesNames[c]),rel:c+1,"data:realIndex":c});if(this.ctx.series.addCollapsedClassToSeries(u,c),e.config.chart.dropShadow.enabled){var h=e.config.chart.dropShadow;new A(this.ctx).dropShadow(u,h,c)}for(var d=0,f=e.config.plotOptions.heatmap.shadeIntensity,p=0;p-1&&this.pieClicked(h),n.config.dataLabels.enabled){var x=y.x,w=y.y,k=100*f/this.fullAngle+"%";if(0!==f&&n.config.plotOptions.pie.dataLabels.minAngleToShowLabelthis.fullAngle?e.endAngle=e.endAngle-(r+o):r+o=this.fullAngle+this.w.config.plotOptions.pie.startAngle%this.fullAngle&&(c=this.fullAngle+this.w.config.plotOptions.pie.startAngle%this.fullAngle-.01),Math.ceil(c)>this.fullAngle&&(c-=this.fullAngle);var u=Math.PI*(c-90)/180,h=n.centerX+a*Math.cos(l),d=n.centerY+a*Math.sin(l),f=n.centerX+a*Math.cos(u),p=n.centerY+a*Math.sin(u),v=S.polarToCartesian(n.centerX,n.centerY,n.donutSize,c),g=S.polarToCartesian(n.centerX,n.centerY,n.donutSize,s),m=i>180?1:0,y=["M",h,d,"A",a,a,0,m,1,f,p];return e="donut"===n.chartType?[].concat(y,["L",v.x,v.y,"A",n.donutSize,n.donutSize,0,m,0,g.x,g.y,"L",h,d,"z"]).join(" "):"pie"===n.chartType||"polarArea"===n.chartType?[].concat(y,["L",n.centerX,n.centerY,"L",h,d]).join(" "):[].concat(y).join(" "),o.roundPathCorners(e,2*this.strokeWidth)}},{key:"drawPolarElements",value:function(t){var e=this.w,n=new tt(this.ctx),r=new _(this.ctx),i=new Mt(this.ctx),a=r.group(),o=r.group(),s=n.niceScale(0,Math.ceil(this.maxY),0),l=s.result.reverse(),c=s.result.length;this.maxY=s.niceMax;for(var u=e.globals.radialSize,h=u/(c-1),d=0;d1&&t.total.show&&(i=t.total.color);var o=a.globals.dom.baseEl.querySelector(".apexcharts-datalabel-label"),s=a.globals.dom.baseEl.querySelector(".apexcharts-datalabel-value");n=(0,t.value.formatter)(n,a),r||"function"!=typeof t.total.formatter||(n=t.total.formatter(a));var l=e===t.total.label;e=this.donutDataLabels.total.label?t.name.formatter(e,l,a):"",null!==o&&(o.textContent=e),null!==s&&(s.textContent=n),null!==o&&(o.style.fill=i)}},{key:"printDataLabelsInner",value:function(t,e){var n=this.w,r=t.getAttribute("data:value"),i=n.globals.seriesNames[parseInt(t.parentNode.getAttribute("rel"),10)-1];n.globals.series.length>1&&this.printInnerLabels(e,i,r,t);var a=n.globals.dom.baseEl.querySelector(".apexcharts-datalabels-group");null!==a&&(a.style.opacity=1)}},{key:"drawSpokes",value:function(t){var e=this,n=this.w,r=new _(this.ctx),i=n.config.plotOptions.polarArea.spokes;if(0!==i.strokeWidth){for(var a=[],o=360/n.globals.series.length,s=0;s0&&(p=e.getPreviousPath(o));for(var v=0;v=10?t.x>0?(n="start",r+=10):t.x<0&&(n="end",r-=10):n="middle",Math.abs(t.y)>=e-10&&(t.y<0?i-=10:t.y>0&&(i+=10)),{textAnchor:n,newX:r,newY:i}}},{key:"getPreviousPath",value:function(t){for(var e=this.w,n=null,r=0;r0&&parseInt(i.realIndex,10)===parseInt(t,10)&&void 0!==e.globals.previousPaths[r].paths[0]&&(n=e.globals.previousPaths[r].paths[0].d)}return n}},{key:"getDataPointsPos",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.dataPointsLen;t=t||[],e=e||[];for(var r=[],i=0;i=360&&(d=360-Math.abs(this.startAngle)-.1);var f=n.drawPath({d:"",stroke:u,strokeWidth:o*parseInt(c.strokeWidth,10)/100,fill:"none",strokeOpacity:c.opacity,classes:"apexcharts-radialbar-area"});if(c.dropShadow.enabled){var p=c.dropShadow;i.dropShadow(f,p)}l.add(f),f.attr("id","apexcharts-radialbarTrack-"+s),this.animatePaths(f,{centerX:t.centerX,centerY:t.centerY,endAngle:d,startAngle:h,size:t.size,i:s,totalItems:2,animBeginArr:0,dur:0,isTrack:!0,easing:e.globals.easing})}return r}},{key:"drawArcs",value:function(t){var e=this.w,n=new _(this.ctx),r=new W(this.ctx),i=new A(this.ctx),a=n.group(),o=this.getStrokeWidth(t);t.size=t.size-o/2;var s=e.config.plotOptions.radialBar.hollow.background,l=t.size-o*t.series.length-this.margin*t.series.length-o*parseInt(e.config.plotOptions.radialBar.track.strokeWidth,10)/100/2,c=l-e.config.plotOptions.radialBar.hollow.margin;void 0!==e.config.plotOptions.radialBar.hollow.image&&(s=this.drawHollowImage(t,a,l,s));var u=this.drawHollow({size:c,centerX:t.centerX,centerY:t.centerY,fill:s||"transparent"});if(e.config.plotOptions.radialBar.hollow.dropShadow.enabled){var h=e.config.plotOptions.radialBar.hollow.dropShadow;i.dropShadow(u,h)}var d=1;!this.radialDataLabels.total.show&&e.globals.series.length>1&&(d=0);var f=null;if(this.radialDataLabels.show){var p=e.globals.dom.Paper.select(".apexcharts-datalabels-group").members[0];f=this.renderInnerDataLabels(p,this.radialDataLabels,{hollowSize:l,centerX:t.centerX,centerY:t.centerY,opacity:d})}"back"===e.config.plotOptions.radialBar.hollow.position&&(a.add(u),f&&a.add(f));var v=!1;e.config.plotOptions.radialBar.inverseOrder&&(v=!0);for(var g=v?t.series.length-1:0;v?g>=0:g100?100:t.series[g])/100,k=Math.round(this.totalAngle*w)+this.startAngle,C=void 0;e.globals.dataChanged&&(x=this.startAngle,C=Math.round(this.totalAngle*S.negToZero(e.globals.previousPaths[g])/100)+x),Math.abs(k)+Math.abs(b)>360&&(k-=.01),Math.abs(C)+Math.abs(x)>360&&(C-=.01);var D=k-b,T=Array.isArray(e.config.stroke.dashArray)?e.config.stroke.dashArray[g]:e.config.stroke.dashArray,E=n.drawPath({d:"",stroke:y,strokeWidth:o,fill:"none",fillOpacity:e.config.fill.opacity,classes:"apexcharts-radialbar-area apexcharts-radialbar-slice-"+g,strokeDashArray:T});if(_.setAttrs(E.node,{"data:angle":D,"data:value":t.series[g]}),e.config.chart.dropShadow.enabled){var O=e.config.chart.dropShadow;i.dropShadow(E,O,g)}if(i.setSelectionFilter(E,0,g),this.addListeners(E,this.radialDataLabels),m.add(E),E.attr({index:0,j:g}),this.barLabels.enabled){var P=S.polarToCartesian(t.centerX,t.centerY,t.size,b),I=this.barLabels.formatter(e.globals.seriesNames[g],{seriesIndex:g,w:e}),M=["apexcharts-radialbar-label"];this.barLabels.onClick||M.push("apexcharts-no-click");var V=this.barLabels.useSeriesColors?e.globals.colors[g]:e.config.chart.foreColor;V||(V=e.config.chart.foreColor);var L=P.x+this.barLabels.offsetX,j=P.y+this.barLabels.offsetY,B=n.drawText({x:L,y:j,text:I,textAnchor:"end",dominantBaseline:"middle",fontFamily:this.barLabels.fontFamily,fontWeight:this.barLabels.fontWeight,fontSize:this.barLabels.fontSize,foreColor:V,cssClass:M.join(" ")});B.on("click",this.onBarLabelClick),B.attr({rel:g+1}),0!==b&&B.attr({"transform-origin":"".concat(L," ").concat(j),transform:"rotate(".concat(b," 0 0)")}),m.add(B)}var R=0;!this.initialAnim||e.globals.resized||e.globals.dataChanged||(R=e.config.chart.animations.speed),e.globals.dataChanged&&(R=e.config.chart.animations.dynamicAnimation.speed),this.animDur=R/(1.2*t.series.length)+this.animDur,this.animBeginArr.push(this.animDur),this.animatePaths(E,{centerX:t.centerX,centerY:t.centerY,endAngle:k,startAngle:b,prevEndAngle:C,prevStartAngle:x,size:t.size,i:g,totalItems:2,animBeginArr:this.animBeginArr,dur:R,shouldSetPrevPaths:!0,easing:e.globals.easing})}return{g:a,elHollow:u,dataLabels:f}}},{key:"drawHollow",value:function(t){var e=new _(this.ctx).drawCircle(2*t.size);return e.attr({class:"apexcharts-radialbar-hollow",cx:t.centerX,cy:t.centerY,r:t.size,fill:t.fill}),e}},{key:"drawHollowImage",value:function(t,e,n,r){var i=this.w,a=new W(this.ctx),o=S.randomId(),s=i.config.plotOptions.radialBar.hollow.image;if(i.config.plotOptions.radialBar.hollow.imageClipped)a.clippedImgArea({width:n,height:n,image:s,patternID:"pattern".concat(i.globals.cuid).concat(o)}),r="url(#pattern".concat(i.globals.cuid).concat(o,")");else{var l=i.config.plotOptions.radialBar.hollow.imageWidth,c=i.config.plotOptions.radialBar.hollow.imageHeight;if(void 0===l&&void 0===c){var u=i.globals.dom.Paper.image(s).loaded((function(e){this.move(t.centerX-e.width/2+i.config.plotOptions.radialBar.hollow.imageOffsetX,t.centerY-e.height/2+i.config.plotOptions.radialBar.hollow.imageOffsetY)}));e.add(u)}else{var h=i.globals.dom.Paper.image(s).loaded((function(e){this.move(t.centerX-l/2+i.config.plotOptions.radialBar.hollow.imageOffsetX,t.centerY-c/2+i.config.plotOptions.radialBar.hollow.imageOffsetY),this.size(l,c)}));e.add(h)}}return r}},{key:"getStrokeWidth",value:function(t){var e=this.w;return t.size*(100-parseInt(e.config.plotOptions.radialBar.hollow.size,10))/100/(t.series.length+1)-this.margin}},{key:"onBarLabelClick",value:function(t){var e=parseInt(t.target.getAttribute("rel"),10)-1,n=this.barLabels.onClick,r=this.w;n&&n(r.globals.seriesNames[e],{w:r,seriesIndex:e})}}]),n}(Vt),Bt=function(t){f(n,t);var e=u(n);function n(){return o(this,n),e.apply(this,arguments)}return l(n,[{key:"draw",value:function(t,e){var n=this.w,r=new _(this.ctx);this.rangeBarOptions=this.w.config.plotOptions.rangeBar,this.series=t,this.seriesRangeStart=n.globals.seriesRangeStart,this.seriesRangeEnd=n.globals.seriesRangeEnd,this.barHelpers.initVariables(t);for(var i=r.group({class:"apexcharts-rangebar-series apexcharts-plot-series"}),a=0;a0&&(this.visibleI=this.visibleI+1);var v=0,m=0,y=0;this.yRatio.length>1&&(this.yaxisIndex=n.globals.seriesYAxisReverseMap[d][0],y=d);var b=this.barHelpers.initialPositions();h=b.y,c=b.zeroW,u=b.x,m=b.barWidth,v=b.barHeight,o=b.xDivision,s=b.yDivision,l=b.zeroH;for(var x=r.group({class:"apexcharts-datalabels","data:realIndex":d}),w=r.group({class:"apexcharts-rangebar-goals-markers"}),k=0;k0}));return this.isHorizontal?(r=d.config.plotOptions.bar.rangeBarGroupRows?a+c*m:a+s*this.visibleI+c*m,y>-1&&!d.config.plotOptions.bar.rangeBarOverlap&&(f=d.globals.seriesRange[e][y].overlaps).indexOf(p)>-1&&(r=(s=h.barHeight/f.length)*this.visibleI+c*(100-parseInt(this.barOptions.barHeight,10))/100/2+s*(this.visibleI+f.indexOf(p))+c*m)):(m>-1&&!d.globals.timescaleLabels.length&&(i=d.config.plotOptions.bar.rangeBarGroupRows?o+u*m:o+l*this.visibleI+u*m),y>-1&&!d.config.plotOptions.bar.rangeBarOverlap&&(f=d.globals.seriesRange[e][y].overlaps).indexOf(p)>-1&&(i=(l=h.barWidth/f.length)*this.visibleI+u*(100-parseInt(this.barOptions.barWidth,10))/100/2+l*(this.visibleI+f.indexOf(p))+u*m)),{barYPosition:r,barXPosition:i,barHeight:s,barWidth:l}}},{key:"drawRangeColumnPaths",value:function(t){var e=t.indexes,n=t.x,r=t.xDivision,i=t.barWidth,a=t.barXPosition,o=t.zeroH,s=this.w,l=e.i,c=e.j,u=e.realIndex,h=e.translationsIndex,d=this.yRatio[h],f=this.getRangeValue(u,c),p=Math.min(f.start,f.end),v=Math.max(f.start,f.end);void 0===this.series[l][c]||null===this.series[l][c]?p=o:(p=o-p/d,v=o-v/d);var g=Math.abs(v-p),m=this.barHelpers.getColumnPaths({barXPosition:a,barWidth:i,y1:p,y2:v,strokeWidth:this.strokeWidth,series:this.seriesRangeEnd,realIndex:u,i:u,j:c,w:s});if(s.globals.isXNumeric){var y=this.getBarXForNumericXAxis({x:n,j:c,realIndex:u,barWidth:i});n=y.x,a=y.barXPosition}else n+=r;return{pathTo:m.pathTo,pathFrom:m.pathFrom,barHeight:g,x:n,y:f.start<0&&f.end<0?p:v,goalY:this.barHelpers.getGoalValues("y",null,o,l,c,h),barXPosition:a}}},{key:"preventBarOverflow",value:function(t){var e=this.w;return t<0&&(t=0),t>e.globals.gridWidth&&(t=e.globals.gridWidth),t}},{key:"drawRangeBarPaths",value:function(t){var e=t.indexes,n=t.y,r=t.y1,i=t.y2,a=t.yDivision,o=t.barHeight,s=t.barYPosition,l=t.zeroW,c=this.w,u=e.realIndex,h=e.j,d=this.preventBarOverflow(l+r/this.invertedYRatio),f=this.preventBarOverflow(l+i/this.invertedYRatio),p=this.getRangeValue(u,h),v=Math.abs(f-d),g=this.barHelpers.getBarpaths({barYPosition:s,barHeight:o,x1:d,x2:f,strokeWidth:this.strokeWidth,series:this.seriesRangeEnd,i:u,realIndex:u,j:h,w:c});return c.globals.isXNumeric||(n+=a),{pathTo:g.pathTo,pathFrom:g.pathFrom,barWidth:v,x:p.start<0&&p.end<0?d:f,goalX:this.barHelpers.getGoalValues("x",l,null,u,h),y:n}}},{key:"getRangeValue",value:function(t,e){var n=this.w;return{start:n.globals.seriesRangeStart[t][e],end:n.globals.seriesRangeEnd[t][e]}}}]),n}(Tt),Rt=function(){function t(e){o(this,t),this.w=e.w,this.lineCtx=e}return l(t,[{key:"sameValueSeriesFix",value:function(t,e){var n=this.w;if(("gradient"===n.config.fill.type||"gradient"===n.config.fill.type[t])&&new D(this.lineCtx.ctx,n).seriesHaveSameValues(t)){var r=e[t].slice();r[r.length-1]=r[r.length-1]+1e-6,e[t]=r}return e}},{key:"calculatePoints",value:function(t){var e=t.series,n=t.realIndex,r=t.x,i=t.y,a=t.i,o=t.j,s=t.prevY,l=this.w,c=[],u=[];if(0===o){var h=this.lineCtx.categoryAxisCorrection+l.config.markers.offsetX;l.globals.isXNumeric&&(h=(l.globals.seriesX[n][0]-l.globals.minX)/this.lineCtx.xRatio+l.config.markers.offsetX),c.push(h),u.push(S.isNumber(e[a][0])?s+l.config.markers.offsetY:null),c.push(r+l.config.markers.offsetX),u.push(S.isNumber(e[a][o+1])?i+l.config.markers.offsetY:null)}else c.push(r+l.config.markers.offsetX),u.push(S.isNumber(e[a][o+1])?i+l.config.markers.offsetY:null);return{x:c,y:u}}},{key:"checkPreviousPaths",value:function(t){for(var e=t.pathFromLine,n=t.pathFromArea,r=t.realIndex,i=this.w,a=0;a0&&parseInt(o.realIndex,10)===parseInt(r,10)&&("line"===o.type?(this.lineCtx.appendPathFrom=!1,e=i.globals.previousPaths[a].paths[0].d):"area"===o.type&&(this.lineCtx.appendPathFrom=!1,n=i.globals.previousPaths[a].paths[0].d,i.config.stroke.show&&i.globals.previousPaths[a].paths[1]&&(e=i.globals.previousPaths[a].paths[1].d)))}return{pathFromLine:e,pathFromArea:n}}},{key:"determineFirstPrevY",value:function(t){var e,n,r,i=t.i,a=t.realIndex,o=t.series,s=t.prevY,l=t.lineYPosition,c=t.translationsIndex,u=this.w,h=u.config.chart.stacked&&!u.globals.comboCharts||u.config.chart.stacked&&u.globals.comboCharts&&(!this.w.config.chart.stackOnlyBar||"bar"===(null===(e=this.w.config.series[a])||void 0===e?void 0:e.type)||"column"===(null===(n=this.w.config.series[a])||void 0===n?void 0:n.type));if(void 0!==(null===(r=o[i])||void 0===r?void 0:r[0]))s=(l=h&&i>0?this.lineCtx.prevSeriesY[i-1][0]:this.lineCtx.zeroY)-o[i][0]/this.lineCtx.yRatio[c]+2*(this.lineCtx.isReversed?o[i][0]/this.lineCtx.yRatio[c]:0);else if(h&&i>0&&void 0===o[i][0])for(var d=i-1;d>=0;d--)if(null!==o[d][0]&&void 0!==o[d][0]){s=l=this.lineCtx.prevSeriesY[d][0];break}return{prevY:s,lineYPosition:l}}}]),t}(),Ft=function(t){for(var e,n,r,i,a=function(t){for(var e=[],n=t[0],r=t[1],i=e[0]=$t(n,r),a=1,o=t.length-1;a9&&(i=3*r/Math.sqrt(i),a[l]=i*e,a[l+1]=i*n);for(var c=0;c<=o;c++)i=(t[Math.min(o,c+1)][0]-t[Math.max(0,c-1)][0])/(6*(1+a[c]*a[c])),s.push([i||0,a[c]*i||0]);return s},Nt=function(t){var e=Ft(t),n=t[1],r=t[0],i=[],a=e[1],o=e[0];i.push(r,[r[0]+o[0],r[1]+o[1],n[0]-a[0],n[1]-a[1],n[0],n[1]]);for(var s=2,l=e.length;s1&&r[1].length<6){var i=r[0].length;r[1]=[2*r[0][i-2]-r[0][i-4],2*r[0][i-1]-r[0][i-3]].concat(r[1])}r[0]=r[0].slice(-2)}return r};function $t(t,e){return(e[1]-t[1])/(e[0]-t[0])}var Yt=function(){function t(e,n,r){o(this,t),this.ctx=e,this.w=e.w,this.xyRatios=n,this.pointsChart=!("bubble"!==this.w.config.chart.type&&"scatter"!==this.w.config.chart.type)||r,this.scatter=new G(this.ctx),this.noNegatives=this.w.globals.minX===Number.MAX_VALUE,this.lineHelpers=new Rt(this),this.markers=new X(this.ctx),this.prevSeriesY=[],this.categoryAxisCorrection=0,this.yaxisIndex=0}return l(t,[{key:"draw",value:function(t,e,n,r){var i,a=this.w,o=new _(this.ctx),s=a.globals.comboCharts?e:a.config.chart.type,l=o.group({class:"apexcharts-".concat(s,"-series apexcharts-plot-series")}),c=new D(this.ctx,a);this.yRatio=this.xyRatios.yRatio,this.zRatio=this.xyRatios.zRatio,this.xRatio=this.xyRatios.xRatio,this.baseLineY=this.xyRatios.baseLineY,t=c.getLogSeries(t),this.yRatio=c.getLogYRatios(this.yRatio),this.prevSeriesY=[];for(var u=[],h=0;h1?d:0;this._initSerieVariables(t,h,d);var p=[],v=[],m=[],y=a.globals.padHorizontal+this.categoryAxisCorrection;this.ctx.series.addCollapsedClassToSeries(this.elSeries,d),a.globals.isXNumeric&&a.globals.seriesX.length>0&&(y=(a.globals.seriesX[d][0]-a.globals.minX)/this.xRatio),m.push(y);var b,x=y,w=void 0,k=x,S=this.zeroY,C=this.zeroY;S=this.lineHelpers.determineFirstPrevY({i:h,realIndex:d,series:t,prevY:S,lineYPosition:0,translationsIndex:f}).prevY,"monotoneCubic"===a.config.stroke.curve&&null===t[h][0]?p.push(null):p.push(S),b=S,"rangeArea"===s&&(w=C=this.lineHelpers.determineFirstPrevY({i:h,realIndex:d,series:r,prevY:C,lineYPosition:0,translationsIndex:f}).prevY,v.push(null!==p[0]?C:null));var A=this._calculatePathsFrom({type:s,series:t,i:h,realIndex:d,translationsIndex:f,prevX:k,prevY:S,prevY2:C}),T=[p[0]],E=[v[0]],O={type:s,series:t,realIndex:d,translationsIndex:f,i:h,x:y,y:1,pX:x,pY:b,pathsFrom:A,linePaths:[],areaPaths:[],seriesIndex:n,lineYPosition:0,xArrj:m,yArrj:p,y2Arrj:v,seriesRangeEnd:r},P=this._iterateOverDataPoints(g(g({},O),{},{iterations:"rangeArea"===s?t[h].length-1:void 0,isRangeStart:!0}));if("rangeArea"===s){for(var I=this._calculatePathsFrom({series:r,i:h,realIndex:d,prevX:k,prevY:C}),M=this._iterateOverDataPoints(g(g({},O),{},{series:r,xArrj:[y],yArrj:T,y2Arrj:E,pY:w,areaPaths:P.areaPaths,pathsFrom:I,iterations:r[h].length-1,isRangeStart:!1})),V=P.linePaths.length/2,L=0;L=0;j--)l.add(u[j]);else for(var B=0;B1&&(this.yaxisIndex=r.globals.seriesYAxisReverseMap[n],a=n),this.isReversed=r.config.yaxis[this.yaxisIndex]&&r.config.yaxis[this.yaxisIndex].reversed,this.zeroY=r.globals.gridHeight-this.baseLineY[a]-(this.isReversed?r.globals.gridHeight:0)+(this.isReversed?2*this.baseLineY[a]:0),this.areaBottomY=this.zeroY,(this.zeroY>r.globals.gridHeight||"end"===r.config.plotOptions.area.fillTo)&&(this.areaBottomY=r.globals.gridHeight),this.categoryAxisCorrection=this.xDivision/2,this.elSeries=i.group({class:"apexcharts-series",zIndex:void 0!==r.config.series[n].zIndex?r.config.series[n].zIndex:n,seriesName:S.escapeString(r.globals.seriesNames[n])}),this.elPointsMain=i.group({class:"apexcharts-series-markers-wrap","data:realIndex":n}),this.elDataLabelsWrap=i.group({class:"apexcharts-datalabels","data:realIndex":n});var o=t[e].length===r.globals.dataPoints;this.elSeries.attr({"data:longestSeries":o,rel:e+1,"data:realIndex":n}),this.appendPathFrom=!0}},{key:"_calculatePathsFrom",value:function(t){var e,n,r,i,a=t.type,o=t.series,s=t.i,l=t.realIndex,c=t.translationsIndex,u=t.prevX,h=t.prevY,d=t.prevY2,f=this.w,p=new _(this.ctx);if(null===o[s][0]){for(var v=0;v0){var g=this.lineHelpers.checkPreviousPaths({pathFromLine:r,pathFromArea:i,realIndex:l});r=g.pathFromLine,i=g.pathFromArea}return{prevX:u,prevY:h,linePath:e,areaPath:n,pathFromLine:r,pathFromArea:i}}},{key:"_handlePaths",value:function(t){var e=t.type,n=t.realIndex,r=t.i,i=t.paths,a=this.w,o=new _(this.ctx),s=new W(this.ctx);this.prevSeriesY.push(i.yArrj),a.globals.seriesXvalues[n]=i.xArrj,a.globals.seriesYvalues[n]=i.yArrj;var l=a.config.forecastDataPoints;if(l.count>0&&"rangeArea"!==e){var c=a.globals.seriesXvalues[n][a.globals.seriesXvalues[n].length-l.count-1],u=o.drawRect(c,0,a.globals.gridWidth,a.globals.gridHeight,0);a.globals.dom.elForecastMask.appendChild(u.node);var h=o.drawRect(0,0,c,a.globals.gridHeight,0);a.globals.dom.elNonForecastMask.appendChild(h.node)}this.pointsChart||a.globals.delayedElements.push({el:this.elPointsMain.node,index:n});var d={i:r,realIndex:n,animationDelay:r,initialSpeed:a.config.chart.animations.speed,dataChangeSpeed:a.config.chart.animations.dynamicAnimation.speed,className:"apexcharts-".concat(e)};if("area"===e)for(var f=s.fillPath({seriesNumber:n}),p=0;p0&&"rangeArea"!==e){var S=o.renderPaths(w);S.node.setAttribute("stroke-dasharray",l.dashArray),l.strokeWidth&&S.node.setAttribute("stroke-width",l.strokeWidth),this.elSeries.add(S),S.attr("clip-path","url(#forecastMask".concat(a.globals.cuid,")")),k.attr("clip-path","url(#nonForecastMask".concat(a.globals.cuid,")"))}}}}},{key:"_iterateOverDataPoints",value:function(t){var e,n,r=this,i=t.type,a=t.series,o=t.iterations,s=t.realIndex,l=t.translationsIndex,c=t.i,u=t.x,h=t.y,d=t.pX,f=t.pY,p=t.pathsFrom,v=t.linePaths,g=t.areaPaths,m=t.seriesIndex,y=t.lineYPosition,b=t.xArrj,x=t.yArrj,w=t.y2Arrj,k=t.isRangeStart,C=t.seriesRangeEnd,A=this.w,D=new _(this.ctx),T=this.yRatio,E=p.prevY,O=p.linePath,P=p.areaPath,I=p.pathFromLine,M=p.pathFromArea,V=S.isNumber(A.globals.minYArr[s])?A.globals.minYArr[s]:A.globals.minY;o||(o=A.globals.dataPoints>1?A.globals.dataPoints-1:A.globals.dataPoints);var L=function(t,e){return e-t/T[l]+2*(r.isReversed?t/T[l]:0)},j=h,B=A.config.chart.stacked&&!A.globals.comboCharts||A.config.chart.stacked&&A.globals.comboCharts&&(!this.w.config.chart.stackOnlyBar||"bar"===(null===(e=this.w.config.series[s])||void 0===e?void 0:e.type)||"column"===(null===(n=this.w.config.series[s])||void 0===n?void 0:n.type)),R=A.config.stroke.curve;Array.isArray(R)&&(R=Array.isArray(m)?R[m[c]]:R[c]);for(var F,N=0,z=0;z0&&A.globals.collapsedSeries.length0;e--){if(!(A.globals.collapsedSeriesIndices.indexOf((null==m?void 0:m[e])||e)>-1))return e;e--}return 0}(c-1)][z+1]:this.zeroY,$?h=L(V,y):(h=L(a[c][z+1],y),"rangeArea"===i&&(j=L(C[c][z+1],y))),b.push(u),!$||"smooth"!==A.config.stroke.curve&&"monotoneCubic"!==A.config.stroke.curve?(x.push(h),w.push(j)):(x.push(null),w.push(null));var H=this.lineHelpers.calculatePoints({series:a,x:u,y:h,realIndex:s,i:c,j:z,prevY:E}),W=this._createPaths({type:i,series:a,i:c,realIndex:s,j:z,x:u,y:h,y2:j,xArrj:b,yArrj:x,y2Arrj:w,pX:d,pY:f,pathState:N,segmentStartX:F,linePath:O,areaPath:P,linePaths:v,areaPaths:g,curve:R,isRangeStart:k});g=W.areaPaths,v=W.linePaths,d=W.pX,f=W.pY,N=W.pathState,F=W.segmentStartX,P=W.areaPath,O=W.linePath,!this.appendPathFrom||"monotoneCubic"===R&&"rangeArea"===i||(I+=D.line(u,this.zeroY),M+=D.line(u,this.zeroY)),this.handleNullDataPoints(a,H,c,z,s),this._handleMarkersAndLabels({type:i,pointsPos:H,i:c,j:z,realIndex:s,isRangeStart:k})}return{yArrj:x,xArrj:b,pathFromArea:M,areaPaths:g,pathFromLine:I,linePaths:v,linePath:O,areaPath:P}}},{key:"_handleMarkersAndLabels",value:function(t){var e=t.type,n=t.pointsPos,r=t.isRangeStart,i=t.i,a=t.j,o=t.realIndex,s=this.w,l=new U(this.ctx);if(this.pointsChart)this.scatter.draw(this.elSeries,a,{realIndex:o,pointsPos:n,zRatio:this.zRatio,elParent:this.elPointsMain});else{s.globals.series[i].length>1&&this.elPointsMain.node.classList.add("apexcharts-element-hidden");var c=this.markers.plotChartMarkers(n,o,a+1);null!==c&&this.elPointsMain.add(c)}var u=l.drawDataLabel({type:e,isRangeStart:r,pos:n,i:o,j:a+1});null!==u&&this.elDataLabelsWrap.add(u)}},{key:"_createPaths",value:function(t){var e=t.type,n=t.series,r=t.i;t.realIndex;var i,a=t.j,o=t.x,s=t.y,l=t.xArrj,c=t.yArrj,u=t.y2,h=t.y2Arrj,d=t.pX,f=t.pY,p=t.pathState,v=t.segmentStartX,g=t.linePath,m=t.areaPath,y=t.linePaths,b=t.areaPaths,x=t.curve,w=t.isRangeStart,k=new _(this.ctx),S=this.areaBottomY,C="rangeArea"===e,A="rangeArea"===e&&w;switch(x){case"monotoneCubic":var D=w?c:h;switch(p){case 0:if(null===D[a+1])break;p=1;case 1:if(!(C?l.length===n[r].length:a===n[r].length-2))break;case 2:var T=w?l:l.slice().reverse(),E=w?D:D.slice().reverse(),O=(i=E,T.map((function(t,e){return[t,i[e]]})).filter((function(t){return null!==t[1]}))),P=O.length>1?Nt(O):O,I=[];C&&(A?b=O:I=b.reverse());var M=0,V=0;if(function(t,e){for(var n=function(t){var e=[],n=0;return t.forEach((function(t){null!==t?n++:n>0&&(e.push(n),n=0)})),n>0&&e.push(n),e}(t),r=[],i=0,a=0;i4?(e+="C".concat(r[0],", ").concat(r[1]),e+=", ".concat(r[2],", ").concat(r[3]),e+=", ".concat(r[4],", ").concat(r[5])):i>2&&(e+="S".concat(r[0],", ").concat(r[1]),e+=", ".concat(r[2],", ").concat(r[3]))}return e}(t),n=V,r=(V+=t.length)-1;A?g=k.move(O[n][0],O[n][1])+e:C?g=k.move(I[n][0],I[n][1])+k.line(O[n][0],O[n][1])+e+k.line(I[r][0],I[r][1]):(g=k.move(O[n][0],O[n][1])+e,m=g+k.line(O[r][0],S)+k.line(O[n][0],S)+"z",b.push(m)),y.push(g)})),C&&M>1&&!A){var L=y.slice(M).reverse();y.splice(M),L.forEach((function(t){return y.push(t)}))}p=0}break;case"smooth":var j=.35*(o-d);if(null===n[r][a])p=0;else switch(p){case 0:if(v=d,g=A?k.move(d,h[a])+k.line(d,f):k.move(d,f),m=k.move(d,f),null===n[r][a+1]){y.push(g),b.push(m);break}if(p=1,a=n[r].length-2&&(A&&(g+=k.curve(o,s,o,s,o,u)+k.move(o,u)),m+=k.curve(o,s,o,s,o,S)+k.line(v,S)+"z",y.push(g),b.push(m),p=-1)}}d=o,f=s;break;default:var F=function(t,e,n){var r=[];switch(t){case"stepline":r=k.line(e,null,"H")+k.line(null,n,"V");break;case"linestep":r=k.line(null,n,"V")+k.line(e,null,"H");break;case"straight":r=k.line(e,n)}return r};if(null===n[r][a])p=0;else switch(p){case 0:if(v=d,g=A?k.move(d,h[a])+k.line(d,f):k.move(d,f),m=k.move(d,f),null===n[r][a+1]){y.push(g),b.push(m);break}if(p=1,a=n[r].length-2&&(A&&(g+=k.line(o,u)),m+=k.line(o,S)+k.line(v,S)+"z",y.push(g),b.push(m),p=-1)}}d=o,f=s}return{linePaths:y,areaPaths:b,pX:d,pY:f,pathState:p,segmentStartX:v,linePath:g,areaPath:m}}},{key:"handleNullDataPoints",value:function(t,e,n,r,i){var a=this.w;if(null===t[n][r]&&a.config.markers.showNullDataPoints||1===t[n].length){var o=this.strokeWidth-a.config.markers.strokeWidth/2;o>0||(o=0);var s=this.markers.plotChartMarkers(e,i,r+1,o,!0);null!==s&&this.elPointsMain.add(s)}}}]),t}();window.TreemapSquared={},window.TreemapSquared.generate=function(){function t(e,n,r,i){this.xoffset=e,this.yoffset=n,this.height=i,this.width=r,this.shortestEdge=function(){return Math.min(this.height,this.width)},this.getCoordinates=function(t){var e,n=[],r=this.xoffset,i=this.yoffset,o=a(t)/this.height,s=a(t)/this.width;if(this.width>=this.height)for(e=0;e=this.height){var r=e/this.height,i=this.width-r;n=new t(this.xoffset+r,this.yoffset,i,this.height)}else{var a=e/this.width,o=this.height-a;n=new t(this.xoffset,this.yoffset+a,this.width,o)}return n}}function e(e,r,i,o,s){o=void 0===o?0:o,s=void 0===s?0:s;var l=n(function(t,e){var n,r=[],i=e/a(t);for(n=0;n=o}(e,l=t[0],s)?(e.push(l),n(t.slice(1),e,i,o)):(c=i.cutArea(a(e),o),o.push(i.getCoordinates(e)),n(t,[],c,o)),o;o.push(i.getCoordinates(e))}function r(t,e){var n=Math.min.apply(Math,t),r=Math.max.apply(Math,t),i=a(t);return Math.max(Math.pow(e,2)*r/Math.pow(i,2),Math.pow(i,2)/(Math.pow(e,2)*n))}function i(t){return t&&t.constructor===Array}function a(t){var e,n=0;for(e=0;ea-r&&l.width<=o-i){var c=s.rotateAroundCenter(t.node);t.node.setAttribute("transform","rotate(-90 ".concat(c.x," ").concat(c.y,") translate(").concat(l.height/3,")"))}}},{key:"truncateLabels",value:function(t,e,n,r,i,a){var o=new _(this.ctx),s=o.getTextRects(t,e).width+this.w.config.stroke.width+5>i-n&&a-r>i-n?a-r:i-n,l=o.getTextBasedOnMaxWidth({text:t,maxWidth:s,fontSize:e});return t.length!==l.length&&s/e<5?"":l}},{key:"animateTreemap",value:function(t,e,n,r){var i=new C(this.ctx);i.animateRect(t,{x:e.x,y:e.y,width:e.width,height:e.height},{x:n.x,y:n.y,width:n.width,height:n.height},r,(function(){i.animationCompleted(t)}))}}]),t}(),Gt=86400,Ut=10/Gt,qt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w,this.timeScaleArray=[],this.utc=this.w.config.xaxis.labels.datetimeUTC}return l(t,[{key:"calculateTimeScaleTicks",value:function(t,e){var n=this,r=this.w;if(r.globals.allSeriesCollapsed)return r.globals.labels=[],r.globals.timescaleLabels=[],[];var i=new O(this.ctx),a=(e-t)/864e5;this.determineInterval(a),r.globals.disableZoomIn=!1,r.globals.disableZoomOut=!1,a5e4&&(r.globals.disableZoomOut=!0);var o=i.getTimeUnitsfromTimestamp(t,e,this.utc),s=r.globals.gridWidth/a,l=s/24,c=l/60,u=c/60,h=Math.floor(24*a),d=Math.floor(1440*a),f=Math.floor(a*Gt),p=Math.floor(a),v=Math.floor(a/30),m=Math.floor(a/365),y={minMillisecond:o.minMillisecond,minSecond:o.minSecond,minMinute:o.minMinute,minHour:o.minHour,minDate:o.minDate,minMonth:o.minMonth,minYear:o.minYear},b={firstVal:y,currentMillisecond:y.minMillisecond,currentSecond:y.minSecond,currentMinute:y.minMinute,currentHour:y.minHour,currentMonthDate:y.minDate,currentDate:y.minDate,currentMonth:y.minMonth,currentYear:y.minYear,daysWidthOnXAxis:s,hoursWidthOnXAxis:l,minutesWidthOnXAxis:c,secondsWidthOnXAxis:u,numberOfSeconds:f,numberOfMinutes:d,numberOfHours:h,numberOfDays:p,numberOfMonths:v,numberOfYears:m};switch(this.tickInterval){case"years":this.generateYearScale(b);break;case"months":case"half_year":this.generateMonthScale(b);break;case"months_days":case"months_fortnight":case"days":case"week_days":this.generateDayScale(b);break;case"hours":this.generateHourScale(b);break;case"minutes_fives":case"minutes":this.generateMinuteScale(b);break;case"seconds_tens":case"seconds_fives":case"seconds":this.generateSecondScale(b)}var x=this.timeScaleArray.map((function(t){var e={position:t.position,unit:t.unit,year:t.year,day:t.day?t.day:1,hour:t.hour?t.hour:0,month:t.month+1};return"month"===t.unit?g(g({},e),{},{day:1,value:t.value+1}):"day"===t.unit||"hour"===t.unit?g(g({},e),{},{value:t.value}):"minute"===t.unit?g(g({},e),{},{value:t.value,minute:t.value}):"second"===t.unit?g(g({},e),{},{value:t.value,minute:t.minute,second:t.second}):t}));return x.filter((function(t){var e=1,i=Math.ceil(r.globals.gridWidth/120),a=t.value;void 0!==r.config.xaxis.tickAmount&&(i=r.config.xaxis.tickAmount),x.length>i&&(e=Math.floor(x.length/i));var o=!1,s=!1;switch(n.tickInterval){case"years":"year"===t.unit&&(o=!0);break;case"half_year":e=7,"year"===t.unit&&(o=!0);break;case"months":e=1,"year"===t.unit&&(o=!0);break;case"months_fortnight":e=15,"year"!==t.unit&&"month"!==t.unit||(o=!0),30===a&&(s=!0);break;case"months_days":e=10,"month"===t.unit&&(o=!0),30===a&&(s=!0);break;case"week_days":e=8,"month"===t.unit&&(o=!0);break;case"days":e=1,"month"===t.unit&&(o=!0);break;case"hours":"day"===t.unit&&(o=!0);break;case"minutes_fives":case"seconds_fives":a%5!=0&&(s=!0);break;case"seconds_tens":a%10!=0&&(s=!0)}if("hours"===n.tickInterval||"minutes_fives"===n.tickInterval||"seconds_tens"===n.tickInterval||"seconds_fives"===n.tickInterval){if(!s)return!0}else if((a%e==0||o)&&!s)return!0}))}},{key:"recalcDimensionsBasedOnFormat",value:function(t,e){var n=this.w,r=this.formatDates(t),i=this.removeOverlappingTS(r);n.globals.timescaleLabels=i.slice(),new pt(this.ctx).plotCoords()}},{key:"determineInterval",value:function(t){var e=24*t,n=60*e;switch(!0){case t/365>5:this.tickInterval="years";break;case t>800:this.tickInterval="half_year";break;case t>180:this.tickInterval="months";break;case t>90:this.tickInterval="months_fortnight";break;case t>60:this.tickInterval="months_days";break;case t>30:this.tickInterval="week_days";break;case t>2:this.tickInterval="days";break;case e>2.4:this.tickInterval="hours";break;case n>15:this.tickInterval="minutes_fives";break;case n>5:this.tickInterval="minutes";break;case n>1:this.tickInterval="seconds_tens";break;case 60*n>20:this.tickInterval="seconds_fives";break;default:this.tickInterval="seconds"}}},{key:"generateYearScale",value:function(t){var e=t.firstVal,n=t.currentMonth,r=t.currentYear,i=t.daysWidthOnXAxis,a=t.numberOfYears,o=e.minYear,s=0,l=new O(this.ctx),c="year";if(e.minDate>1||e.minMonth>0){var u=l.determineRemainingDaysOfYear(e.minYear,e.minMonth,e.minDate);s=(l.determineDaysOfYear(e.minYear)-u+1)*i,o=e.minYear+1,this.timeScaleArray.push({position:s,value:o,unit:c,year:o,month:S.monthMod(n+1)})}else 1===e.minDate&&0===e.minMonth&&this.timeScaleArray.push({position:s,value:o,unit:c,year:r,month:S.monthMod(n+1)});for(var h=o,d=s,f=0;f1){l=(c.determineDaysOfMonths(r+1,e.minYear)-n+1)*a,s=S.monthMod(r+1);var d=i+h,f=S.monthMod(s),p=s;0===s&&(u="year",p=d,f=1,d+=h+=1),this.timeScaleArray.push({position:l,value:p,unit:u,year:d,month:f})}else this.timeScaleArray.push({position:l,value:s,unit:u,year:i,month:S.monthMod(r)});for(var v=s+1,g=l,m=0,y=1;mo.determineDaysOfMonths(e+1,n)?(c=1,s="month",d=e+=1,e):e},h=(24-e.minHour)*i,d=l,f=u(c,n,r);0===e.minHour&&1===e.minDate?(h=0,d=S.monthMod(e.minMonth),s="month",c=e.minDate):1!==e.minDate&&0===e.minHour&&0===e.minMinute&&(h=0,l=e.minDate,d=l,f=u(c=l,n,r)),this.timeScaleArray.push({position:h,value:d,unit:s,year:this._getYear(r,f,0),month:S.monthMod(f),day:c});for(var p=h,v=0;vs.determineDaysOfMonths(e+1,i)&&(v=1,e+=1),{month:e,date:v}},u=function(t,e){return t>s.determineDaysOfMonths(e+1,i)?e+=1:e},h=60-(e.minMinute+e.minSecond/60),d=h*a,f=e.minHour+1,p=f;60===h&&(d=0,p=f=e.minHour);var v=n;p>=24&&(p=0,v+=1,l="day");var g=c(v,r).month;g=u(v,g),this.timeScaleArray.push({position:d,value:f,unit:l,day:v,hour:p,year:i,month:S.monthMod(g)}),p++;for(var m=d,y=0;y=24&&(p=0,l="day",g=c(v+=1,g).month,g=u(v,g));var b=this._getYear(i,g,0);m=60*a+m;var x=0===p?v:p;this.timeScaleArray.push({position:m,value:x,unit:l,hour:p,day:v,year:b,month:S.monthMod(g)}),p++}}},{key:"generateMinuteScale",value:function(t){for(var e=t.currentMillisecond,n=t.currentSecond,r=t.currentMinute,i=t.currentHour,a=t.currentDate,o=t.currentMonth,s=t.currentYear,l=t.minutesWidthOnXAxis,c=t.secondsWidthOnXAxis,u=t.numberOfMinutes,h=r+1,d=a,f=o,p=s,v=i,g=(60-n-e/1e3)*c,m=0;m=60&&(h=0,24===(v+=1)&&(v=0)),this.timeScaleArray.push({position:g,value:h,unit:"minute",hour:v,minute:h,day:d,year:this._getYear(p,f,0),month:S.monthMod(f)}),g+=l,h++}},{key:"generateSecondScale",value:function(t){for(var e=t.currentMillisecond,n=t.currentSecond,r=t.currentMinute,i=t.currentHour,a=t.currentDate,o=t.currentMonth,s=t.currentYear,l=t.secondsWidthOnXAxis,c=t.numberOfSeconds,u=n+1,h=r,d=a,f=o,p=s,v=i,g=(1e3-e)/1e3*l,m=0;m=60&&(u=0,++h>=60&&(h=0,24===++v&&(v=0))),this.timeScaleArray.push({position:g,value:u,unit:"second",hour:v,minute:h,second:u,day:d,year:this._getYear(p,f,0),month:S.monthMod(f)}),g+=l,u++}},{key:"createRawDateString",value:function(t,e){var n=t.year;return 0===t.month&&(t.month=1),n+="-"+("0"+t.month.toString()).slice(-2),"day"===t.unit?n+="day"===t.unit?"-"+("0"+e).slice(-2):"-01":n+="-"+("0"+(t.day?t.day:"1")).slice(-2),"hour"===t.unit?n+="hour"===t.unit?"T"+("0"+e).slice(-2):"T00":n+="T"+("0"+(t.hour?t.hour:"0")).slice(-2),"minute"===t.unit?n+=":"+("0"+e).slice(-2):n+=":"+(t.minute?("0"+t.minute).slice(-2):"00"),"second"===t.unit?n+=":"+("0"+e).slice(-2):n+=":00",this.utc&&(n+=".000Z"),n}},{key:"formatDates",value:function(t){var e=this,n=this.w;return t.map((function(t){var r=t.value.toString(),i=new O(e.ctx),a=e.createRawDateString(t,r),o=i.getDate(i.parseDate(a));if(e.utc||(o=i.getDate(i.parseDateWithTimezone(a))),void 0===n.config.xaxis.labels.format){var s="dd MMM",l=n.config.xaxis.labels.datetimeFormatter;"year"===t.unit&&(s=l.year),"month"===t.unit&&(s=l.month),"day"===t.unit&&(s=l.day),"hour"===t.unit&&(s=l.hour),"minute"===t.unit&&(s=l.minute),"second"===t.unit&&(s=l.second),r=i.formatDate(o,s)}else r=i.formatDate(o,n.config.xaxis.labels.format);return{dateString:a,position:t.position,value:r,unit:t.unit,year:t.year,month:t.month}}))}},{key:"removeOverlappingTS",value:function(t){var e,n=this,r=new _(this.ctx),i=!1;t.length>0&&t[0].value&&t.every((function(e){return e.value.length===t[0].value.length}))&&(i=!0,e=r.getTextRects(t[0].value).width);var a=0,o=t.map((function(o,s){if(s>0&&n.w.config.xaxis.labels.hideOverlappingLabels){var l=i?e:r.getTextRects(t[a].value).width,c=t[a].position;return o.position>c+l+10?(a=s,o):null}return o}));return o.filter((function(t){return null!==t}))}},{key:"_getYear",value:function(t,e,n){return t+Math.floor(e/12)+n}}]),t}(),Zt=function(){function t(e,n){o(this,t),this.ctx=n,this.w=n.w,this.el=e}return l(t,[{key:"setupElements",value:function(){var t=this.w,e=t.globals,n=t.config,r=n.chart.type;e.axisCharts=["line","area","bar","rangeBar","rangeArea","candlestick","boxPlot","scatter","bubble","radar","heatmap","treemap"].includes(r),e.xyCharts=["line","area","bar","rangeBar","rangeArea","candlestick","boxPlot","scatter","bubble"].includes(r),e.isBarHorizontal=["bar","rangeBar","boxPlot"].includes(r)&&n.plotOptions.bar.horizontal,e.chartClass=".apexcharts".concat(e.chartID),e.dom.baseEl=this.el,e.dom.elWrap=document.createElement("div"),_.setAttrs(e.dom.elWrap,{id:e.chartClass.substring(1),class:"apexcharts-canvas ".concat(e.chartClass.substring(1))}),this.el.appendChild(e.dom.elWrap),e.dom.Paper=new window.SVG.Doc(e.dom.elWrap),e.dom.Paper.attr({class:"apexcharts-svg","xmlns:data":"ApexChartsNS",transform:"translate(".concat(n.chart.offsetX,", ").concat(n.chart.offsetY,")")}),e.dom.Paper.node.style.background="dark"!==n.theme.mode||n.chart.background?"light"!==n.theme.mode||n.chart.background?n.chart.background:"#fff":"#424242",this.setSVGDimensions(),e.dom.elLegendForeign=document.createElementNS(e.SVGNS,"foreignObject"),_.setAttrs(e.dom.elLegendForeign,{x:0,y:0,width:e.svgWidth,height:e.svgHeight}),e.dom.elLegendWrap=document.createElement("div"),e.dom.elLegendWrap.classList.add("apexcharts-legend"),e.dom.elLegendWrap.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),e.dom.elLegendForeign.appendChild(e.dom.elLegendWrap),e.dom.Paper.node.appendChild(e.dom.elLegendForeign),e.dom.elGraphical=e.dom.Paper.group().attr({class:"apexcharts-inner apexcharts-graphical"}),e.dom.elDefs=e.dom.Paper.defs(),e.dom.Paper.add(e.dom.elGraphical),e.dom.elGraphical.add(e.dom.elDefs)}},{key:"plotChartType",value:function(t,e){var n=this.w,r=this.ctx,i=n.config,a=n.globals,o={line:{series:[],i:[]},area:{series:[],i:[]},scatter:{series:[],i:[]},bubble:{series:[],i:[]},column:{series:[],i:[]},candlestick:{series:[],i:[]},boxPlot:{series:[],i:[]},rangeBar:{series:[],i:[]},rangeArea:{series:[],seriesRangeEnd:[],i:[]}},s=i.chart.type||"line",l=null,c=0;a.series.forEach((function(e,r){var i=t[r].type||s;o[i]?("rangeArea"===i?(o[i].series.push(a.seriesRangeStart[r]),o[i].seriesRangeEnd.push(a.seriesRangeEnd[r])):o[i].series.push(e),o[i].i.push(r),"column"!==i&&"bar"!==i||(n.globals.columnSeries=o.column)):["heatmap","treemap","pie","donut","polarArea","radialBar","radar"].includes(i)?l=i:"bar"===i?(o.column.series.push(e),o.column.i.push(r)):console.warn("You have specified an unrecognized series type (".concat(i,").")),s!==i&&"scatter"!==i&&c++})),c>0&&(l&&console.warn("Chart or series type ".concat(l," cannot appear with other chart or series types.")),o.column.series.length>0&&i.plotOptions.bar.horizontal&&(c-=o.column.series.length,o.column={series:[],i:[]},n.globals.columnSeries={series:[],i:[]},console.warn("Horizontal bars are not supported in a mixed/combo chart. Please turn off `plotOptions.bar.horizontal`"))),a.comboCharts||(a.comboCharts=c>0);var u=new Yt(r,e),h=new Ot(r,e);r.pie=new Vt(r);var d=new jt(r);r.rangeBar=new Bt(r,e);var f=new Lt(r),p=[];if(a.comboCharts){var v,g,m=new D(r);if(o.area.series.length>0&&(v=p).push.apply(v,b(m.drawSeriesByGroup(o.area,a.areaGroups,"area",u))),o.column.series.length>0)if(i.chart.stacked){var y=new Et(r,e);p.push(y.draw(o.column.series,o.column.i))}else r.bar=new Tt(r,e),p.push(r.bar.draw(o.column.series,o.column.i));if(o.rangeArea.series.length>0&&p.push(u.draw(o.rangeArea.series,"rangeArea",o.rangeArea.i,o.rangeArea.seriesRangeEnd)),o.line.series.length>0&&(g=p).push.apply(g,b(m.drawSeriesByGroup(o.line,a.lineGroups,"line",u))),o.candlestick.series.length>0&&p.push(h.draw(o.candlestick.series,"candlestick",o.candlestick.i)),o.boxPlot.series.length>0&&p.push(h.draw(o.boxPlot.series,"boxPlot",o.boxPlot.i)),o.rangeBar.series.length>0&&p.push(r.rangeBar.draw(o.rangeBar.series,o.rangeBar.i)),o.scatter.series.length>0){var x=new Yt(r,e,!0);p.push(x.draw(o.scatter.series,"scatter",o.scatter.i))}if(o.bubble.series.length>0){var w=new Yt(r,e,!0);p.push(w.draw(o.bubble.series,"bubble",o.bubble.i))}}else switch(i.chart.type){case"line":p=u.draw(a.series,"line");break;case"area":p=u.draw(a.series,"area");break;case"bar":i.chart.stacked?p=new Et(r,e).draw(a.series):(r.bar=new Tt(r,e),p=r.bar.draw(a.series));break;case"candlestick":p=new Ot(r,e).draw(a.series,"candlestick");break;case"boxPlot":p=new Ot(r,e).draw(a.series,i.chart.type);break;case"rangeBar":p=r.rangeBar.draw(a.series);break;case"rangeArea":p=u.draw(a.seriesRangeStart,"rangeArea",void 0,a.seriesRangeEnd);break;case"heatmap":p=new It(r,e).draw(a.series);break;case"treemap":p=new Xt(r,e).draw(a.series);break;case"pie":case"donut":case"polarArea":p=r.pie.draw(a.series);break;case"radialBar":p=d.draw(a.series);break;case"radar":p=f.draw(a.series);break;default:p=u.draw(a.series)}return p}},{key:"setSVGDimensions",value:function(){var t=this.w,e=t.globals,n=t.config;n.chart.width=n.chart.width||"100%",n.chart.height=n.chart.height||"auto",e.svgWidth=n.chart.width,e.svgHeight=n.chart.height;var r=S.getDimensions(this.el),i=n.chart.width.toString().split(/[0-9]+/g).pop();"%"===i?S.isNumber(r[0])&&(0===r[0].width&&(r=S.getDimensions(this.el.parentNode)),e.svgWidth=r[0]*parseInt(n.chart.width,10)/100):"px"!==i&&""!==i||(e.svgWidth=parseInt(n.chart.width,10));var a=String(n.chart.height).toString().split(/[0-9]+/g).pop();if("auto"!==e.svgHeight&&""!==e.svgHeight)if("%"===a){var o=S.getDimensions(this.el.parentNode);e.svgHeight=o[1]*parseInt(n.chart.height,10)/100}else e.svgHeight=parseInt(n.chart.height,10);else e.svgHeight=e.axisCharts?e.svgWidth/1.61:e.svgWidth/1.2;if(e.svgWidth=Math.max(e.svgWidth,0),e.svgHeight=Math.max(e.svgHeight,0),_.setAttrs(e.dom.Paper.node,{width:e.svgWidth,height:e.svgHeight}),"%"!==a){var s=n.chart.sparkline.enabled?0:e.axisCharts?n.chart.parentHeightOffset:0;e.dom.Paper.node.parentNode.parentNode.style.minHeight="".concat(e.svgHeight+s,"px")}e.dom.elWrap.style.width="".concat(e.svgWidth,"px"),e.dom.elWrap.style.height="".concat(e.svgHeight,"px")}},{key:"shiftGraphPosition",value:function(){var t=this.w.globals,e=t.translateY,n=t.translateX;_.setAttrs(t.dom.elGraphical.node,{transform:"translate(".concat(n,", ").concat(e,")")})}},{key:"resizeNonAxisCharts",value:function(){var t=this.w,e=t.globals,n=0,r=t.config.chart.sparkline.enabled?1:15;r+=t.config.grid.padding.bottom,["top","bottom"].includes(t.config.legend.position)&&t.config.legend.show&&!t.config.legend.floating&&(n=new gt(this.ctx).legendHelpers.getLegendDimensions().clwh+7);var i=t.globals.dom.baseEl.querySelector(".apexcharts-radialbar, .apexcharts-pie"),a=2.05*t.globals.radialSize;if(i&&!t.config.chart.sparkline.enabled&&0!==t.config.plotOptions.radialBar.startAngle){var o=S.getBoundingClientRect(i);a=o.bottom;var s=o.bottom-o.top;a=Math.max(2.05*t.globals.radialSize,s)}var l=Math.ceil(a+e.translateY+n+r);e.dom.elLegendForeign&&e.dom.elLegendForeign.setAttribute("height",l),t.config.chart.height&&String(t.config.chart.height).includes("%")||(e.dom.elWrap.style.height="".concat(l,"px"),_.setAttrs(e.dom.Paper.node,{height:l}),e.dom.Paper.node.parentNode.parentNode.style.minHeight="".concat(l,"px"))}},{key:"coreCalculations",value:function(){new et(this.ctx).init()}},{key:"resetGlobals",value:function(){var t=this,e=function(){return t.w.config.series.map((function(){return[]}))},n=new Y,r=this.w.globals;n.initGlobalVars(r),r.seriesXvalues=e(),r.seriesYvalues=e()}},{key:"isMultipleY",value:function(){return!!(Array.isArray(this.w.config.yaxis)&&this.w.config.yaxis.length>1)&&(this.w.globals.isMultipleYAxis=!0,!0)}},{key:"xySettings",value:function(){var t=this.w,e=null;if(t.globals.axisCharts){if("back"===t.config.xaxis.crosshairs.position&&new ot(this.ctx).drawXCrosshairs(),"back"===t.config.yaxis[0].crosshairs.position&&new ot(this.ctx).drawYCrosshairs(),"datetime"===t.config.xaxis.type&&void 0===t.config.xaxis.labels.formatter){this.ctx.timeScale=new qt(this.ctx);var n=[];isFinite(t.globals.minX)&&isFinite(t.globals.maxX)&&!t.globals.isBarHorizontal?n=this.ctx.timeScale.calculateTimeScaleTicks(t.globals.minX,t.globals.maxX):t.globals.isBarHorizontal&&(n=this.ctx.timeScale.calculateTimeScaleTicks(t.globals.minY,t.globals.maxY)),this.ctx.timeScale.recalcDimensionsBasedOnFormat(n)}e=new D(this.ctx).getCalculatedRatios()}return e}},{key:"updateSourceChart",value:function(t){this.ctx.w.globals.selection=void 0,this.ctx.updateHelpers._updateOptions({chart:{selection:{xaxis:{min:t.w.globals.minX,max:t.w.globals.maxX}}}},!1,!1)}},{key:"setupBrushHandler",value:function(){var t=this,e=this.w;if(e.config.chart.brush.enabled&&"function"!=typeof e.config.chart.events.selection){var n=Array.isArray(e.config.chart.brush.targets)?e.config.chart.brush.targets:[e.config.chart.brush.target];n.forEach((function(e){var n=ApexCharts.getChartByID(e);n.w.globals.brushSource=t.ctx,"function"!=typeof n.w.config.chart.events.zoomed&&(n.w.config.chart.events.zoomed=function(){return t.updateSourceChart(n)}),"function"!=typeof n.w.config.chart.events.scrolled&&(n.w.config.chart.events.scrolled=function(){return t.updateSourceChart(n)})})),e.config.chart.events.selection=function(t,e){n.forEach((function(t){ApexCharts.getChartByID(t).ctx.updateHelpers._updateOptions({xaxis:{min:e.xaxis.min,max:e.xaxis.max}},!1,!1,!1,!1)}))}}}}]),t}(),Kt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"_updateOptions",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],a=arguments.length>4&&void 0!==arguments[4]&&arguments[4];return new Promise((function(o){var s=[e.ctx];i&&(s=e.ctx.getSyncedCharts()),e.ctx.w.globals.isExecCalled&&(s=[e.ctx],e.ctx.w.globals.isExecCalled=!1),s.forEach((function(i,l){var c=i.w;if(c.globals.shouldAnimate=r,n||(c.globals.resized=!0,c.globals.dataChanged=!0,r&&i.series.getPreviousPaths()),t&&"object"===w(t)&&(i.config=new $(t),t=D.extendArrayProps(i.config,t,c),i.w.globals.chartID!==e.ctx.w.globals.chartID&&delete t.series,c.config=S.extend(c.config,t),a&&(c.globals.lastXAxis=t.xaxis?S.clone(t.xaxis):[],c.globals.lastYAxis=t.yaxis?S.clone(t.yaxis):[],c.globals.initialConfig=S.extend({},c.config),c.globals.initialSeries=S.clone(c.config.series),t.series))){for(var u=0;u2&&void 0!==arguments[2]&&arguments[2];return new Promise((function(i){var a,o=n.w;return o.globals.shouldAnimate=e,o.globals.dataChanged=!0,e&&n.ctx.series.getPreviousPaths(),o.globals.axisCharts?(0===(a=t.map((function(t,e){return n._extendSeries(t,e)}))).length&&(a=[{data:[]}]),o.config.series=a):o.config.series=t.slice(),r&&(o.globals.initialConfig.series=S.clone(o.config.series),o.globals.initialSeries=S.clone(o.config.series)),n.ctx.update().then((function(){i(n.ctx)}))}))}},{key:"_extendSeries",value:function(t,e){var n=this.w,r=n.config.series[e];return g(g({},n.config.series[e]),{},{name:t.name?t.name:null==r?void 0:r.name,color:t.color?t.color:null==r?void 0:r.color,type:t.type?t.type:null==r?void 0:r.type,group:t.group?t.group:null==r?void 0:r.group,hidden:void 0!==t.hidden?t.hidden:null==r?void 0:r.hidden,data:t.data?t.data:null==r?void 0:r.data,zIndex:void 0!==t.zIndex?t.zIndex:e})}},{key:"toggleDataPointSelection",value:function(t,e){var n=this.w,r=null,i=".apexcharts-series[data\\:realIndex='".concat(t,"']");return n.globals.axisCharts?r=n.globals.dom.Paper.select("".concat(i," path[j='").concat(e,"'], ").concat(i," circle[j='").concat(e,"'], ").concat(i," rect[j='").concat(e,"']")).members[0]:void 0===e&&(r=n.globals.dom.Paper.select("".concat(i," path[j='").concat(t,"']")).members[0],"pie"!==n.config.chart.type&&"polarArea"!==n.config.chart.type&&"donut"!==n.config.chart.type||this.ctx.pie.pieClicked(t)),r?(new _(this.ctx).pathMouseDown(r,null),r.node?r.node:null):(console.warn("toggleDataPointSelection: Element not found"),null)}},{key:"forceXAxisUpdate",value:function(t){var e=this.w;if(["min","max"].forEach((function(n){void 0!==t.xaxis[n]&&(e.config.xaxis[n]=t.xaxis[n],e.globals.lastXAxis[n]=t.xaxis[n])})),t.xaxis.categories&&t.xaxis.categories.length&&(e.config.xaxis.categories=t.xaxis.categories),e.config.xaxis.convertedCatToNumeric){var n=new z(t);t=n.convertCatToNumericXaxis(t,this.ctx)}return t}},{key:"forceYAxisUpdate",value:function(t){return t.chart&&t.chart.stacked&&"100%"===t.chart.stackType&&(Array.isArray(t.yaxis)?t.yaxis.forEach((function(e,n){t.yaxis[n].min=0,t.yaxis[n].max=100})):(t.yaxis.min=0,t.yaxis.max=100)),t}},{key:"revertDefaultAxisMinMax",value:function(t){var e=this,n=this.w,r=n.globals.lastXAxis,i=n.globals.lastYAxis;t&&t.xaxis&&(r=t.xaxis),t&&t.yaxis&&(i=t.yaxis),n.config.xaxis.min=r.min,n.config.xaxis.max=r.max;var a=function(t){void 0!==i[t]&&(n.config.yaxis[t].min=i[t].min,n.config.yaxis[t].max=i[t].max)};n.config.yaxis.map((function(t,r){n.globals.zoomed||void 0!==i[r]?a(r):void 0!==e.ctx.opts.yaxis[r]&&(t.min=e.ctx.opts.yaxis[r].min,t.max=e.ctx.opts.yaxis[r].max)}))}}]),t}();Ht="undefined"!=typeof window?window:void 0,Wt=function(t,e){var n=(void 0!==this?this:t).SVG=function(t){if(n.supported)return t=new n.Doc(t),n.parser.draw||n.prepare(),t};if(n.ns="http://www.w3.org/2000/svg",n.xmlns="http://www.w3.org/2000/xmlns/",n.xlink="http://www.w3.org/1999/xlink",n.svgjs="http://svgjs.dev",n.supported=!0,!n.supported)return!1;n.did=1e3,n.eid=function(t){return"Svgjs"+u(t)+n.did++},n.create=function(t){var n=e.createElementNS(this.ns,t);return n.setAttribute("id",this.eid(t)),n},n.extend=function(){var t,e;e=(t=[].slice.call(arguments)).pop();for(var r=t.length-1;r>=0;r--)if(t[r])for(var i in e)t[r].prototype[i]=e[i];n.Set&&n.Set.inherit&&n.Set.inherit()},n.invent=function(t){var e="function"==typeof t.create?t.create:function(){this.constructor.call(this,n.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&n.extend(e,t.extend),t.construct&&n.extend(t.parent||n.Container,t.construct),e},n.adopt=function(e){return e?e.instance?e.instance:((r="svg"==e.nodeName?e.parentNode instanceof t.SVGElement?new n.Nested:new n.Doc:"linearGradient"==e.nodeName?new n.Gradient("linear"):"radialGradient"==e.nodeName?new n.Gradient("radial"):n[u(e.nodeName)]?new(n[u(e.nodeName)]):new n.Element(e)).type=e.nodeName,r.node=e,e.instance=r,r instanceof n.Doc&&r.namespace().defs(),r.setData(JSON.parse(e.getAttribute("svgjs:data"))||{}),r):null;var r},n.prepare=function(){var t=e.getElementsByTagName("body")[0],r=(t?new n.Doc(t):n.adopt(e.documentElement).nested()).size(2,0);n.parser={body:t||e.documentElement,draw:r.style("opacity:0;position:absolute;left:-100%;top:-100%;overflow:hidden").node,poly:r.polyline().node,path:r.path().node,native:n.create("svg")}},n.parser={native:n.create("svg")},e.addEventListener("DOMContentLoaded",(function(){n.parser.draw||n.prepare()}),!1),n.regex={numberAndUnit:/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,transforms:/\)\s*,?\s*/,whitespace:/\s/g,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,isPercent:/^-?[\d\.]+%$/,isImage:/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,delimiter:/[\s,]+/,hyphen:/([^e])\-/gi,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,numbersWithDots:/((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,dots:/\./g},n.utils={map:function(t,e){for(var n=t.length,r=[],i=0;i1?1:t,new n.Color({r:~~(this.r+(this.destination.r-this.r)*t),g:~~(this.g+(this.destination.g-this.g)*t),b:~~(this.b+(this.destination.b-this.b)*t)})):this}}),n.Color.test=function(t){return t+="",n.regex.isHex.test(t)||n.regex.isRgb.test(t)},n.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},n.Color.isColor=function(t){return n.Color.isRgb(t)||n.Color.test(t)},n.Array=function(t,e){0==(t=(t||[]).valueOf()).length&&e&&(t=e.valueOf()),this.value=this.parse(t)},n.extend(n.Array,{toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:this.split(t)}}),n.PointArray=function(t,e){n.Array.call(this,t,e||[[0,0]])},n.PointArray.prototype=new n.Array,n.PointArray.prototype.constructor=n.PointArray;for(var r={M:function(t,e,n){return e.x=n.x=t[0],e.y=n.y=t[1],["M",e.x,e.y]},L:function(t,e){return e.x=t[0],e.y=t[1],["L",t[0],t[1]]},H:function(t,e){return e.x=t[0],["H",t[0]]},V:function(t,e){return e.y=t[0],["V",t[0]]},C:function(t,e){return e.x=t[4],e.y=t[5],["C",t[0],t[1],t[2],t[3],t[4],t[5]]},Q:function(t,e){return e.x=t[2],e.y=t[3],["Q",t[0],t[1],t[2],t[3]]},S:function(t,e){return e.x=t[2],e.y=t[3],["S",t[0],t[1],t[2],t[3]]},Z:function(t,e,n){return e.x=n.x,e.y=n.y,["Z"]}},i="mlhvqtcsaz".split(""),a=0,o=i.length;ac);return a},bbox:function(){return n.parser.draw||n.prepare(),n.parser.path.setAttribute("d",this.toString()),n.parser.path.getBBox()}}),n.Number=n.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:t<0?-34e37:34e37:"string"==typeof t?(e=t.match(n.regex.numberAndUnit))&&(this.value=parseFloat(e[1]),"%"==e[5]?this.value/=100:"s"==e[5]&&(this.value*=1e3),this.unit=e[5]):t instanceof n.Number&&(this.value=t.valueOf(),this.unit=t.unit)},extend:{toString:function(){return("%"==this.unit?~~(1e8*this.value)/1e6:"s"==this.unit?this.value/1e3:this.value)+this.unit},toJSON:function(){return this.toString()},valueOf:function(){return this.value},plus:function(t){return t=new n.Number(t),new n.Number(this+t,this.unit||t.unit)},minus:function(t){return t=new n.Number(t),new n.Number(this-t,this.unit||t.unit)},times:function(t){return t=new n.Number(t),new n.Number(this*t,this.unit||t.unit)},divide:function(t){return t=new n.Number(t),new n.Number(this/t,this.unit||t.unit)},to:function(t){var e=new n.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new n.Number(t),t.relative&&(this.destination.value+=this.value),this},at:function(t){return this.destination?new n.Number(this.destination).minus(this).times(t).plus(this):this}}}),n.Element=n.invent({create:function(t){this._stroke=n.defaults.attrs.stroke,this._event=null,this.dom={},(this.node=t)&&(this.type=t.nodeName,this.node.instance=this,this._stroke=t.getAttribute("stroke")||this._stroke)},extend:{x:function(t){return this.attr("x",t)},y:function(t){return this.attr("y",t)},cx:function(t){return null==t?this.x()+this.width()/2:this.x(t-this.width()/2)},cy:function(t){return null==t?this.y()+this.height()/2:this.y(t-this.height()/2)},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},width:function(t){return this.attr("width",t)},height:function(t){return this.attr("height",t)},size:function(t,e){var r=d(this,t,e);return this.width(new n.Number(r.width)).height(new n.Number(r.height))},clone:function(t){this.writeDataToDom();var e=v(this.node.cloneNode(!0));return t?t.add(e):this.after(e),e},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return t.put(this)},putIn:function(t){return t.add(this)},id:function(t){return this.attr("id",t)},show:function(){return this.style("display","")},hide:function(){return this.style("display","none")},visible:function(){return"none"!=this.style("display")},toString:function(){return this.attr("id")},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(n.regex.delimiter)},hasClass:function(t){return-1!=this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter((function(e){return e!=t})).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return n.get(this.attr(t))},parent:function(e){var r=this;if(!r.node.parentNode)return null;if(r=n.adopt(r.node.parentNode),!e)return r;for(;r&&r.node instanceof t.SVGElement;){if("string"==typeof e?r.matches(e):r instanceof e)return r;if(!r.node.parentNode||"#document"==r.node.parentNode.nodeName)return null;r=n.adopt(r.node.parentNode)}},doc:function(){return this instanceof n.Doc?this:this.parent(n.Doc)},parents:function(t){var e=[],n=this;do{if(!(n=n.parent(t))||!n.node)break;e.push(n)}while(n.parent);return e},matches:function(t){return function(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}(this.node,t)},native:function(){return this.node},svg:function(t){var r=e.createElementNS("http://www.w3.org/2000/svg","svg");if(!(t&&this instanceof n.Parent))return r.appendChild(t=e.createElementNS("http://www.w3.org/2000/svg","svg")),this.writeDataToDom(),t.appendChild(this.node.cloneNode(!0)),r.innerHTML.replace(/^/,"").replace(/<\/svg>$/,"");r.innerHTML=""+t.replace(/\n/,"").replace(/<([\w:-]+)([^<]+?)\/>/g,"<$1$2>")+"";for(var i=0,a=r.firstChild.childNodes.length;i":function(t){return-Math.cos(t*Math.PI)/2+.5},">":function(t){return Math.sin(t*Math.PI/2)},"<":function(t){return 1-Math.cos(t*Math.PI/2)}},n.morph=function(t){return function(e,r){return new n.MorphObj(e,r).at(t)}},n.Situation=n.invent({create:function(t){this.init=!1,this.reversed=!1,this.reversing=!1,this.duration=new n.Number(t.duration).valueOf(),this.delay=new n.Number(t.delay).valueOf(),this.start=+new Date+this.delay,this.finish=this.start+this.duration,this.ease=t.ease,this.loop=0,this.loops=!1,this.animations={},this.attrs={},this.styles={},this.transforms=[],this.once={}}}),n.FX=n.invent({create:function(t){this._target=t,this.situations=[],this.active=!1,this.situation=null,this.paused=!1,this.lastPos=0,this.pos=0,this.absPos=0,this._speed=1},extend:{animate:function(t,e,r){"object"===w(t)&&(e=t.ease,r=t.delay,t=t.duration);var i=new n.Situation({duration:t||1e3,delay:r||0,ease:n.easing[e||"-"]||e});return this.queue(i),this},target:function(t){return t&&t instanceof n.Element?(this._target=t,this):this._target},timeToAbsPos:function(t){return(t-this.situation.start)/(this.situation.duration/this._speed)},absPosToTime:function(t){return this.situation.duration/this._speed*t+this.situation.start},startAnimFrame:function(){this.stopAnimFrame(),this.animationFrame=t.requestAnimationFrame(function(){this.step()}.bind(this))},stopAnimFrame:function(){t.cancelAnimationFrame(this.animationFrame)},start:function(){return!this.active&&this.situation&&(this.active=!0,this.startCurrent()),this},startCurrent:function(){return this.situation.start=+new Date+this.situation.delay/this._speed,this.situation.finish=this.situation.start+this.situation.duration/this._speed,this.initAnimations().step()},queue:function(t){return("function"==typeof t||t instanceof n.Situation)&&this.situations.push(t),this.situation||(this.situation=this.situations.shift()),this},dequeue:function(){return this.stop(),this.situation=this.situations.shift(),this.situation&&(this.situation instanceof n.Situation?this.start():this.situation.call(this)),this},initAnimations:function(){var t,e=this.situation;if(e.init)return this;for(var r in e.animations){t=this.target()[r](),Array.isArray(t)||(t=[t]),Array.isArray(e.animations[r])||(e.animations[r]=[e.animations[r]]);for(var i=t.length;i--;)e.animations[r][i]instanceof n.Number&&(t[i]=new n.Number(t[i])),e.animations[r][i]=t[i].morph(e.animations[r][i])}for(var r in e.attrs)e.attrs[r]=new n.MorphObj(this.target().attr(r),e.attrs[r]);for(var r in e.styles)e.styles[r]=new n.MorphObj(this.target().style(r),e.styles[r]);return e.initialTransformation=this.target().matrixify(),e.init=!0,this},clearQueue:function(){return this.situations=[],this},clearCurrent:function(){return this.situation=null,this},stop:function(t,e){var n=this.active;return this.active=!1,e&&this.clearQueue(),t&&this.situation&&(!n&&this.startCurrent(),this.atEnd()),this.stopAnimFrame(),this.clearCurrent()},after:function(t){var e=this.last();return this.target().on("finished.fx",(function n(r){r.detail.situation==e&&(t.call(this,e),this.off("finished.fx",n))})),this._callStart()},during:function(t){var e=this.last(),r=function(r){r.detail.situation==e&&t.call(this,r.detail.pos,n.morph(r.detail.pos),r.detail.eased,e)};return this.target().off("during.fx",r).on("during.fx",r),this.after((function(){this.off("during.fx",r)})),this._callStart()},afterAll:function(t){var e=function e(n){t.call(this),this.off("allfinished.fx",e)};return this.target().off("allfinished.fx",e).on("allfinished.fx",e),this._callStart()},last:function(){return this.situations.length?this.situations[this.situations.length-1]:this.situation},add:function(t,e,n){return this.last()[n||"animations"][t]=e,this._callStart()},step:function(t){var e,n,r;t||(this.absPos=this.timeToAbsPos(+new Date)),!1!==this.situation.loops?(e=Math.max(this.absPos,0),n=Math.floor(e),!0===this.situation.loops||nthis.lastPos&&a<=i&&(this.situation.once[a].call(this.target(),this.pos,i),delete this.situation.once[a]);return this.active&&this.target().fire("during",{pos:this.pos,eased:i,fx:this,situation:this.situation}),this.situation?(this.eachAt(),1==this.pos&&!this.situation.reversed||this.situation.reversed&&0==this.pos?(this.stopAnimFrame(),this.target().fire("finished",{fx:this,situation:this.situation}),this.situations.length||(this.target().fire("allfinished"),this.situations.length||(this.target().off(".fx"),this.active=!1)),this.active?this.dequeue():this.clearCurrent()):!this.paused&&this.active&&this.startAnimFrame(),this.lastPos=i,this):this},eachAt:function(){var t,e=this,r=this.target(),i=this.situation;for(var a in i.animations)t=[].concat(i.animations[a]).map((function(t){return"string"!=typeof t&&t.at?t.at(i.ease(e.pos),e.pos):t})),r[a].apply(r,t);for(var a in i.attrs)t=[a].concat(i.attrs[a]).map((function(t){return"string"!=typeof t&&t.at?t.at(i.ease(e.pos),e.pos):t})),r.attr.apply(r,t);for(var a in i.styles)t=[a].concat(i.styles[a]).map((function(t){return"string"!=typeof t&&t.at?t.at(i.ease(e.pos),e.pos):t})),r.style.apply(r,t);if(i.transforms.length){t=i.initialTransformation,a=0;for(var o=i.transforms.length;a=0;--r)this[m[r]]=null!=t[m[r]]?t[m[r]]:e[m[r]]},extend:{extract:function(){var t=f(this,0,1);f(this,1,0);var e=180/Math.PI*Math.atan2(t.y,t.x)-90;return{x:this.e,y:this.f,transformedX:(this.e*Math.cos(e*Math.PI/180)+this.f*Math.sin(e*Math.PI/180))/Math.sqrt(this.a*this.a+this.b*this.b),transformedY:(this.f*Math.cos(e*Math.PI/180)+this.e*Math.sin(-e*Math.PI/180))/Math.sqrt(this.c*this.c+this.d*this.d),rotation:e,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f,matrix:new n.Matrix(this)}},clone:function(){return new n.Matrix(this)},morph:function(t){return this.destination=new n.Matrix(t),this},multiply:function(t){return new n.Matrix(this.native().multiply(function(t){return t instanceof n.Matrix||(t=new n.Matrix(t)),t}(t).native()))},inverse:function(){return new n.Matrix(this.native().inverse())},translate:function(t,e){return new n.Matrix(this.native().translate(t||0,e||0))},native:function(){for(var t=n.parser.native.createSVGMatrix(),e=m.length-1;e>=0;e--)t[m[e]]=this[m[e]];return t},toString:function(){return"matrix("+g(this.a)+","+g(this.b)+","+g(this.c)+","+g(this.d)+","+g(this.e)+","+g(this.f)+")"}},parent:n.Element,construct:{ctm:function(){return new n.Matrix(this.node.getCTM())},screenCTM:function(){if(this instanceof n.Nested){var t=this.rect(1,1),e=t.node.getScreenCTM();return t.remove(),new n.Matrix(e)}return new n.Matrix(this.node.getScreenCTM())}}}),n.Point=n.invent({create:function(t,e){var n;n=Array.isArray(t)?{x:t[0],y:t[1]}:"object"===w(t)?{x:t.x,y:t.y}:null!=t?{x:t,y:null!=e?e:t}:{x:0,y:0},this.x=n.x,this.y=n.y},extend:{clone:function(){return new n.Point(this)},morph:function(t,e){return this.destination=new n.Point(t,e),this}}}),n.extend(n.Element,{point:function(t,e){return new n.Point(t,e).transform(this.screenCTM().inverse())}}),n.extend(n.Element,{attr:function(t,e,r){if(null==t){for(t={},r=(e=this.node.attributes).length-1;r>=0;r--)t[e[r].nodeName]=n.regex.isNumber.test(e[r].nodeValue)?parseFloat(e[r].nodeValue):e[r].nodeValue;return t}if("object"===w(t))for(var i in t)this.attr(i,t[i]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return null==(e=this.node.getAttribute(t))?n.defaults.attrs[t]:n.regex.isNumber.test(e)?parseFloat(e):e;"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),"fill"!=t&&"stroke"!=t||(n.regex.isImage.test(e)&&(e=this.doc().defs().image(e,0,0)),e instanceof n.Image&&(e=this.doc().defs().pattern(0,0,(function(){this.add(e)})))),"number"==typeof e?e=new n.Number(e):n.Color.isColor(e)?e=new n.Color(e):Array.isArray(e)&&(e=new n.Array(e)),"leading"==t?this.leading&&this.leading(e):"string"==typeof r?this.node.setAttributeNS(r,t,e.toString()):this.node.setAttribute(t,e.toString()),!this.rebuild||"font-size"!=t&&"x"!=t||this.rebuild(t,e)}return this}}),n.extend(n.Element,{transform:function(t,e){var r;return"object"!==w(t)?(r=new n.Matrix(this).extract(),"string"==typeof t?r[t]:r):(r=new n.Matrix(this),e=!!e||!!t.relative,null!=t.a&&(r=e?r.multiply(new n.Matrix(t)):new n.Matrix(t)),this.attr("transform",r))}}),n.extend(n.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){return(this.attr("transform")||"").split(n.regex.transforms).slice(0,-1).map((function(t){var e=t.trim().split("(");return[e[0],e[1].split(n.regex.delimiter).map((function(t){return parseFloat(t)}))]})).reduce((function(t,e){return"matrix"==e[0]?t.multiply(p(e[1])):t[e[0]].apply(t,e[1])}),new n.Matrix)},toParent:function(t){if(this==t)return this;var e=this.screenCTM(),n=t.screenCTM().inverse();return this.addTo(t).untransform().transform(n.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),n.Transformation=n.invent({create:function(t,e){if(arguments.length>1&&"boolean"!=typeof e)return this.constructor.call(this,[].slice.call(arguments));if(Array.isArray(t))for(var n=0,r=this.arguments.length;n=0},index:function(t){return[].slice.call(this.node.childNodes).indexOf(t.node)},get:function(t){return n.adopt(this.node.childNodes[t])},first:function(){return this.get(0)},last:function(){return this.get(this.node.childNodes.length-1)},each:function(t,e){for(var r=this.children(),i=0,a=r.length;i=0;r--)e.childNodes[r]instanceof t.SVGElement&&v(e.childNodes[r]);return n.adopt(e).id(n.eid(e.nodeName))}function g(t){return Math.abs(t)>1e-37?t:0}["fill","stroke"].forEach((function(t){var e={};e[t]=function(e){if(void 0===e)return this;if("string"==typeof e||n.Color.isRgb(e)||e&&"function"==typeof e.fill)this.attr(t,e);else for(var r=s[t].length-1;r>=0;r--)null!=e[s[t][r]]&&this.attr(s.prefix(t,s[t][r]),e[s[t][r]]);return this},n.extend(n.Element,n.FX,e)})),n.extend(n.Element,n.FX,{translate:function(t,e){return this.transform({x:t,y:e})},matrix:function(t){return this.attr("transform",new n.Matrix(6==arguments.length?[].slice.call(arguments):t))},opacity:function(t){return this.attr("opacity",t)},dx:function(t){return this.x(new n.Number(t).plus(this instanceof n.FX?0:this.x()),!0)},dy:function(t){return this.y(new n.Number(t).plus(this instanceof n.FX?0:this.y()),!0)}}),n.extend(n.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return this.node.getPointAtLength(t)}}),n.Set=n.invent({create:function(t){Array.isArray(t)?this.members=t:this.clear()},extend:{add:function(){for(var t=[].slice.call(arguments),e=0,n=t.length;e-1&&this.members.splice(e,1),this},each:function(t){for(var e=0,n=this.members.length;e=0},index:function(t){return this.members.indexOf(t)},get:function(t){return this.members[t]},first:function(){return this.get(0)},last:function(){return this.get(this.members.length-1)},valueOf:function(){return this.members}},construct:{set:function(t){return new n.Set(t)}}}),n.FX.Set=n.invent({create:function(t){this.set=t}}),n.Set.inherit=function(){var t=[];for(var e in n.Shape.prototype)"function"==typeof n.Shape.prototype[e]&&"function"!=typeof n.Set.prototype[e]&&t.push(e);for(var e in t.forEach((function(t){n.Set.prototype[t]=function(){for(var e=0,r=this.members.length;e=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),n.get=function(t){var r=e.getElementById(function(t){var e=(t||"").toString().match(n.regex.reference);if(e)return e[1]}(t)||t);return n.adopt(r)},n.select=function(t,r){return new n.Set(n.utils.map((r||e).querySelectorAll(t),(function(t){return n.adopt(t)})))},n.extend(n.Parent,{select:function(t){return n.select(t,this.node)}});var m="abcdef".split("");if("function"!=typeof t.CustomEvent){var y=function(t,n){n=n||{bubbles:!1,cancelable:!1,detail:void 0};var r=e.createEvent("CustomEvent");return r.initCustomEvent(t,n.bubbles,n.cancelable,n.detail),r};y.prototype=t.Event.prototype,n.CustomEvent=y}else n.CustomEvent=t.CustomEvent;return n},r=function(){return Wt(Ht,Ht.document)}.call(e,n,e,t),void 0!==r&&(t.exports=r), +/*! svg.filter.js - v2.0.2 - 2016-02-24 + * https://github.com/wout/svg.filter.js + * Copyright (c) 2016 Wout Fierens; Licensed MIT */ +function(){SVG.Filter=SVG.invent({create:"filter",inherit:SVG.Parent,extend:{source:"SourceGraphic",sourceAlpha:"SourceAlpha",background:"BackgroundImage",backgroundAlpha:"BackgroundAlpha",fill:"FillPaint",stroke:"StrokePaint",autoSetIn:!0,put:function(t,e){return this.add(t,e),!t.attr("in")&&this.autoSetIn&&t.attr("in",this.source),t.attr("result")||t.attr("result",t),t},blend:function(t,e,n){return this.put(new SVG.BlendEffect(t,e,n))},colorMatrix:function(t,e){return this.put(new SVG.ColorMatrixEffect(t,e))},convolveMatrix:function(t){return this.put(new SVG.ConvolveMatrixEffect(t))},componentTransfer:function(t){return this.put(new SVG.ComponentTransferEffect(t))},composite:function(t,e,n){return this.put(new SVG.CompositeEffect(t,e,n))},flood:function(t,e){return this.put(new SVG.FloodEffect(t,e))},offset:function(t,e){return this.put(new SVG.OffsetEffect(t,e))},image:function(t){return this.put(new SVG.ImageEffect(t))},merge:function(){var t=[void 0];for(var e in arguments)t.push(arguments[e]);return this.put(new(SVG.MergeEffect.bind.apply(SVG.MergeEffect,t)))},gaussianBlur:function(t,e){return this.put(new SVG.GaussianBlurEffect(t,e))},morphology:function(t,e){return this.put(new SVG.MorphologyEffect(t,e))},diffuseLighting:function(t,e,n){return this.put(new SVG.DiffuseLightingEffect(t,e,n))},displacementMap:function(t,e,n,r,i){return this.put(new SVG.DisplacementMapEffect(t,e,n,r,i))},specularLighting:function(t,e,n,r){return this.put(new SVG.SpecularLightingEffect(t,e,n,r))},tile:function(){return this.put(new SVG.TileEffect)},turbulence:function(t,e,n,r,i){return this.put(new SVG.TurbulenceEffect(t,e,n,r,i))},toString:function(){return"url(#"+this.attr("id")+")"}}}),SVG.extend(SVG.Defs,{filter:function(t){var e=this.put(new SVG.Filter);return"function"==typeof t&&t.call(e,e),e}}),SVG.extend(SVG.Container,{filter:function(t){return this.defs().filter(t)}}),SVG.extend(SVG.Element,SVG.G,SVG.Nested,{filter:function(t){return this.filterer=t instanceof SVG.Element?t:this.doc().filter(t),this.doc()&&this.filterer.doc()!==this.doc()&&this.doc().defs().add(this.filterer),this.attr("filter",this.filterer),this.filterer},unfilter:function(t){return this.filterer&&!0===t&&this.filterer.remove(),delete this.filterer,this.attr("filter",null)}}),SVG.Effect=SVG.invent({create:function(){this.constructor.call(this)},inherit:SVG.Element,extend:{in:function(t){return null==t?this.parent()&&this.parent().select('[result="'+this.attr("in")+'"]').get(0)||this.attr("in"):this.attr("in",t)},result:function(t){return null==t?this.attr("result"):this.attr("result",t)},toString:function(){return this.result()}}}),SVG.ParentEffect=SVG.invent({create:function(){this.constructor.call(this)},inherit:SVG.Parent,extend:{in:function(t){return null==t?this.parent()&&this.parent().select('[result="'+this.attr("in")+'"]').get(0)||this.attr("in"):this.attr("in",t)},result:function(t){return null==t?this.attr("result"):this.attr("result",t)},toString:function(){return this.result()}}});var t={blend:function(t,e){return this.parent()&&this.parent().blend(this,t,e)},colorMatrix:function(t,e){return this.parent()&&this.parent().colorMatrix(t,e).in(this)},convolveMatrix:function(t){return this.parent()&&this.parent().convolveMatrix(t).in(this)},componentTransfer:function(t){return this.parent()&&this.parent().componentTransfer(t).in(this)},composite:function(t,e){return this.parent()&&this.parent().composite(this,t,e)},flood:function(t,e){return this.parent()&&this.parent().flood(t,e)},offset:function(t,e){return this.parent()&&this.parent().offset(t,e).in(this)},image:function(t){return this.parent()&&this.parent().image(t)},merge:function(){return this.parent()&&this.parent().merge.apply(this.parent(),[this].concat(arguments))},gaussianBlur:function(t,e){return this.parent()&&this.parent().gaussianBlur(t,e).in(this)},morphology:function(t,e){return this.parent()&&this.parent().morphology(t,e).in(this)},diffuseLighting:function(t,e,n){return this.parent()&&this.parent().diffuseLighting(t,e,n).in(this)},displacementMap:function(t,e,n,r){return this.parent()&&this.parent().displacementMap(this,t,e,n,r)},specularLighting:function(t,e,n,r){return this.parent()&&this.parent().specularLighting(t,e,n,r).in(this)},tile:function(){return this.parent()&&this.parent().tile().in(this)},turbulence:function(t,e,n,r,i){return this.parent()&&this.parent().turbulence(t,e,n,r,i).in(this)}};SVG.extend(SVG.Effect,t),SVG.extend(SVG.ParentEffect,t),SVG.ChildEffect=SVG.invent({create:function(){this.constructor.call(this)},inherit:SVG.Element,extend:{in:function(t){this.attr("in",t)}}});var e={blend:function(t,e,n){this.attr({in:t,in2:e,mode:n||"normal"})},colorMatrix:function(t,e){"matrix"==t&&(e=i(e)),this.attr({type:t,values:void 0===e?null:e})},convolveMatrix:function(t){t=i(t),this.attr({order:Math.sqrt(t.split(" ").length),kernelMatrix:t})},composite:function(t,e,n){this.attr({in:t,in2:e,operator:n})},flood:function(t,e){this.attr("flood-color",t),null!=e&&this.attr("flood-opacity",e)},offset:function(t,e){this.attr({dx:t,dy:e})},image:function(t){this.attr("href",t,SVG.xlink)},displacementMap:function(t,e,n,r,i){this.attr({in:t,in2:e,scale:n,xChannelSelector:r,yChannelSelector:i})},gaussianBlur:function(t,e){null!=t||null!=e?this.attr("stdDeviation",function(t){if(!Array.isArray(t))return t;for(var e=0,n=t.length,r=[];e1&&(T*=r=Math.sqrt(r),E*=r),i=(new SVG.Matrix).rotate(O).scale(1/T,1/E).rotate(-O),L=L.transform(i),j=j.transform(i),a=[j.x-L.x,j.y-L.y],s=a[0]*a[0]+a[1]*a[1],o=Math.sqrt(s),a[0]/=o,a[1]/=o,l=s<4?Math.sqrt(1-s/4):0,P===I&&(l*=-1),c=new SVG.Point((j.x+L.x)/2+l*-a[1],(j.y+L.y)/2+l*a[0]),u=new SVG.Point(L.x-c.x,L.y-c.y),h=new SVG.Point(j.x-c.x,j.y-c.y),d=Math.acos(u.x/Math.sqrt(u.x*u.x+u.y*u.y)),u.y<0&&(d*=-1),f=Math.acos(h.x/Math.sqrt(h.x*h.x+h.y*h.y)),h.y<0&&(f*=-1),I&&d>f&&(f+=2*Math.PI),!I&&da.maxX-e.width&&(o=(r=a.maxX-e.width)-this.startPoints.box.x),null!=a.minY&&ia.maxY-e.height&&(s=(i=a.maxY-e.height)-this.startPoints.box.y),null!=a.snapToGrid&&(r-=r%a.snapToGrid,i-=i%a.snapToGrid,o-=o%a.snapToGrid,s-=s%a.snapToGrid),this.el instanceof SVG.G?this.el.matrix(this.startPoints.transform).transform({x:o,y:s},!0):this.el.move(r,i));return n},t.prototype.end=function(t){var e=this.drag(t);this.el.fire("dragend",{event:t,p:e,m:this.m,handler:this}),SVG.off(window,"mousemove.drag"),SVG.off(window,"touchmove.drag"),SVG.off(window,"mouseup.drag"),SVG.off(window,"touchend.drag")},SVG.extend(SVG.Element,{draggable:function(e,n){"function"!=typeof e&&"object"!=typeof e||(n=e,e=!0);var r=this.remember("_draggable")||new t(this);return(e=void 0===e||e)?r.init(n||{},e):(this.off("mousedown.drag"),this.off("touchstart.drag")),this}})}.call(void 0),function(){function t(t){this.el=t,t.remember("_selectHandler",this),this.pointSelection={isSelected:!1},this.rectSelection={isSelected:!1},this.pointsList={lt:[0,0],rt:["width",0],rb:["width","height"],lb:[0,"height"],t:["width",0],r:["width","height"],b:["width","height"],l:[0,"height"]},this.pointCoord=function(t,e,n){var r="string"!=typeof t?t:e[t];return n?r/2:r},this.pointCoords=function(t,e){var n=this.pointsList[t];return{x:this.pointCoord(n[0],e,"t"===t||"b"===t),y:this.pointCoord(n[1],e,"r"===t||"l"===t)}}}t.prototype.init=function(t,e){var n=this.el.bbox();this.options={};var r=this.el.selectize.defaults.points;for(var i in this.el.selectize.defaults)this.options[i]=this.el.selectize.defaults[i],void 0!==e[i]&&(this.options[i]=e[i]);var a=["points","pointsExclude"];for(var i in a){var o=this.options[a[i]];"string"==typeof o?o=o.length>0?o.split(/\s*,\s*/i):[]:"boolean"==typeof o&&"points"===a[i]&&(o=o?r:[]),this.options[a[i]]=o}this.options.points=[r,this.options.points].reduce((function(t,e){return t.filter((function(t){return e.indexOf(t)>-1}))})),this.options.points=[this.options.points,this.options.pointsExclude].reduce((function(t,e){return t.filter((function(t){return e.indexOf(t)<0}))})),this.parent=this.el.parent(),this.nested=this.nested||this.parent.group(),this.nested.matrix(new SVG.Matrix(this.el).translate(n.x,n.y)),this.options.deepSelect&&-1!==["line","polyline","polygon"].indexOf(this.el.type)?this.selectPoints(t):this.selectRect(t),this.observe(),this.cleanup()},t.prototype.selectPoints=function(t){return this.pointSelection.isSelected=t,this.pointSelection.set||(this.pointSelection.set=this.parent.set(),this.drawPoints()),this},t.prototype.getPointArray=function(){var t=this.el.bbox();return this.el.array().valueOf().map((function(e){return[e[0]-t.x,e[1]-t.y]}))},t.prototype.drawPoints=function(){for(var t=this,e=this.getPointArray(),n=0,r=e.length;n0&&this.parameters.box.height-n[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x+n[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize-n[0]);n=this.checkAspectRatio(n),this.el.move(this.parameters.box.x+n[0],this.parameters.box.y+n[1]).size(this.parameters.box.width-n[0],this.parameters.box.height-n[1])}};break;case"rt":this.calc=function(t,e){var n=this.snapToGrid(t,e,2);if(this.parameters.box.width+n[0]>0&&this.parameters.box.height-n[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x-n[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize+n[0]);n=this.checkAspectRatio(n,!0),this.el.move(this.parameters.box.x,this.parameters.box.y+n[1]).size(this.parameters.box.width+n[0],this.parameters.box.height-n[1])}};break;case"rb":this.calc=function(t,e){var n=this.snapToGrid(t,e,0);if(this.parameters.box.width+n[0]>0&&this.parameters.box.height+n[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x-n[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize+n[0]);n=this.checkAspectRatio(n),this.el.move(this.parameters.box.x,this.parameters.box.y).size(this.parameters.box.width+n[0],this.parameters.box.height+n[1])}};break;case"lb":this.calc=function(t,e){var n=this.snapToGrid(t,e,1);if(this.parameters.box.width-n[0]>0&&this.parameters.box.height+n[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x+n[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize-n[0]);n=this.checkAspectRatio(n,!0),this.el.move(this.parameters.box.x+n[0],this.parameters.box.y).size(this.parameters.box.width-n[0],this.parameters.box.height+n[1])}};break;case"t":this.calc=function(t,e){var n=this.snapToGrid(t,e,2);if(this.parameters.box.height-n[1]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x,this.parameters.box.y+n[1]).height(this.parameters.box.height-n[1])}};break;case"r":this.calc=function(t,e){var n=this.snapToGrid(t,e,0);if(this.parameters.box.width+n[0]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x,this.parameters.box.y).width(this.parameters.box.width+n[0])}};break;case"b":this.calc=function(t,e){var n=this.snapToGrid(t,e,0);if(this.parameters.box.height+n[1]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x,this.parameters.box.y).height(this.parameters.box.height+n[1])}};break;case"l":this.calc=function(t,e){var n=this.snapToGrid(t,e,1);if(this.parameters.box.width-n[0]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x+n[0],this.parameters.box.y).width(this.parameters.box.width-n[0])}};break;case"rot":this.calc=function(t,e){var n=t+this.parameters.p.x,r=e+this.parameters.p.y,i=Math.atan2(this.parameters.p.y-this.parameters.box.y-this.parameters.box.height/2,this.parameters.p.x-this.parameters.box.x-this.parameters.box.width/2),a=Math.atan2(r-this.parameters.box.y-this.parameters.box.height/2,n-this.parameters.box.x-this.parameters.box.width/2),o=this.parameters.rotation+180*(a-i)/Math.PI+this.options.snapToAngle/2;this.el.center(this.parameters.box.cx,this.parameters.box.cy).rotate(o-o%this.options.snapToAngle,this.parameters.box.cx,this.parameters.box.cy)};break;case"point":this.calc=function(t,e){var n=this.snapToGrid(t,e,this.parameters.pointCoords[0],this.parameters.pointCoords[1]),r=this.el.array().valueOf();r[this.parameters.i][0]=this.parameters.pointCoords[0]+n[0],r[this.parameters.i][1]=this.parameters.pointCoords[1]+n[1],this.el.plot(r)}}this.el.fire("resizestart",{dx:this.parameters.x,dy:this.parameters.y,event:t}),SVG.on(window,"touchmove.resize",(function(t){e.update(t||window.event)})),SVG.on(window,"touchend.resize",(function(){e.done()})),SVG.on(window,"mousemove.resize",(function(t){e.update(t||window.event)})),SVG.on(window,"mouseup.resize",(function(){e.done()}))},t.prototype.update=function(t){if(t){var e=this._extractPosition(t),n=this.transformPoint(e.x,e.y),r=n.x-this.parameters.p.x,i=n.y-this.parameters.p.y;this.lastUpdateCall=[r,i],this.calc(r,i),this.el.fire("resizing",{dx:r,dy:i,event:t})}else this.lastUpdateCall&&this.calc(this.lastUpdateCall[0],this.lastUpdateCall[1])},t.prototype.done=function(){this.lastUpdateCall=null,SVG.off(window,"mousemove.resize"),SVG.off(window,"mouseup.resize"),SVG.off(window,"touchmove.resize"),SVG.off(window,"touchend.resize"),this.el.fire("resizedone")},t.prototype.snapToGrid=function(t,e,n,r){var i;return void 0!==r?i=[(n+t)%this.options.snapToGrid,(r+e)%this.options.snapToGrid]:(n=null==n?3:n,i=[(this.parameters.box.x+t+(1&n?0:this.parameters.box.width))%this.options.snapToGrid,(this.parameters.box.y+e+(2&n?0:this.parameters.box.height))%this.options.snapToGrid]),t<0&&(i[0]-=this.options.snapToGrid),e<0&&(i[1]-=this.options.snapToGrid),t-=Math.abs(i[0])o.maxX&&(t=o.maxX-i),void 0!==o.minY&&a+eo.maxY&&(e=o.maxY-a),[t,e]},t.prototype.checkAspectRatio=function(t,e){if(!this.options.saveAspectRatio)return t;var n=t.slice(),r=this.parameters.box.width/this.parameters.box.height,i=this.parameters.box.width+t[0],a=this.parameters.box.height-t[1],o=i/a;return or&&(n[0]=this.parameters.box.width-a*r,e&&(n[0]=-n[0])),n},SVG.extend(SVG.Element,{resize:function(e){return(this.remember("_resizeHandler")||new t(this)).init(e||{}),this}}),SVG.Element.prototype.resize.defaults={snapToAngle:.1,snapToGrid:1,constraint:{},saveAspectRatio:!1}}).call(this)}(),void 0===window.Apex&&(window.Apex={});var Jt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"initModules",value:function(){this.ctx.publicMethods=["updateOptions","updateSeries","appendData","appendSeries","isSeriesHidden","highlightSeries","toggleSeries","showSeries","hideSeries","setLocale","resetSeries","zoomX","toggleDataPointSelection","dataURI","exportToCSV","addXaxisAnnotation","addYaxisAnnotation","addPointAnnotation","clearAnnotations","removeAnnotation","paper","destroy"],this.ctx.eventList=["click","mousedown","mousemove","mouseleave","touchstart","touchmove","touchleave","mouseup","touchend"],this.ctx.animations=new C(this.ctx),this.ctx.axes=new at(this.ctx),this.ctx.core=new Zt(this.ctx.el,this.ctx),this.ctx.config=new $({}),this.ctx.data=new Z(this.ctx),this.ctx.grid=new Q(this.ctx),this.ctx.graphics=new _(this.ctx),this.ctx.coreUtils=new D(this.ctx),this.ctx.crosshairs=new ot(this.ctx),this.ctx.events=new rt(this.ctx),this.ctx.exports=new K(this.ctx),this.ctx.fill=new W(this.ctx),this.ctx.localization=new it(this.ctx),this.ctx.options=new B,this.ctx.responsive=new st(this.ctx),this.ctx.series=new q(this.ctx),this.ctx.theme=new lt(this.ctx),this.ctx.formatters=new P(this.ctx),this.ctx.titleSubtitle=new ct(this.ctx),this.ctx.legend=new gt(this.ctx),this.ctx.toolbar=new mt(this.ctx),this.ctx.tooltip=new At(this.ctx),this.ctx.dimensions=new pt(this.ctx),this.ctx.updateHelpers=new Kt(this.ctx),this.ctx.zoomPanSelection=new yt(this.ctx),this.ctx.w.globals.tooltip=new At(this.ctx)}}]),t}(),Qt=function(){function t(e){o(this,t),this.ctx=e,this.w=e.w}return l(t,[{key:"clear",value:function(t){var e=t.isUpdating;this.ctx.zoomPanSelection&&this.ctx.zoomPanSelection.destroy(),this.ctx.toolbar&&this.ctx.toolbar.destroy(),this.ctx.animations=null,this.ctx.axes=null,this.ctx.annotations=null,this.ctx.core=null,this.ctx.data=null,this.ctx.grid=null,this.ctx.series=null,this.ctx.responsive=null,this.ctx.theme=null,this.ctx.formatters=null,this.ctx.titleSubtitle=null,this.ctx.legend=null,this.ctx.dimensions=null,this.ctx.options=null,this.ctx.crosshairs=null,this.ctx.zoomPanSelection=null,this.ctx.updateHelpers=null,this.ctx.toolbar=null,this.ctx.localization=null,this.ctx.w.globals.tooltip=null,this.clearDomElements({isUpdating:e})}},{key:"killSVG",value:function(t){t.each((function(){this.removeClass("*"),this.off(),this.stop()}),!0),t.ungroup(),t.clear()}},{key:"clearDomElements",value:function(t){var e=this,n=t.isUpdating,r=this.w.globals.dom.Paper.node;r.parentNode&&r.parentNode.parentNode&&!n&&(r.parentNode.parentNode.style.minHeight="unset");var i=this.w.globals.dom.baseEl;i&&this.ctx.eventList.forEach((function(t){i.removeEventListener(t,e.ctx.events.documentEvent)}));var a=this.w.globals.dom;if(null!==this.ctx.el)for(;this.ctx.el.firstChild;)this.ctx.el.removeChild(this.ctx.el.firstChild);this.killSVG(a.Paper),a.Paper.remove(),a.elWrap=null,a.elGraphical=null,a.elLegendWrap=null,a.elLegendForeign=null,a.baseEl=null,a.elGridRect=null,a.elGridRectMask=null,a.elGridRectBarMask=null,a.elGridRectMarkerMask=null,a.elForecastMask=null,a.elNonForecastMask=null,a.elDefs=null}}]),t}(),te=new WeakMap,ee=function(){function t(e,n){o(this,t),this.opts=n,this.ctx=this,this.w=new H(n).init(),this.el=e,this.w.globals.cuid=S.randomId(),this.w.globals.chartID=this.w.config.chart.id?S.escapeString(this.w.config.chart.id):this.w.globals.cuid,new Jt(this).initModules(),this.create=S.bind(this.create,this),this.windowResizeHandler=this._windowResizeHandler.bind(this),this.parentResizeHandler=this._parentResizeCallback.bind(this)}return l(t,[{key:"render",value:function(){var t=this;return new Promise((function(e,n){if(null!==t.el){void 0===Apex._chartInstances&&(Apex._chartInstances=[]),t.w.config.chart.id&&Apex._chartInstances.push({id:t.w.globals.chartID,group:t.w.config.chart.group,chart:t}),t.setLocale(t.w.config.chart.defaultLocale);var r=t.w.config.chart.events.beforeMount;"function"==typeof r&&r(t,t.w),t.events.fireEvent("beforeMount",[t,t.w]),window.addEventListener("resize",t.windowResizeHandler),function(t,e){var n=!1;if(t.nodeType!==Node.DOCUMENT_FRAGMENT_NODE){var r=t.getBoundingClientRect();"none"!==t.style.display&&0!==r.width||(n=!0)}var i=new ResizeObserver((function(r){n&&e.call(t,r),n=!0}));t.nodeType===Node.DOCUMENT_FRAGMENT_NODE?Array.from(t.children).forEach((function(t){return i.observe(t)})):i.observe(t),te.set(e,i)}(t.el.parentNode,t.parentResizeHandler);var i=t.el.getRootNode&&t.el.getRootNode(),a=S.is("ShadowRoot",i),o=t.el.ownerDocument,s=a?i.getElementById("apexcharts-css"):o.getElementById("apexcharts-css");if(!s){var l;(s=document.createElement("style")).id="apexcharts-css",s.textContent='@keyframes opaque {\n 0% {\n opacity: 0\n }\n\n to {\n opacity: 1\n }\n}\n\n@keyframes resizeanim {\n\n 0%,\n to {\n opacity: 0\n }\n}\n\n.apexcharts-canvas {\n position: relative;\n direction: ltr !important;\n user-select: none\n}\n\n.apexcharts-canvas ::-webkit-scrollbar {\n -webkit-appearance: none;\n width: 6px\n}\n\n.apexcharts-canvas ::-webkit-scrollbar-thumb {\n border-radius: 4px;\n background-color: rgba(0, 0, 0, .5);\n box-shadow: 0 0 1px rgba(255, 255, 255, .5);\n -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, .5)\n}\n\n.apexcharts-inner {\n position: relative\n}\n\n.apexcharts-text tspan {\n font-family: inherit\n}\n\nrect.legend-mouseover-inactive,\n.legend-mouseover-inactive rect,\n.legend-mouseover-inactive path,\n.legend-mouseover-inactive circle,\n.legend-mouseover-inactive line,\n.legend-mouseover-inactive text.apexcharts-yaxis-title-text,\n.legend-mouseover-inactive text.apexcharts-yaxis-label {\n transition: .15s ease all;\n opacity: .2\n}\n\n.apexcharts-legend-text {\n padding-left: 15px;\n margin-left: -15px;\n}\n\n.apexcharts-series-collapsed {\n opacity: 0\n}\n\n.apexcharts-tooltip {\n border-radius: 5px;\n box-shadow: 2px 2px 6px -4px #999;\n cursor: default;\n font-size: 14px;\n left: 62px;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n top: 20px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n white-space: nowrap;\n z-index: 12;\n transition: .15s ease all\n}\n\n.apexcharts-tooltip.apexcharts-active {\n opacity: 1;\n transition: .15s ease all\n}\n\n.apexcharts-tooltip.apexcharts-theme-light {\n border: 1px solid #e3e3e3;\n background: rgba(255, 255, 255, .96)\n}\n\n.apexcharts-tooltip.apexcharts-theme-dark {\n color: #fff;\n background: rgba(30, 30, 30, .8)\n}\n\n.apexcharts-tooltip * {\n font-family: inherit\n}\n\n.apexcharts-tooltip-title {\n padding: 6px;\n font-size: 15px;\n margin-bottom: 4px\n}\n\n.apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title {\n background: #eceff1;\n border-bottom: 1px solid #ddd\n}\n\n.apexcharts-tooltip.apexcharts-theme-dark .apexcharts-tooltip-title {\n background: rgba(0, 0, 0, .7);\n border-bottom: 1px solid #333\n}\n\n.apexcharts-tooltip-text-goals-value,\n.apexcharts-tooltip-text-y-value,\n.apexcharts-tooltip-text-z-value {\n display: inline-block;\n margin-left: 5px;\n font-weight: 600\n}\n\n.apexcharts-tooltip-text-goals-label:empty,\n.apexcharts-tooltip-text-goals-value:empty,\n.apexcharts-tooltip-text-y-label:empty,\n.apexcharts-tooltip-text-y-value:empty,\n.apexcharts-tooltip-text-z-value:empty,\n.apexcharts-tooltip-title:empty {\n display: none\n}\n\n.apexcharts-tooltip-text-goals-label,\n.apexcharts-tooltip-text-goals-value {\n padding: 6px 0 5px\n}\n\n.apexcharts-tooltip-goals-group,\n.apexcharts-tooltip-text-goals-label,\n.apexcharts-tooltip-text-goals-value {\n display: flex\n}\n\n.apexcharts-tooltip-text-goals-label:not(:empty),\n.apexcharts-tooltip-text-goals-value:not(:empty) {\n margin-top: -6px\n}\n\n.apexcharts-tooltip-marker {\n width: 12px;\n height: 12px;\n position: relative;\n top: 0;\n margin-right: 10px;\n border-radius: 50%\n}\n\n.apexcharts-tooltip-series-group {\n padding: 0 10px;\n display: none;\n text-align: left;\n justify-content: left;\n align-items: center\n}\n\n.apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker {\n opacity: 1\n}\n\n.apexcharts-tooltip-series-group.apexcharts-active,\n.apexcharts-tooltip-series-group:last-child {\n padding-bottom: 4px\n}\n\n.apexcharts-tooltip-y-group {\n padding: 6px 0 5px\n}\n\n.apexcharts-custom-tooltip,\n.apexcharts-tooltip-box {\n padding: 4px 8px\n}\n\n.apexcharts-tooltip-boxPlot {\n display: flex;\n flex-direction: column-reverse\n}\n\n.apexcharts-tooltip-box>div {\n margin: 4px 0\n}\n\n.apexcharts-tooltip-box span.value {\n font-weight: 700\n}\n\n.apexcharts-tooltip-rangebar {\n padding: 5px 8px\n}\n\n.apexcharts-tooltip-rangebar .category {\n font-weight: 600;\n color: #777\n}\n\n.apexcharts-tooltip-rangebar .series-name {\n font-weight: 700;\n display: block;\n margin-bottom: 5px\n}\n\n.apexcharts-xaxistooltip,\n.apexcharts-yaxistooltip {\n opacity: 0;\n pointer-events: none;\n color: #373d3f;\n font-size: 13px;\n text-align: center;\n border-radius: 2px;\n position: absolute;\n z-index: 10;\n background: #eceff1;\n border: 1px solid #90a4ae\n}\n\n.apexcharts-xaxistooltip {\n padding: 9px 10px;\n transition: .15s ease all\n}\n\n.apexcharts-xaxistooltip.apexcharts-theme-dark {\n background: rgba(0, 0, 0, .7);\n border: 1px solid rgba(0, 0, 0, .5);\n color: #fff\n}\n\n.apexcharts-xaxistooltip:after,\n.apexcharts-xaxistooltip:before {\n left: 50%;\n border: solid transparent;\n content: " ";\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none\n}\n\n.apexcharts-xaxistooltip:after {\n border-color: transparent;\n border-width: 6px;\n margin-left: -6px\n}\n\n.apexcharts-xaxistooltip:before {\n border-color: transparent;\n border-width: 7px;\n margin-left: -7px\n}\n\n.apexcharts-xaxistooltip-bottom:after,\n.apexcharts-xaxistooltip-bottom:before {\n bottom: 100%\n}\n\n.apexcharts-xaxistooltip-top:after,\n.apexcharts-xaxistooltip-top:before {\n top: 100%\n}\n\n.apexcharts-xaxistooltip-bottom:after {\n border-bottom-color: #eceff1\n}\n\n.apexcharts-xaxistooltip-bottom:before {\n border-bottom-color: #90a4ae\n}\n\n.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after,\n.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before {\n border-bottom-color: rgba(0, 0, 0, .5)\n}\n\n.apexcharts-xaxistooltip-top:after {\n border-top-color: #eceff1\n}\n\n.apexcharts-xaxistooltip-top:before {\n border-top-color: #90a4ae\n}\n\n.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after,\n.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before {\n border-top-color: rgba(0, 0, 0, .5)\n}\n\n.apexcharts-xaxistooltip.apexcharts-active {\n opacity: 1;\n transition: .15s ease all\n}\n\n.apexcharts-yaxistooltip {\n padding: 4px 10px\n}\n\n.apexcharts-yaxistooltip.apexcharts-theme-dark {\n background: rgba(0, 0, 0, .7);\n border: 1px solid rgba(0, 0, 0, .5);\n color: #fff\n}\n\n.apexcharts-yaxistooltip:after,\n.apexcharts-yaxistooltip:before {\n top: 50%;\n border: solid transparent;\n content: " ";\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none\n}\n\n.apexcharts-yaxistooltip:after {\n border-color: transparent;\n border-width: 6px;\n margin-top: -6px\n}\n\n.apexcharts-yaxistooltip:before {\n border-color: transparent;\n border-width: 7px;\n margin-top: -7px\n}\n\n.apexcharts-yaxistooltip-left:after,\n.apexcharts-yaxistooltip-left:before {\n left: 100%\n}\n\n.apexcharts-yaxistooltip-right:after,\n.apexcharts-yaxistooltip-right:before {\n right: 100%\n}\n\n.apexcharts-yaxistooltip-left:after {\n border-left-color: #eceff1\n}\n\n.apexcharts-yaxistooltip-left:before {\n border-left-color: #90a4ae\n}\n\n.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after,\n.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before {\n border-left-color: rgba(0, 0, 0, .5)\n}\n\n.apexcharts-yaxistooltip-right:after {\n border-right-color: #eceff1\n}\n\n.apexcharts-yaxistooltip-right:before {\n border-right-color: #90a4ae\n}\n\n.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after,\n.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before {\n border-right-color: rgba(0, 0, 0, .5)\n}\n\n.apexcharts-yaxistooltip.apexcharts-active {\n opacity: 1\n}\n\n.apexcharts-yaxistooltip-hidden {\n display: none\n}\n\n.apexcharts-xcrosshairs,\n.apexcharts-ycrosshairs {\n pointer-events: none;\n opacity: 0;\n transition: .15s ease all\n}\n\n.apexcharts-xcrosshairs.apexcharts-active,\n.apexcharts-ycrosshairs.apexcharts-active {\n opacity: 1;\n transition: .15s ease all\n}\n\n.apexcharts-ycrosshairs-hidden {\n opacity: 0\n}\n\n.apexcharts-selection-rect {\n cursor: move\n}\n\n.svg_select_boundingRect,\n.svg_select_points_rot {\n pointer-events: none;\n opacity: 0;\n visibility: hidden\n}\n\n.apexcharts-selection-rect+g .svg_select_boundingRect,\n.apexcharts-selection-rect+g .svg_select_points_rot {\n opacity: 0;\n visibility: hidden\n}\n\n.apexcharts-selection-rect+g .svg_select_points_l,\n.apexcharts-selection-rect+g .svg_select_points_r {\n cursor: ew-resize;\n opacity: 1;\n visibility: visible\n}\n\n.svg_select_points {\n fill: #efefef;\n stroke: #333;\n rx: 2\n}\n\n.apexcharts-svg.apexcharts-zoomable.hovering-zoom {\n cursor: crosshair\n}\n\n.apexcharts-svg.apexcharts-zoomable.hovering-pan {\n cursor: move\n}\n\n.apexcharts-menu-icon,\n.apexcharts-pan-icon,\n.apexcharts-reset-icon,\n.apexcharts-selection-icon,\n.apexcharts-toolbar-custom-icon,\n.apexcharts-zoom-icon,\n.apexcharts-zoomin-icon,\n.apexcharts-zoomout-icon {\n cursor: pointer;\n width: 20px;\n height: 20px;\n line-height: 24px;\n color: #6e8192;\n text-align: center\n}\n\n.apexcharts-menu-icon svg,\n.apexcharts-reset-icon svg,\n.apexcharts-zoom-icon svg,\n.apexcharts-zoomin-icon svg,\n.apexcharts-zoomout-icon svg {\n fill: #6e8192\n}\n\n.apexcharts-selection-icon svg {\n fill: #444;\n transform: scale(.76)\n}\n\n.apexcharts-theme-dark .apexcharts-menu-icon svg,\n.apexcharts-theme-dark .apexcharts-pan-icon svg,\n.apexcharts-theme-dark .apexcharts-reset-icon svg,\n.apexcharts-theme-dark .apexcharts-selection-icon svg,\n.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg,\n.apexcharts-theme-dark .apexcharts-zoom-icon svg,\n.apexcharts-theme-dark .apexcharts-zoomin-icon svg,\n.apexcharts-theme-dark .apexcharts-zoomout-icon svg {\n fill: #f3f4f5\n}\n\n.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg,\n.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg,\n.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg {\n fill: #008ffb\n}\n\n.apexcharts-theme-light .apexcharts-menu-icon:hover svg,\n.apexcharts-theme-light .apexcharts-reset-icon:hover svg,\n.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg,\n.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg,\n.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg,\n.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg {\n fill: #333\n}\n\n.apexcharts-menu-icon,\n.apexcharts-selection-icon {\n position: relative\n}\n\n.apexcharts-reset-icon {\n margin-left: 5px\n}\n\n.apexcharts-menu-icon,\n.apexcharts-reset-icon,\n.apexcharts-zoom-icon {\n transform: scale(.85)\n}\n\n.apexcharts-zoomin-icon,\n.apexcharts-zoomout-icon {\n transform: scale(.7)\n}\n\n.apexcharts-zoomout-icon {\n margin-right: 3px\n}\n\n.apexcharts-pan-icon {\n transform: scale(.62);\n position: relative;\n left: 1px;\n top: 0\n}\n\n.apexcharts-pan-icon svg {\n fill: #fff;\n stroke: #6e8192;\n stroke-width: 2\n}\n\n.apexcharts-pan-icon.apexcharts-selected svg {\n stroke: #008ffb\n}\n\n.apexcharts-pan-icon:not(.apexcharts-selected):hover svg {\n stroke: #333\n}\n\n.apexcharts-toolbar {\n position: absolute;\n z-index: 11;\n max-width: 176px;\n text-align: right;\n border-radius: 3px;\n padding: 0 6px 2px;\n display: flex;\n justify-content: space-between;\n align-items: center\n}\n\n.apexcharts-menu {\n background: #fff;\n position: absolute;\n top: 100%;\n border: 1px solid #ddd;\n border-radius: 3px;\n padding: 3px;\n right: 10px;\n opacity: 0;\n min-width: 110px;\n transition: .15s ease all;\n pointer-events: none\n}\n\n.apexcharts-menu.apexcharts-menu-open {\n opacity: 1;\n pointer-events: all;\n transition: .15s ease all\n}\n\n.apexcharts-menu-item {\n padding: 6px 7px;\n font-size: 12px;\n cursor: pointer\n}\n\n.apexcharts-theme-light .apexcharts-menu-item:hover {\n background: #eee\n}\n\n.apexcharts-theme-dark .apexcharts-menu {\n background: rgba(0, 0, 0, .7);\n color: #fff\n}\n\n@media screen and (min-width:768px) {\n .apexcharts-canvas:hover .apexcharts-toolbar {\n opacity: 1\n }\n}\n\n.apexcharts-canvas .apexcharts-element-hidden,\n.apexcharts-datalabel.apexcharts-element-hidden,\n.apexcharts-hide .apexcharts-series-points {\n opacity: 0;\n}\n\n.apexcharts-hidden-element-shown {\n opacity: 1;\n transition: 0.25s ease all;\n}\n\n.apexcharts-datalabel,\n.apexcharts-datalabel-label,\n.apexcharts-datalabel-value,\n.apexcharts-datalabels,\n.apexcharts-pie-label {\n cursor: default;\n pointer-events: none\n}\n\n.apexcharts-pie-label-delay {\n opacity: 0;\n animation-name: opaque;\n animation-duration: .3s;\n animation-fill-mode: forwards;\n animation-timing-function: ease\n}\n\n.apexcharts-radialbar-label {\n cursor: pointer;\n}\n\n.apexcharts-annotation-rect,\n.apexcharts-area-series .apexcharts-area,\n.apexcharts-area-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,\n.apexcharts-gridline,\n.apexcharts-line,\n.apexcharts-line-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,\n.apexcharts-point-annotation-label,\n.apexcharts-radar-series path:not(.apexcharts-marker),\n.apexcharts-radar-series polygon,\n.apexcharts-toolbar svg,\n.apexcharts-tooltip .apexcharts-marker,\n.apexcharts-xaxis-annotation-label,\n.apexcharts-yaxis-annotation-label,\n.apexcharts-zoom-rect {\n pointer-events: none\n}\n\n.apexcharts-tooltip-active .apexcharts-marker {\n transition: .15s ease all\n}\n\n.resize-triggers {\n animation: 1ms resizeanim;\n visibility: hidden;\n opacity: 0;\n height: 100%;\n width: 100%;\n overflow: hidden\n}\n\n.contract-trigger:before,\n.resize-triggers,\n.resize-triggers>div {\n content: " ";\n display: block;\n position: absolute;\n top: 0;\n left: 0\n}\n\n.resize-triggers>div {\n height: 100%;\n width: 100%;\n background: #eee;\n overflow: auto\n}\n\n.contract-trigger:before {\n overflow: hidden;\n width: 200%;\n height: 200%\n}\n\n.apexcharts-bar-goals-markers {\n pointer-events: none\n}\n\n.apexcharts-bar-shadows {\n pointer-events: none\n}\n\n.apexcharts-rangebar-goals-markers {\n pointer-events: none\n}\n';var c=(null===(l=t.opts.chart)||void 0===l?void 0:l.nonce)||t.w.config.chart.nonce;c&&s.setAttribute("nonce",c),a?i.prepend(s):o.head.appendChild(s)}var u=t.create(t.w.config.series,{});if(!u)return e(t);t.mount(u).then((function(){"function"==typeof t.w.config.chart.events.mounted&&t.w.config.chart.events.mounted(t,t.w),t.events.fireEvent("mounted",[t,t.w]),e(u)})).catch((function(t){n(t)}))}else n(new Error("Element not found"))}))}},{key:"create",value:function(t,e){var n=this,r=this.w;new Jt(this).initModules();var i=this.w.globals;if(i.noData=!1,i.animationEnded=!1,this.responsive.checkResponsiveConfig(e),r.config.xaxis.convertedCatToNumeric&&new z(r.config).convertCatToNumericXaxis(r.config,this.ctx),null===this.el)return i.animationEnded=!0,null;if(this.core.setupElements(),"treemap"===r.config.chart.type&&(r.config.grid.show=!1,r.config.yaxis[0].show=!1),0===i.svgWidth)return i.animationEnded=!0,null;var a=t;t.forEach((function(t,e){t.hidden&&(a=n.legend.legendHelpers.getSeriesAfterCollapsing({realIndex:e}))}));var o=D.checkComboSeries(a,r.config.chart.type);i.comboCharts=o.comboCharts,i.comboBarCount=o.comboBarCount;var s=a.every((function(t){return t.data&&0===t.data.length}));(0===a.length||s&&i.collapsedSeries.length<1)&&this.series.handleNoData(),this.events.setupEventHandlers(),this.data.parseData(a),this.theme.init(),new X(this).setGlobalMarkerSize(),this.formatters.setLabelFormatters(),this.titleSubtitle.draw(),i.noData&&i.collapsedSeries.length!==i.series.length&&!r.config.legend.showForSingleSeries||this.legend.init(),this.series.hasAllSeriesEqualX(),i.axisCharts&&(this.core.coreCalculations(),"category"!==r.config.xaxis.type&&this.formatters.setLabelFormatters(),this.ctx.toolbar.minX=r.globals.minX,this.ctx.toolbar.maxX=r.globals.maxX),this.formatters.heatmapLabelFormatters(),new D(this).getLargestMarkerSize(),this.dimensions.plotCoords();var l=this.core.xySettings();this.grid.createGridMask();var c=this.core.plotChartType(a,l),u=new U(this);return u.bringForward(),r.config.dataLabels.background.enabled&&u.dataLabelsBackground(),this.core.shiftGraphPosition(),{elGraph:c,xyRatios:l,dimensions:{plot:{left:r.globals.translateX,top:r.globals.translateY,width:r.globals.gridWidth,height:r.globals.gridHeight}}}}},{key:"mount",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=this,r=n.w;return new Promise((function(i,a){if(null===n.el)return a(new Error("Not enough data to display or target element not found"));(null===e||r.globals.allSeriesCollapsed)&&n.series.handleNoData(),n.grid=new Q(n);var o,s,l=n.grid.drawGrid();if(n.annotations=new R(n),n.annotations.drawImageAnnos(),n.annotations.drawTextAnnos(),"back"===r.config.grid.position&&(l&&r.globals.dom.elGraphical.add(l.el),null!=l&&null!==(o=l.elGridBorders)&&void 0!==o&&o.node&&r.globals.dom.elGraphical.add(l.elGridBorders)),Array.isArray(e.elGraph))for(var c=0;c0&&r.globals.memory.methodsToExec.forEach((function(t){t.method(t.params,!1,t.context)})),r.globals.axisCharts||r.globals.noData||n.core.resizeNonAxisCharts(),i(n)}))}},{key:"destroy",value:function(){var t,e;window.removeEventListener("resize",this.windowResizeHandler),this.el.parentNode,t=this.parentResizeHandler,(e=te.get(t))&&(e.disconnect(),te.delete(t));var n=this.w.config.chart.id;n&&Apex._chartInstances.forEach((function(t,e){t.id===S.escapeString(n)&&Apex._chartInstances.splice(e,1)})),new Qt(this.ctx).clear({isUpdating:!1})}},{key:"updateOptions",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],o=this.w;return o.globals.selection=void 0,t.series&&(this.series.resetSeries(!1,!0,!1),t.series.length&&t.series[0].data&&(t.series=t.series.map((function(t,n){return e.updateHelpers._extendSeries(t,n)}))),this.updateHelpers.revertDefaultAxisMinMax()),t.xaxis&&(t=this.updateHelpers.forceXAxisUpdate(t)),t.yaxis&&(t=this.updateHelpers.forceYAxisUpdate(t)),o.globals.collapsedSeriesIndices.length>0&&this.series.clearPreviousPaths(),t.theme&&(t=this.theme.updateThemeOptions(t)),this.updateHelpers._updateOptions(t,n,r,i,a)}},{key:"updateSeries",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.series.resetSeries(!1),this.updateHelpers.revertDefaultAxisMinMax(),this.updateHelpers._updateSeries(t,e,n)}},{key:"appendSeries",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=this.w.config.series.slice();return r.push(t),this.series.resetSeries(!1),this.updateHelpers.revertDefaultAxisMinMax(),this.updateHelpers._updateSeries(r,e,n)}},{key:"appendData",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this;n.w.globals.dataChanged=!0,n.series.getPreviousPaths();for(var r=n.w.config.series.slice(),i=0;i0&&void 0!==arguments[0])||arguments[0],e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.series.resetSeries(t,e)}},{key:"addEventListener",value:function(t,e){this.events.addEventListener(t,e)}},{key:"removeEventListener",value:function(t,e){this.events.removeEventListener(t,e)}},{key:"addXaxisAnnotation",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,r=this;n&&(r=n),r.annotations.addXaxisAnnotationExternal(t,e,r)}},{key:"addYaxisAnnotation",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,r=this;n&&(r=n),r.annotations.addYaxisAnnotationExternal(t,e,r)}},{key:"addPointAnnotation",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,r=this;n&&(r=n),r.annotations.addPointAnnotationExternal(t,e,r)}},{key:"clearAnnotations",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,e=this;t&&(e=t),e.annotations.clearAnnotations(e)}},{key:"removeAnnotation",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0,n=this;e&&(n=e),n.annotations.removeAnnotation(n,t)}},{key:"getChartArea",value:function(){return this.w.globals.dom.baseEl.querySelector(".apexcharts-inner")}},{key:"getSeriesTotalXRange",value:function(t,e){return this.coreUtils.getSeriesTotalsXRange(t,e)}},{key:"getHighestValueInSeries",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return new et(this.ctx).getMinYMaxY(t).highestY}},{key:"getLowestValueInSeries",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return new et(this.ctx).getMinYMaxY(t).lowestY}},{key:"getSeriesTotal",value:function(){return this.w.globals.seriesTotals}},{key:"toggleDataPointSelection",value:function(t,e){return this.updateHelpers.toggleDataPointSelection(t,e)}},{key:"zoomX",value:function(t,e){this.ctx.toolbar.zoomUpdateOptions(t,e)}},{key:"setLocale",value:function(t){this.localization.setCurrentLocaleValues(t)}},{key:"dataURI",value:function(t){return new K(this.ctx).dataURI(t)}},{key:"exportToCSV",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return new K(this.ctx).exportToCSV(t)}},{key:"paper",value:function(){return this.w.globals.dom.Paper}},{key:"_parentResizeCallback",value:function(){this.w.globals.animationEnded&&this.w.config.chart.redrawOnParentResize&&this._windowResize()}},{key:"_windowResize",value:function(){var t=this;clearTimeout(this.w.globals.resizeTimer),this.w.globals.resizeTimer=window.setTimeout((function(){t.w.globals.resized=!0,t.w.globals.dataChanged=!1,t.ctx.update()}),150)}},{key:"_windowResizeHandler",value:function(){var t=this.w.config.chart.redrawOnWindowResize;"function"==typeof t&&(t=t()),t&&this._windowResize()}}],[{key:"getChartByID",value:function(t){var e=S.escapeString(t);if(Apex._chartInstances){var n=Apex._chartInstances.filter((function(t){return t.id===e}))[0];return n&&n.chart}}},{key:"initOnLoad",value:function(){for(var e=document.querySelectorAll("[data-apexcharts]"),n=0;n2?i-2:0),o=2;o]*>)/g,s=/\$([$&'`]|\d{1,2})/g;t.exports=function(t,e,n,l,c,u){var h=n+t.length,d=l.length,f=s;return void 0!==c&&(c=r(c),f=o),a.call(u,f,(function(r,a){var o;switch(a.charAt(0)){case"$":return"$";case"&":return t;case"`":return e.slice(0,n);case"'":return e.slice(h);case"<":o=c[a.slice(1,-1)];break;default:var s=+a;if(0===s)return r;if(s>d){var u=i(s/10);return 0===u?r:u<=d?void 0===l[u-1]?a.charAt(1):l[u-1]+a.charAt(1):r}o=l[s-1]}return void 0===o?"":o}))}},"0cfb":function(t,e,n){var r=n("83ab"),i=n("d039"),a=n("cc12");t.exports=!r&&!i((function(){return 7!=Object.defineProperty(a("div"),"a",{get:function(){return 7}}).a}))},"0d24":function(t,e,n){(function(t){var r=n("2b3e"),i=n("07c7"),a=e&&!e.nodeType&&e,o=a&&"object"==typeof t&&t&&!t.nodeType&&t,s=o&&o.exports===a,l=s?r.Buffer:void 0,c=l?l.isBuffer:void 0,u=c||i;t.exports=u}).call(this,n("62e4")(t))},"0da5":function(t,e,n){var r=n("24fb");e=r(!1),e.push([t.i,".vc-nav-header{display:flex;justify-content:space-between}.vc-nav-arrow{display:flex;justify-content:center;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;line-height:var(--leading-snug);border-width:2px;border-style:solid;border-color:transparent;border-radius:var(--rounded)}.vc-nav-arrow.is-left{margin-right:auto}.vc-nav-arrow.is-right{margin-left:auto}.vc-nav-arrow.is-disabled{opacity:.25;pointer-events:none;cursor:not-allowed}.vc-nav-arrow:hover{background-color:var(--gray-900)}.vc-nav-arrow:focus{border-color:var(--accent-600)}.vc-nav-title{color:var(--accent-100);font-weight:var(--font-bold);line-height:var(--leading-snug);padding:4px 8px;border-radius:var(--rounded);border-width:2px;border-style:solid;border-color:transparent;-webkit-user-select:none;user-select:none}.vc-nav-title:hover{background-color:var(--gray-900)}.vc-nav-title:focus{border-color:var(--accent-600)}.vc-nav-items{display:grid;grid-template-columns:repeat(3,1fr);grid-row-gap:2px;grid-column-gap:5px}.vc-nav-item{width:48px;text-align:center;line-height:var(--leading-snug);font-weight:var(--font-semibold);padding:4px 0;cursor:pointer;border-color:transparent;border-width:2px;border-style:solid;border-radius:var(--rounded);-webkit-user-select:none;user-select:none}.vc-nav-item:hover{color:var(--white);background-color:var(--gray-900);box-shadow:var(--shadow-inner)}.vc-nav-item.is-active{color:var(--accent-900);background:var(--accent-100);font-weight:var(--font-bold);box-shadow:var(--shadow)}.vc-nav-item.is-current{color:var(--accent-100);font-weight:var(--bold);border-color:var(--accent-100)}.vc-nav-item:focus{border-color:var(--accent-600)}.vc-nav-item.is-disabled{opacity:.25;pointer-events:none}.vc-is-dark .vc-nav-title{color:var(--gray-900)}.vc-is-dark .vc-nav-title:hover{background-color:var(--gray-200)}.vc-is-dark .vc-nav-title:focus{border-color:var(--accent-400)}.vc-is-dark .vc-nav-arrow:hover{background-color:var(--gray-200)}.vc-is-dark .vc-nav-arrow:focus{border-color:var(--accent-400)}.vc-is-dark .vc-nav-item:hover{color:var(--gray-900);background-color:var(--gray-200);box-shadow:none}.vc-is-dark .vc-nav-item.is-active{color:var(--white);background:var(--accent-500)}.vc-is-dark .vc-nav-item.is-current{color:var(--accent-600);border-color:var(--accent-500)}.vc-is-dark .vc-nav-item:focus{border-color:var(--accent-400)}",""]),t.exports=e},"0f0f":function(t,e,n){var r=n("8eeb"),i=n("9934");function a(t,e){return t&&r(e,i(e),t)}t.exports=a},"0f5c":function(t,e,n){var r=n("159a");function i(t,e,n){return null==t?t:r(t,e,n)}t.exports=i},"0fb2":function(t,e,n){var r=n("24fb");e=r(!1),e.push([t.i,'.vc-popover-content-wrapper[data-v-39b30300]{--popover-horizontal-content-offset:8px;--popover-vertical-content-offset:10px;--popover-slide-translation:15px;--popover-transition-time:0.14s ease-in-out;--popover-caret-horizontal-offset:18px;--popover-caret-vertical-offset:8px;position:absolute;display:block;outline:none;z-index:10}.vc-popover-content-wrapper[data-v-39b30300]:not(.is-interactive){pointer-events:none}.vc-popover-content[data-v-39b30300]{position:relative;outline:none;z-index:10;box-shadow:var(--shadow-lg)}.vc-popover-content.direction-bottom[data-v-39b30300]{margin-top:var(--popover-vertical-content-offset)}.vc-popover-content.direction-top[data-v-39b30300]{margin-bottom:var(--popover-vertical-content-offset)}.vc-popover-content.direction-left[data-v-39b30300]{margin-right:var(--popover-horizontal-content-offset)}.vc-popover-content.direction-right[data-v-39b30300]{margin-left:var(--popover-horizontal-content-offset)}.vc-popover-caret[data-v-39b30300]{content:"";position:absolute;display:block;width:12px;height:12px;border-top:inherit;border-left:inherit;background-color:inherit;-webkit-user-select:none;user-select:none;z-index:-1}.vc-popover-caret.direction-bottom[data-v-39b30300]{top:0}.vc-popover-caret.direction-bottom.align-left[data-v-39b30300]{transform:translateY(-50%) rotate(45deg)}.vc-popover-caret.direction-bottom.align-center[data-v-39b30300]{transform:translateX(-50%) translateY(-50%) rotate(45deg)}.vc-popover-caret.direction-bottom.align-right[data-v-39b30300]{transform:translateY(-50%) rotate(45deg)}.vc-popover-caret.direction-top[data-v-39b30300]{top:100%}.vc-popover-caret.direction-top.align-left[data-v-39b30300]{transform:translateY(-50%) rotate(-135deg)}.vc-popover-caret.direction-top.align-center[data-v-39b30300]{transform:translateX(-50%) translateY(-50%) rotate(-135deg)}.vc-popover-caret.direction-top.align-right[data-v-39b30300]{transform:translateY(-50%) rotate(-135deg)}.vc-popover-caret.direction-left[data-v-39b30300]{left:100%}.vc-popover-caret.direction-left.align-top[data-v-39b30300]{transform:translateX(-50%) rotate(135deg)}.vc-popover-caret.direction-left.align-middle[data-v-39b30300]{transform:translateY(-50%) translateX(-50%) rotate(135deg)}.vc-popover-caret.direction-left.align-bottom[data-v-39b30300]{transform:translateX(-50%) rotate(135deg)}.vc-popover-caret.direction-right[data-v-39b30300]{left:0}.vc-popover-caret.direction-right.align-top[data-v-39b30300]{transform:translateX(-50%) rotate(-45deg)}.vc-popover-caret.direction-right.align-middle[data-v-39b30300]{transform:translateY(-50%) translateX(-50%) rotate(-45deg)}.vc-popover-caret.direction-right.align-bottom[data-v-39b30300]{transform:translateX(-50%) rotate(-45deg)}.vc-popover-caret.align-left[data-v-39b30300]{left:var(--popover-caret-horizontal-offset)}.vc-popover-caret.align-center[data-v-39b30300]{left:50%}.vc-popover-caret.align-right[data-v-39b30300]{right:var(--popover-caret-horizontal-offset)}.vc-popover-caret.align-top[data-v-39b30300]{top:var(--popover-caret-vertical-offset)}.vc-popover-caret.align-middle[data-v-39b30300]{top:50%}.vc-popover-caret.align-bottom[data-v-39b30300]{bottom:var(--popover-caret-vertical-offset)}.fade-enter-active[data-v-39b30300],.fade-leave-active[data-v-39b30300],.slide-fade-enter-active[data-v-39b30300],.slide-fade-leave-active[data-v-39b30300]{transition:all var(--popover-transition-time);pointer-events:none}.fade-enter[data-v-39b30300],.fade-leave-to[data-v-39b30300],.slide-fade-enter[data-v-39b30300],.slide-fade-leave-to[data-v-39b30300]{opacity:0}.slide-fade-enter.direction-bottom[data-v-39b30300],.slide-fade-leave-to.direction-bottom[data-v-39b30300]{transform:translateY(calc(var(--popover-slide-translation)*-1))}.slide-fade-enter.direction-top[data-v-39b30300],.slide-fade-leave-to.direction-top[data-v-39b30300]{transform:translateY(var(--popover-slide-translation))}.slide-fade-enter.direction-left[data-v-39b30300],.slide-fade-leave-to.direction-left[data-v-39b30300]{transform:translateX(var(--popover-slide-translation))}.slide-fade-enter.direction-right[data-v-39b30300],.slide-fade-leave-to.direction-right[data-v-39b30300]{transform:translateX(calc(var(--popover-slide-translation)*-1))}',""]),t.exports=e},"100e":function(t,e,n){var r=n("cd9d"),i=n("2286"),a=n("c1c9");function o(t,e){return a(i(t,e,r),t+"")}t.exports=o},1041:function(t,e,n){var r=n("8eeb"),i=n("a029");function a(t,e){return r(t,i(t),e)}t.exports=a},"107c":function(t,e,n){var r=n("d039");t.exports=r((function(){var t=RegExp("(?b)","string".charAt(5));return"b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$c")}))},1290:function(t,e){function n(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t}t.exports=n},1310:function(t,e){function n(t){return null!=t&&"object"==typeof t}t.exports=n},1368:function(t,e,n){var r=n("da03"),i=function(){var t=/[^.]+$/.exec(r&&r.keys&&r.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();function a(t){return!!i&&i in t}t.exports=a},"14c3":function(t,e,n){var r=n("c6b6"),i=n("9263");t.exports=function(t,e){var n=t.exec;if("function"===typeof n){var a=n.call(t,e);if("object"!==typeof a)throw TypeError("RegExp exec method returned something other than an Object or null");return a}if("RegExp"!==r(t))throw TypeError("RegExp#exec called on incompatible receiver");return i.call(t,e)}},"159a":function(t,e,n){var r=n("32b3"),i=n("e2e4"),a=n("c098"),o=n("1a8c"),s=n("f4d6");function l(t,e,n,l){if(!o(t))return t;e=i(e,t);var c=-1,u=e.length,h=u-1,d=t;while(null!=d&&++ci?0:i+e),n=n>i?i:n,n<0&&(n+=i),i=e>n?0:n-e>>>0,e>>>=0;var a=Array(i);while(++r=74)&&(r=o.match(/Chrome\/(\d+)/),r&&(i=r[1]))),t.exports=i&&+i},"2d7c":function(t,e){function n(t,e){var n=-1,r=null==t?0:t.length,i=0,a=[];while(++n1?n[a-1]:void 0,s=a>2?n[2]:void 0;o=t.length>3&&"function"==typeof o?(a--,o):void 0,s&&i(n[0],n[1],s)&&(o=a<3?void 0:o,a=1),e=Object(e);while(++rl)i.f(t,n=r[l++],e[n]);return t}},3818:function(t,e,n){var r=n("7e64"),i=n("8057"),a=n("32b3"),o=n("5b01"),s=n("0f0f"),l=n("e538"),c=n("4359"),u=n("54eb"),h=n("1041"),d=n("a994"),f=n("1bac"),p=n("42a2"),v=n("c87c"),g=n("c2b6"),m=n("fa21"),y=n("6747"),b=n("0d24"),x=n("cc45"),w=n("1a8c"),k=n("d7ee"),S=n("ec69"),C=n("9934"),A=1,_=2,D=4,T="[object Arguments]",E="[object Array]",O="[object Boolean]",P="[object Date]",I="[object Error]",M="[object Function]",V="[object GeneratorFunction]",L="[object Map]",j="[object Number]",B="[object Object]",R="[object RegExp]",F="[object Set]",N="[object String]",z="[object Symbol]",$="[object WeakMap]",Y="[object ArrayBuffer]",H="[object DataView]",W="[object Float32Array]",X="[object Float64Array]",G="[object Int8Array]",U="[object Int16Array]",q="[object Int32Array]",Z="[object Uint8Array]",K="[object Uint8ClampedArray]",J="[object Uint16Array]",Q="[object Uint32Array]",tt={};function et(t,e,n,E,O,P){var I,L=e&A,j=e&_,R=e&D;if(n&&(I=O?n(t,E,O,P):n(t)),void 0!==I)return I;if(!w(t))return t;var F=y(t);if(F){if(I=v(t),!L)return c(t,I)}else{var N=p(t),z=N==M||N==V;if(b(t))return l(t,L);if(N==B||N==T||z&&!O){if(I=j||z?{}:m(t),!L)return j?h(t,s(I,t)):u(t,o(I,t))}else{if(!tt[N])return O?t:{};I=g(t,N,L)}}P||(P=new r);var $=P.get(t);if($)return $;P.set(t,I),k(t)?t.forEach((function(r){I.add(et(r,e,n,r,t,P))})):x(t)&&t.forEach((function(r,i){I.set(i,et(r,e,n,i,t,P))}));var Y=R?j?f:d:j?C:S,H=F?void 0:Y(t);return i(H||t,(function(r,i){H&&(i=r,r=t[i]),a(I,i,et(r,e,n,i,t,P))})),I}tt[T]=tt[E]=tt[Y]=tt[H]=tt[O]=tt[P]=tt[W]=tt[X]=tt[G]=tt[U]=tt[q]=tt[L]=tt[j]=tt[B]=tt[R]=tt[F]=tt[N]=tt[z]=tt[Z]=tt[K]=tt[J]=tt[Q]=!0,tt[I]=tt[M]=tt[$]=!1,t.exports=et},3852:function(t,e,n){var r=n("96f3"),i=n("e2c0");function a(t,e){return null!=t&&i(t,e,r)}t.exports=a},"39ff":function(t,e,n){var r=n("0b07"),i=n("2b3e"),a=r(i,"WeakMap");t.exports=a},"3b4a":function(t,e,n){var r=n("0b07"),i=function(){try{var t=r(Object,"defineProperty");return t({},"",{}),t}catch(e){}}();t.exports=i},"3bb4":function(t,e,n){var r=n("08cc"),i=n("ec69");function a(t){var e=i(t),n=e.length;while(n--){var a=e[n],o=t[a];e[n]=[a,o,r(o)]}return e}t.exports=a},"3bbe":function(t,e,n){var r=n("861d");t.exports=function(t){if(!r(t)&&null!==t)throw TypeError("Can't set "+String(t)+" as a prototype");return t}},"3c55":function(t,e,n){"use strict";var r=n("e969"),i=n.n(r);i.a},"3db9":function(t,e,n){var r=n("adc8");"string"===typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);var i=n("499e").default;i("2b7f9a9d",r,!0,{sourceMap:!1,shadowMode:!1})},"3ee2":function(t,e,n){var r=n("dc8c");"string"===typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);var i=n("499e").default;i("13d41af5",r,!0,{sourceMap:!1,shadowMode:!1})},"3eea":function(t,e,n){var r=n("7948"),i=n("3818"),a=n("4bb5"),o=n("e2e4"),s=n("8eeb"),l=n("e0e7"),c=n("c6cf"),u=n("1bac"),h=1,d=2,f=4,p=c((function(t,e){var n={};if(null==t)return n;var c=!1;e=r(e,(function(e){return e=o(e,t),c||(c=e.length>1),e})),s(t,u(t),n),c&&(n=i(n,h|d|f,l));var p=e.length;while(p--)a(n,e[p]);return n}));t.exports=p},"3f84":function(t,e,n){var r=n("85e3"),i=n("100e"),a=n("e031"),o=n("2411"),s=i((function(t){return t.push(void 0,a),r(o,void 0,t)}));t.exports=s},"3f8c":function(t,e){t.exports={}},"41c3":function(t,e,n){var r=n("1a8c"),i=n("eac5"),a=n("ec8c"),o=Object.prototype,s=o.hasOwnProperty;function l(t){if(!r(t))return a(t);var e=i(t),n=[];for(var o in t)("constructor"!=o||!e&&s.call(t,o))&&n.push(o);return n}t.exports=l},4245:function(t,e,n){var r=n("1290");function i(t,e){var n=t.__data__;return r(e)?n["string"==typeof e?"string":"hash"]:n.map}t.exports=i},4284:function(t,e){function n(t,e){var n=-1,r=null==t?0:t.length;while(++nn.parts.length&&(r.parts.length=n.parts.length)}else{var o=[];for(i=0;iu)if(s=l[u++],s!=s)return!0}else for(;c>u;u++)if((t||u in l)&&l[u]===n)return t||u||0;return!t&&-1}};t.exports={includes:o(!0),indexOf:o(!1)}},"4d8c":function(t,e,n){var r=n("5c69");function i(t){var e=null==t?0:t.length;return e?r(t,1):[]}t.exports=i},"4f50":function(t,e,n){var r=n("b760"),i=n("e538"),a=n("c8fe"),o=n("4359"),s=n("fa21"),l=n("d370"),c=n("6747"),u=n("dcbe"),h=n("0d24"),d=n("9520"),f=n("1a8c"),p=n("60ed"),v=n("73ac"),g=n("8adb"),m=n("8de2");function y(t,e,n,y,b,x,w){var k=g(t,n),S=g(e,n),C=w.get(S);if(C)r(t,n,C);else{var A=x?x(k,S,n+"",t,e,w):void 0,_=void 0===A;if(_){var D=c(S),T=!D&&h(S),E=!D&&!T&&v(S);A=S,D||T||E?c(k)?A=k:u(k)?A=o(k):T?(_=!1,A=i(S,!0)):E?(_=!1,A=a(S,!0)):A=[]:p(S)||l(S)?(A=k,l(k)?A=m(k):f(k)&&!d(k)||(A=s(S))):_=!1}_&&(w.set(S,A),b(A,S,y,x,w),w["delete"](S)),r(t,n,A)}}t.exports=y},"501e":function(t,e,n){var r=n("3729"),i=n("1310"),a="[object Number]";function o(t){return"number"==typeof t||i(t)&&r(t)==a}t.exports=o},"50c4":function(t,e,n){var r=n("a691"),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},"50d8":function(t,e){function n(t,e){var n=-1,r=Array(t);while(++n")}));r("replace",(function(t,e,n){var r=y?"$":"$0";return[function(t,n){var r=l(this),i=void 0==t?void 0:t[f];return void 0!==i?i.call(t,r,n):e.call(String(r),t,n)},function(t,i){if("string"===typeof i&&-1===i.indexOf(r)&&-1===i.indexOf("$<")){var l=n(e,this,t,i);if(l.done)return l.value}var d=a(this),f=String(t),m="function"===typeof i;m||(i=String(i));var y=d.global;if(y){var b=d.unicode;d.lastIndex=0}var x=[];while(1){var w=h(d,f);if(null===w)break;if(x.push(w),!y)break;var k=String(w[0]);""===k&&(d.lastIndex=c(f,o(d.lastIndex),b))}for(var S="",C=0,A=0;A=C&&(S+=f.slice(C,D)+I,C=D+_.length)}return S+f.slice(C)}]}),!b||!m||y)},"53b1":function(t,e,n){var r=n("495a");"string"===typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);var i=n("499e").default;i("2a6e04f4",r,!0,{sourceMap:!1,shadowMode:!1})},"54eb":function(t,e,n){var r=n("8eeb"),i=n("32f4");function a(t,e){return r(t,i(t),e)}t.exports=a},"55a3":function(t,e){function n(t){return this.__data__.has(t)}t.exports=n},5692:function(t,e,n){var r=n("c430"),i=n("c6cd");(t.exports=function(t,e){return i[t]||(i[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.15.2",mode:r?"pure":"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"})},"56ef":function(t,e,n){var r=n("d066"),i=n("241c"),a=n("7418"),o=n("825a");t.exports=r("Reflect","ownKeys")||function(t){var e=i.f(o(t)),n=a.f;return n?e.concat(n(t)):e}},"57a5":function(t,e,n){var r=n("91e9"),i=r(Object.keys,Object);t.exports=i},"585a":function(t,e,n){(function(e){var n="object"==typeof e&&e&&e.Object===Object&&e;t.exports=n}).call(this,n("c8ba"))},"5b01":function(t,e,n){var r=n("8eeb"),i=n("ec69");function a(t,e){return t&&r(e,i(e),t)}t.exports=a},"5c69":function(t,e,n){var r=n("087d"),i=n("0621");function a(t,e,n,o,s){var l=-1,c=t.length;n||(n=i),s||(s=[]);while(++l0&&n(u)?e>1?a(u,e-1,n,o,s):r(s,u):o||(s[s.length]=u)}return s}t.exports=a},"5c6c":function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},"5d89":function(t,e,n){var r=n("f8af");function i(t,e){var n=e?r(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)}t.exports=i},"5e2e":function(t,e,n){var r=n("28c9"),i=n("69d5"),a=n("b4c0"),o=n("fba5"),s=n("67ca");function l(t){var e=-1,n=null==t?0:t.length;this.clear();while(++e=c?t?"":void 0:(a=s.charCodeAt(l),a<55296||a>56319||l+1===c||(o=s.charCodeAt(l+1))<56320||o>57343?t?s.charAt(l):a:t?s.slice(l,l+2):o-56320+(a-55296<<10)+65536)}};t.exports={codeAt:a(!1),charAt:a(!0)}},"656b":function(t,e,n){var r=n("e2e4"),i=n("f4d6");function a(t,e){e=r(e,t);var n=0,a=e.length;while(null!=t&&n",d="<",f="prototype",p="script",v=u("IE_PROTO"),g=function(){},m=function(t){return d+p+h+t+d+"/"+p+h},y=function(t){t.write(m("")),t.close();var e=t.parentWindow.Object;return t=null,e},b=function(){var t,e=c("iframe"),n="java"+p+":";return e.style.display="none",l.appendChild(e),e.src=String(n),t=e.contentWindow.document,t.open(),t.write(m("document.F=Object")),t.close(),t.F},x=function(){try{r=document.domain&&new ActiveXObject("htmlfile")}catch(e){}x=r?y(r):b();var t=o.length;while(t--)delete x[f][o[t]];return x()};s[v]=!0,t.exports=Object.create||function(t,e){var n;return null!==t?(g[f]=i(t),n=new g,g[f]=null,n[v]=t):n=x(),void 0===e?n:a(n,e)}},"7d1f":function(t,e,n){var r=n("087d"),i=n("6747");function a(t,e,n){var a=e(t);return i(t)?a:r(a,n(t))}t.exports=a},"7dd0":function(t,e,n){"use strict";var r=n("23e7"),i=n("9ed3"),a=n("e163"),o=n("d2bb"),s=n("d44e"),l=n("9112"),c=n("6eeb"),u=n("b622"),h=n("c430"),d=n("3f8c"),f=n("ae93"),p=f.IteratorPrototype,v=f.BUGGY_SAFARI_ITERATORS,g=u("iterator"),m="keys",y="values",b="entries",x=function(){return this};t.exports=function(t,e,n,u,f,w,k){i(n,e,u);var S,C,A,_=function(t){if(t===f&&P)return P;if(!v&&t in E)return E[t];switch(t){case m:return function(){return new n(this,t)};case y:return function(){return new n(this,t)};case b:return function(){return new n(this,t)}}return function(){return new n(this)}},D=e+" Iterator",T=!1,E=t.prototype,O=E[g]||E["@@iterator"]||f&&E[f],P=!v&&O||_(f),I="Array"==e&&E.entries||O;if(I&&(S=a(I.call(new t)),p!==Object.prototype&&S.next&&(h||a(S)===p||(o?o(S,p):"function"!=typeof S[g]&&l(S,g,x)),s(S,D,!0,!0),h&&(d[D]=x))),f==y&&O&&O.name!==y&&(T=!0,P=function(){return O.call(this)}),h&&!k||E[g]===P||l(E,g,P),d[e]=P,f)if(C={values:_(y),keys:w?P:_(m),entries:_(b)},k)for(A in C)(v||T||!(A in E))&&c(E,A,C[A]);else r({target:e,proto:!0,forced:v||T},C);return C}},"7dfe":function(t,e,n){var r=n("24fb");e=r(!1),e.push([t.i,".none-enter-active[data-v-5be4b00c],.none-leave-active[data-v-5be4b00c]{transition-duration:0s}.fade-enter-active[data-v-5be4b00c],.fade-leave-active[data-v-5be4b00c],.slide-down-enter-active[data-v-5be4b00c],.slide-down-leave-active[data-v-5be4b00c],.slide-left-enter-active[data-v-5be4b00c],.slide-left-leave-active[data-v-5be4b00c],.slide-right-enter-active[data-v-5be4b00c],.slide-right-leave-active[data-v-5be4b00c],.slide-up-enter-active[data-v-5be4b00c],.slide-up-leave-active[data-v-5be4b00c]{transition:transform var(--slide-duration) var(--slide-timing),opacity var(--slide-duration) var(--slide-timing);-webkit-backface-visibility:hidden;backface-visibility:hidden}.fade-leave-active[data-v-5be4b00c],.none-leave-active[data-v-5be4b00c],.slide-down-leave-active[data-v-5be4b00c],.slide-left-leave-active[data-v-5be4b00c],.slide-right-leave-active[data-v-5be4b00c],.slide-up-leave-active[data-v-5be4b00c]{position:absolute;width:100%}.fade-enter[data-v-5be4b00c],.fade-leave-to[data-v-5be4b00c],.none-enter[data-v-5be4b00c],.none-leave-to[data-v-5be4b00c],.slide-down-enter[data-v-5be4b00c],.slide-down-leave-to[data-v-5be4b00c],.slide-left-enter[data-v-5be4b00c],.slide-left-leave-to[data-v-5be4b00c],.slide-right-enter[data-v-5be4b00c],.slide-right-leave-to[data-v-5be4b00c],.slide-up-enter[data-v-5be4b00c],.slide-up-leave-to[data-v-5be4b00c]{opacity:0}.slide-left-enter[data-v-5be4b00c],.slide-right-leave-to[data-v-5be4b00c]{transform:translateX(var(--slide-translate))}.slide-left-leave-to[data-v-5be4b00c],.slide-right-enter[data-v-5be4b00c]{transform:translateX(calc(var(--slide-translate)*-1))}.slide-down-leave-to[data-v-5be4b00c],.slide-up-enter[data-v-5be4b00c]{transform:translateY(var(--slide-translate))}.slide-down-enter[data-v-5be4b00c],.slide-up-leave-to[data-v-5be4b00c]{transform:translateY(calc(var(--slide-translate)*-1))}",""]),t.exports=e},"7e64":function(t,e,n){var r=n("5e2e"),i=n("efb6"),a=n("2fcc"),o=n("802a"),s=n("55a3"),l=n("d02c");function c(t){var e=this.__data__=new r(t);this.size=e.size}c.prototype.clear=i,c.prototype["delete"]=a,c.prototype.get=o,c.prototype.has=s,c.prototype.set=l,t.exports=c},"7ed2":function(t,e){var n="__lodash_hash_undefined__";function r(t){return this.__data__.set(t,n),this}t.exports=r},"7efe":function(t){t.exports=JSON.parse('{"title":"MMMM YYYY","weekdays":"W","navMonths":"MMM","input":["L","YYYY-MM-DD","YYYY/MM/DD"],"inputDateTime":["L h:mm A","YYYY-MM-DD h:mm A","YYYY/MM/DD h:mm A"],"inputDateTime24hr":["L HH:mm","YYYY-MM-DD HH:mm","YYYY/MM/DD HH:mm"],"inputTime":["h:mm A"],"inputTime24hr":["HH:mm"],"dayPopover":"WWW, MMM D, YYYY","data":["L","YYYY-MM-DD","YYYY/MM/DD"],"iso":"YYYY-MM-DDTHH:mm:ss.SSSZ"}')},"7f9a":function(t,e,n){var r=n("da84"),i=n("8925"),a=r.WeakMap;t.exports="function"===typeof a&&/native code/.test(i(a))},"802a":function(t,e){function n(t){return this.__data__.get(t)}t.exports=n},8057:function(t,e){function n(t,e){var n=-1,r=null==t?0:t.length;while(++n=e?t:e)),t}t.exports=n},"83ab":function(t,e,n){var r=n("d039");t.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},"85a9":function(t){t.exports=JSON.parse('{"sm":"640px","md":"768px","lg":"1024px","xl":"1280px"}')},"85e3":function(t,e){function n(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}t.exports=n},8604:function(t,e,n){var r=n("26e8"),i=n("e2c0");function a(t,e){return null!=t&&i(t,e,r)}t.exports=a},"861d":function(t,e){t.exports=function(t){return"object"===typeof t?null!==t:"function"===typeof t}},"872a":function(t,e,n){var r=n("3b4a");function i(t,e,n){"__proto__"==e&&r?r(t,e,{configurable:!0,enumerable:!0,value:n,writable:!0}):t[e]=n}t.exports=i},"87a9":function(t,e,n){"use strict";var r=n("cecd"),i=n.n(r);i.a},8925:function(t,e,n){var r=n("c6cd"),i=Function.toString;"function"!=typeof r.inspectSource&&(r.inspectSource=function(t){return i.call(t)}),t.exports=r.inspectSource},"89d9":function(t,e,n){var r=n("656b"),i=n("159a"),a=n("e2e4");function o(t,e,n){var o=-1,s=e.length,l={};while(++o0&&(!m.multiline||m.multiline&&"\n"!==t[m.lastIndex-1])&&(S="(?: "+S+")",A=" "+A,C++),n=new RegExp("^(?:"+S+")",k)),v&&(n=new RegExp("^"+S+"$(?!\\s)",k)),f&&(i=m.lastIndex),a=u.call(w?n:m,A),w?a?(a.input=a.input.slice(C),a[0]=a[0].slice(C),a.index=m.lastIndex,m.lastIndex+=a[0].length):m.lastIndex=0:f&&a&&(m.lastIndex=m.global?a.index+a[0].length:i),v&&a&&a.length>1&&h.call(a[0],n,(function(){for(l=1;l2?e[2]:void 0;c&&a(e[0],e[1],c)&&(r=1);while(++nd))return!1;var p=u.get(t),v=u.get(e);if(p&&v)return p==e&&v==t;var g=-1,m=!0,y=n&s?new r:void 0;u.set(t,e),u.set(e,t);while(++g0?r:n)(t)}},a994:function(t,e,n){var r=n("7d1f"),i=n("32f4"),a=n("ec69");function o(t){return r(t,a,i)}t.exports=o},ac1f:function(t,e,n){"use strict";var r=n("23e7"),i=n("9263");r({target:"RegExp",proto:!0,forced:/./.exec!==i},{exec:i})},ac41:function(t,e){function n(t){var e=-1,n=Array(t.size);return t.forEach((function(t){n[++e]=t})),n}t.exports=n},ad6d:function(t,e,n){"use strict";var r=n("825a");t.exports=function(){var t=r(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.dotAll&&(e+="s"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},ad82:function(t,e,n){var r=n("24fb");e=r(!1),e.push([t.i,".vc-time-picker[data-v-f4e11af8]{display:flex;align-items:center;padding:8px}.vc-time-picker.vc-invalid[data-v-f4e11af8]{pointer-events:none;opacity:.5}.vc-time-picker.vc-bordered[data-v-f4e11af8]{border-top:1px solid var(--gray-400)}.vc-date-time[data-v-f4e11af8]{margin-left:8px}.vc-disabled[data-v-f4e11af8]{pointer-events:none;opacity:.5}.vc-time-icon[data-v-f4e11af8]{width:16px;height:16px;color:var(--gray-600)}.vc-date[data-v-f4e11af8]{display:flex;align-items:center;font-size:var(--text-sm);font-weight:var(--font-semibold);text-transform:uppercase;padding:0 0 4px 4px;margin-top:-4px}.vc-date .vc-weekday[data-v-f4e11af8]{color:var(--gray-700);letter-spacing:var(--tracking-wide)}.vc-date .vc-month[data-v-f4e11af8]{color:var(--accent-600);margin-left:8px}.vc-date .vc-day[data-v-f4e11af8]{color:var(--accent-600);margin-left:4px}.vc-date .vc-year[data-v-f4e11af8]{color:var(--gray-500);margin-left:8px}.vc-am-pm[data-v-f4e11af8],.vc-time[data-v-f4e11af8]{display:flex;align-items:center}.vc-am-pm[data-v-f4e11af8]{background:var(--gray-200);margin-left:8px;padding:4px;border-radius:var(--rounded);height:30px}.vc-am-pm button[data-v-f4e11af8]{color:var(--gray-900);font-size:var(--text-sm);font-weight:var(--font-medium);padding:0 4px;background:transparent;border:2px solid transparent;border-radius:var(--rounded);line-height:var(--leading-snug)}.vc-am-pm button[data-v-f4e11af8]:hover{color:var(--gray-600)}.vc-am-pm button[data-v-f4e11af8]:focus{border-color:var(--accent-400)}.vc-am-pm button.active[data-v-f4e11af8]{background:var(--accent-600);color:var(--white)}.vc-am-pm button.active[data-v-f4e11af8]:hover{background:var(--accent-500)}.vc-am-pm button.active[data-v-f4e11af8]:focus{border-color:var(--accent-400)}.vc-is-dark .vc-time-picker[data-v-f4e11af8]{border-color:var(--gray-700)}.vc-is-dark .vc-time-icon[data-v-f4e11af8],.vc-is-dark .vc-weekday[data-v-f4e11af8]{color:var(--gray-400)}.vc-is-dark .vc-day[data-v-f4e11af8],.vc-is-dark .vc-month[data-v-f4e11af8]{color:var(--accent-400)}.vc-is-dark .vc-year[data-v-f4e11af8]{color:var(--gray-500)}.vc-is-dark .vc-am-pm[data-v-f4e11af8]{background:var(--gray-700)}.vc-is-dark .vc-am-pm[data-v-f4e11af8]:focus{border-color:var(--accent-500)}.vc-is-dark .vc-am-pm button[data-v-f4e11af8]{color:var(--gray-100)}.vc-is-dark .vc-am-pm button[data-v-f4e11af8]:hover{color:var(--gray-400)}.vc-is-dark .vc-am-pm button[data-v-f4e11af8]:focus{border-color:var(--accent-500)}.vc-is-dark .vc-am-pm button.active[data-v-f4e11af8]{background:var(--accent-500);color:var(--white)}.vc-is-dark .vc-am-pm button.active[data-v-f4e11af8]:hover{background:var(--accent-600)}.vc-is-dark .vc-am-pm button.active[data-v-f4e11af8]:focus{border-color:var(--accent-500)}",""]),t.exports=e},adc8:function(t,e,n){var r=n("24fb");e=r(!1),e.push([t.i,".vc-day-popover-row[data-v-eb5afd1a]{--day-content-transition-time:0.13s ease-in;display:flex;align-items:center;transition:all var(--day-content-transition-time)}.vc-day-popover-row[data-v-eb5afd1a]:not(:first-child){margin-top:3px}.vc-day-popover-row-indicator[data-v-eb5afd1a]{display:flex;justify-content:center;align-items:center;flex-grow:0;width:15px;margin-right:3px}.vc-day-popover-row-indicator span[data-v-eb5afd1a]{transition:all var(--day-content-transition-time)}.vc-day-popover-row-content[data-v-eb5afd1a]{display:flex;align-items:center;flex-wrap:none;flex-grow:1;width:max-content}",""]),t.exports=e},ae93:function(t,e,n){"use strict";var r,i,a,o=n("d039"),s=n("e163"),l=n("9112"),c=n("5135"),u=n("b622"),h=n("c430"),d=u("iterator"),f=!1,p=function(){return this};[].keys&&(a=[].keys(),"next"in a?(i=s(s(a)),i!==Object.prototype&&(r=i)):f=!0);var v=void 0==r||o((function(){var t={};return r[d].call(t)!==t}));v&&(r={}),h&&!v||c(r,d)||l(r,d,p),t.exports={IteratorPrototype:r,BUGGY_SAFARI_ITERATORS:f}},b047:function(t,e){function n(t){return function(e){return t(e)}}t.exports=n},b1d2:function(t,e,n){var r=n("3729"),i=n("1310"),a="[object Date]";function o(t){return i(t)&&r(t)==a}t.exports=o},b1e5:function(t,e,n){var r=n("a994"),i=1,a=Object.prototype,o=a.hasOwnProperty;function s(t,e,n,a,s,l){var c=n&i,u=r(t),h=u.length,d=r(e),f=d.length;if(h!=f&&!c)return!1;var p=h;while(p--){var v=u[p];if(!(c?v in e:o.call(e,v)))return!1}var g=l.get(t),m=l.get(e);if(g&&m)return g==e&&m==t;var y=!0;l.set(t,e),l.set(e,t);var b=c;while(++p-1&&t%1==0&&t<=n}t.exports=r},b4b0:function(t,e,n){var r=n("8d74"),i=n("1a8c"),a=n("ffd6"),o=NaN,s=/^[-+]0x[0-9a-f]+$/i,l=/^0b[01]+$/i,c=/^0o[0-7]+$/i,u=parseInt;function h(t){if("number"==typeof t)return t;if(a(t))return o;if(i(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=i(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=r(t);var n=l.test(t);return n||c.test(t)?u(t.slice(2),n?2:8):s.test(t)?o:+t}t.exports=h},b4c0:function(t,e,n){var r=n("cb5a");function i(t){var e=this.__data__,n=r(e,t);return n<0?void 0:e[n][1]}t.exports=i},b5a7:function(t,e,n){var r=n("0b07"),i=n("2b3e"),a=r(i,"DataView");t.exports=a},b622:function(t,e,n){var r=n("da84"),i=n("5692"),a=n("5135"),o=n("90e3"),s=n("4930"),l=n("fdbf"),c=i("wks"),u=r.Symbol,h=l?u:u&&u.withoutSetter||o;t.exports=function(t){return a(c,t)&&(s||"string"==typeof c[t])||(s&&a(u,t)?c[t]=u[t]:c[t]=h("Symbol."+t)),c[t]}},b760:function(t,e,n){var r=n("872a"),i=n("9638");function a(t,e,n){(void 0!==n&&!i(t[e],n)||void 0===n&&!(e in t))&&r(t,e,n)}t.exports=a},badf:function(t,e,n){var r=n("642a"),i=n("1838"),a=n("cd9d"),o=n("6747"),s=n("f9ce");function l(t){return"function"==typeof t?t:null==t?a:"object"==typeof t?o(t)?i(t[0],t[1]):r(t):s(t)}t.exports=l},bbc0:function(t,e,n){var r=n("6044"),i="__lodash_hash_undefined__",a=Object.prototype,o=a.hasOwnProperty;function s(t){var e=this.__data__;if(r){var n=e[t];return n===i?void 0:n}return o.call(e,t)?e[t]:void 0}t.exports=s},bdb3:function(t,e,n){"use strict";var r=n("e052"),i=n.n(r);i.a},c04e:function(t,e,n){var r=n("861d");t.exports=function(t,e){if(!r(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!r(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},c05f:function(t,e,n){var r=n("7b97"),i=n("1310");function a(t,e,n,o,s){return t===e||(null==t||null==e||!i(t)&&!i(e)?t!==t&&e!==e:r(t,e,n,o,a,s))}t.exports=a},c098:function(t,e){var n=9007199254740991,r=/^(?:0|[1-9]\d*)$/;function i(t,e){var i=typeof t;return e=null==e?n:e,!!e&&("number"==i||"symbol"!=i&&r.test(t))&&t>-1&&t%1==0&&tl)r(s,n=e[l++])&&(~a(c,n)||c.push(n));return c}},cb5a:function(t,e,n){var r=n("9638");function i(t,e){var n=t.length;while(n--)if(r(t[n][0],e))return n;return-1}t.exports=i},cc12:function(t,e,n){var r=n("da84"),i=n("861d"),a=r.document,o=i(a)&&i(a.createElement);t.exports=function(t){return o?a.createElement(t):{}}},cc45:function(t,e,n){var r=n("1a2d"),i=n("b047"),a=n("99d3"),o=a&&a.isMap,s=o?i(o):r;t.exports=s},cd9d:function(t,e){function n(t){return t}t.exports=n},ce4e:function(t,e,n){var r=n("da84"),i=n("9112");t.exports=function(t,e){try{i(r,t,e)}catch(n){r[t]=e}return e}},ce86:function(t,e,n){var r=n("9e69"),i=n("7948"),a=n("6747"),o=n("ffd6"),s=1/0,l=r?r.prototype:void 0,c=l?l.toString:void 0;function u(t){if("string"==typeof t)return t;if(a(t))return i(t,u)+"";if(o(t))return c?c.call(t):"";var e=t+"";return"0"==e&&1/t==-s?"-0":e}t.exports=u},cebd:function(t,e){function n(t){var e=-1,n=Array(t.size);return t.forEach((function(t){n[++e]=[t,t]})),n}t.exports=n},cecd:function(t,e,n){var r=n("2202");"string"===typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);var i=n("499e").default;i("8c0a5c0c",r,!0,{sourceMap:!1,shadowMode:!1})},d012:function(t,e){t.exports={}},d02c:function(t,e,n){var r=n("5e2e"),i=n("79bc"),a=n("7b83"),o=200;function s(t,e){var n=this.__data__;if(n instanceof r){var s=n.__data__;if(!i||s.length=e.length?(t.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:r,done:!1}:"values"==n?{value:e[r],done:!1}:{value:[r,e[r]],done:!1}}),"values"),a.Arguments=a.Array,i("keys"),i("values"),i("entries")},e2a0:function(t,e,n){var r=n("3729"),i=n("6747"),a=n("1310"),o="[object String]";function s(t){return"string"==typeof t||!i(t)&&a(t)&&r(t)==o}t.exports=s},e2c0:function(t,e,n){var r=n("e2e4"),i=n("d370"),a=n("6747"),o=n("c098"),s=n("b218"),l=n("f4d6");function c(t,e,n){e=r(e,t);var c=-1,u=e.length,h=!1;while(++c0){if(++e>=n)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}t.exports=a},f4d6:function(t,e,n){var r=n("ffd6"),i=1/0;function a(t){if("string"==typeof t||r(t))return t;var e=t+"";return"0"==e&&1/t==-i?"-0":e}t.exports=a},f542:function(t,e,n){var r=n("ec47"),i=n("ec69"),a=r(i);t.exports=a},f608:function(t,e,n){var r=n("6747"),i=n("ffd6"),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,o=/^\w*$/;function s(t,e){if(r(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!i(t))||(o.test(t)||!a.test(t)||null!=e&&t in Object(e))}t.exports=s},f678:function(t,e,n){var r=n("8384"),i=n("b4b0");function a(t,e,n){return void 0===n&&(n=e,e=void 0),void 0!==n&&(n=i(n),n=n===n?n:0),void 0!==e&&(e=i(e),e=e===e?e:0),r(i(t),e,n)}t.exports=a},f772:function(t,e,n){var r=n("5692"),i=n("90e3"),a=r("keys");t.exports=function(t){return a[t]||(a[t]=i(t))}},f8af:function(t,e,n){var r=n("2474");function i(t){var e=new t.constructor(t.byteLength);return new r(e).set(new r(t)),e}t.exports=i},f909:function(t,e,n){var r=n("7e64"),i=n("b760"),a=n("72af"),o=n("4f50"),s=n("1a8c"),l=n("9934"),c=n("8adb");function u(t,e,n,h,d){t!==e&&a(e,(function(a,l){if(d||(d=new r),s(a))o(t,e,l,n,u,h,d);else{var f=h?h(c(t,l),a,l+"",t,e,d):void 0;void 0===f&&(f=a),i(t,l,f)}}),l)}t.exports=u},f9ce:function(t,e,n){var r=n("ef5d"),i=n("e3f8"),a=n("f608"),o=n("f4d6");function s(t){return a(t)?r(o(t)):i(t)}t.exports=s},fa21:function(t,e,n){var r=n("7530"),i=n("2dcb"),a=n("eac5");function o(t){return"function"!=typeof t.constructor||a(t)?{}:r(i(t))}t.exports=o},fb15:function(t,e,n){"use strict";if(n.r(e),"undefined"!==typeof window){var r=window.document.currentScript,i=r&&r.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);i&&(n.p=i[1])}n("ddb0");function a(t){if(null===t||!0===t||!1===t)return NaN;var e=Number(t);return isNaN(e)?e:e<0?Math.ceil(e):Math.floor(e)}function o(t,e){if(e.length1?"s":"")+" required, but only "+e.length+" present")}function s(t){o(1,arguments);var e=Object.prototype.toString.call(t);return t instanceof Date||"object"===typeof t&&"[object Date]"===e?new Date(t.getTime()):"number"===typeof t||"[object Number]"===e?new Date(t):("string"!==typeof t&&"[object String]"!==e||"undefined"===typeof console||(console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule"),console.warn((new Error).stack)),new Date(NaN))}function l(t,e){o(2,arguments);var n=s(t),r=a(e);return isNaN(r)?new Date(NaN):r?(n.setDate(n.getDate()+r),n):n}function c(t,e){o(2,arguments);var n=s(t),r=a(e);if(isNaN(r))return new Date(NaN);if(!r)return n;var i=n.getDate(),l=new Date(n.getTime());l.setMonth(n.getMonth()+r+1,0);var c=l.getDate();return i>=c?l:(n.setFullYear(l.getFullYear(),l.getMonth(),i),n)}function u(t,e){o(2,arguments);var n=a(e);return c(t,12*n)}function h(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function d(t){if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function f(t){var e=d(t),n=e.pageXOffset,r=e.pageYOffset;return{scrollLeft:n,scrollTop:r}}function p(t){var e=d(t).Element;return t instanceof e||t instanceof Element}function v(t){var e=d(t).HTMLElement;return t instanceof e||t instanceof HTMLElement}function g(t){var e=d(t).ShadowRoot;return t instanceof e||t instanceof ShadowRoot}function m(t){return{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}}function y(t){return t!==d(t)&&v(t)?m(t):f(t)}function b(t){return t?(t.nodeName||"").toLowerCase():null}function x(t){return((p(t)?t.ownerDocument:t.document)||window.document).documentElement}function w(t){return h(x(t)).left+f(t).scrollLeft}function k(t){return d(t).getComputedStyle(t)}function S(t){var e=k(t),n=e.overflow,r=e.overflowX,i=e.overflowY;return/auto|scroll|overlay|hidden/.test(n+i+r)}function C(t,e,n){void 0===n&&(n=!1);var r=x(e),i=h(t),a=v(e),o={scrollLeft:0,scrollTop:0},s={x:0,y:0};return(a||!a&&!n)&&(("body"!==b(e)||S(r))&&(o=y(e)),v(e)?(s=h(e),s.x+=e.clientLeft,s.y+=e.clientTop):r&&(s.x=w(r))),{x:i.left+o.scrollLeft-s.x,y:i.top+o.scrollTop-s.y,width:i.width,height:i.height}}function A(t){return{x:t.offsetLeft,y:t.offsetTop,width:t.offsetWidth,height:t.offsetHeight}}function _(t){return"html"===b(t)?t:t.assignedSlot||t.parentNode||t.host||x(t)}function D(t){return["html","body","#document"].indexOf(b(t))>=0?t.ownerDocument.body:v(t)&&S(t)?t:D(_(t))}function T(t,e){void 0===e&&(e=[]);var n=D(t),r="body"===b(n),i=d(n),a=r?[i].concat(i.visualViewport||[],S(n)?n:[]):n,o=e.concat(a);return r?o:o.concat(T(_(a)))}function E(t){return["table","td","th"].indexOf(b(t))>=0}function O(t){if(!v(t)||"fixed"===k(t).position)return null;var e=t.offsetParent;if(e){var n=x(e);if("body"===b(e)&&"static"===k(e).position&&"static"!==k(n).position)return n}return e}function P(t){var e=_(t);while(v(e)&&["html","body"].indexOf(b(e))<0){var n=k(e);if("none"!==n.transform||"none"!==n.perspective||n.willChange&&"auto"!==n.willChange)return e;e=e.parentNode}return null}function I(t){var e=d(t),n=O(t);while(n&&E(n)&&"static"===k(n).position)n=O(n);return n&&"body"===b(n)&&"static"===k(n).position?e:n||P(t)||e}var M="top",V="bottom",L="right",j="left",B="auto",R=[M,V,L,j],F="start",N="end",z="clippingParents",$="viewport",Y="popper",H="reference",W=R.reduce((function(t,e){return t.concat([e+"-"+F,e+"-"+N])}),[]),X=[].concat(R,[B]).reduce((function(t,e){return t.concat([e,e+"-"+F,e+"-"+N])}),[]),G="beforeRead",U="read",q="afterRead",Z="beforeMain",K="main",J="afterMain",Q="beforeWrite",tt="write",et="afterWrite",nt=[G,U,q,Z,K,J,Q,tt,et];function rt(t){var e=new Map,n=new Set,r=[];function i(t){n.add(t.name);var a=[].concat(t.requires||[],t.requiresIfExists||[]);a.forEach((function(t){if(!n.has(t)){var r=e.get(t);r&&i(r)}})),r.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){n.has(t.name)||i(t)})),r}function it(t){var e=rt(t);return nt.reduce((function(t,n){return t.concat(e.filter((function(t){return t.phase===n})))}),[])}function at(t){var e;return function(){return e||(e=new Promise((function(n){Promise.resolve().then((function(){e=void 0,n(t())}))}))),e}}function ot(t){var e=t.reduce((function(t,e){var n=t[e.name];return t[e.name]=n?Object.assign(Object.assign(Object.assign({},n),e),{},{options:Object.assign(Object.assign({},n.options),e.options),data:Object.assign(Object.assign({},n.data),e.data)}):e,t}),{});return Object.keys(e).map((function(t){return e[t]}))}var st={placement:"bottom",modifiers:[],strategy:"absolute"};function lt(){for(var t=arguments.length,e=new Array(t),n=0;n=0?"x":"y"}function gt(t){var e,n=t.reference,r=t.element,i=t.placement,a=i?ft(i):null,o=i?pt(i):null,s=n.x+n.width/2-r.width/2,l=n.y+n.height/2-r.height/2;switch(a){case M:e={x:s,y:n.y-r.height};break;case V:e={x:s,y:n.y+n.height};break;case L:e={x:n.x+n.width,y:l};break;case j:e={x:n.x-r.width,y:l};break;default:e={x:n.x,y:n.y}}var c=a?vt(a):null;if(null!=c){var u="y"===c?"height":"width";switch(o){case F:e[c]=Math.floor(e[c])-Math.floor(n[u]/2-r[u]/2);break;case N:e[c]=Math.floor(e[c])+Math.ceil(n[u]/2-r[u]/2);break;default:}}return e}function mt(t){var e=t.state,n=t.name;e.modifiersData[n]=gt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})}var yt={name:"popperOffsets",enabled:!0,phase:"read",fn:mt,data:{}},bt={top:"auto",right:"auto",bottom:"auto",left:"auto"};function xt(t){var e=t.x,n=t.y,r=window,i=r.devicePixelRatio||1;return{x:Math.round(e*i)/i||0,y:Math.round(n*i)/i||0}}function wt(t){var e,n=t.popper,r=t.popperRect,i=t.placement,a=t.offsets,o=t.position,s=t.gpuAcceleration,l=t.adaptive,c=xt(a),u=c.x,h=c.y,f=a.hasOwnProperty("x"),p=a.hasOwnProperty("y"),v=j,g=M,m=window;if(l){var y=I(n);y===d(n)&&(y=x(n)),i===M&&(g=V,h-=y.clientHeight-r.height,h*=s?1:-1),i===j&&(v=L,u-=y.clientWidth-r.width,u*=s?1:-1)}var b,w=Object.assign({position:o},l&&bt);return s?Object.assign(Object.assign({},w),{},(b={},b[g]=p?"0":"",b[v]=f?"0":"",b.transform=(m.devicePixelRatio||1)<2?"translate("+u+"px, "+h+"px)":"translate3d("+u+"px, "+h+"px, 0)",b)):Object.assign(Object.assign({},w),{},(e={},e[g]=p?h+"px":"",e[v]=f?u+"px":"",e.transform="",e))}function kt(t){var e=t.state,n=t.options,r=n.gpuAcceleration,i=void 0===r||r,a=n.adaptive,o=void 0===a||a,s={placement:ft(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:i};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign(Object.assign({},e.styles.popper),wt(Object.assign(Object.assign({},s),{},{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:o})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign(Object.assign({},e.styles.arrow),wt(Object.assign(Object.assign({},s),{},{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1})))),e.attributes.popper=Object.assign(Object.assign({},e.attributes.popper),{},{"data-popper-placement":e.placement})}var St={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:kt,data:{}};function Ct(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var n=e.styles[t]||{},r=e.attributes[t]||{},i=e.elements[t];v(i)&&b(i)&&(Object.assign(i.style,n),Object.keys(r).forEach((function(t){var e=r[t];!1===e?i.removeAttribute(t):i.setAttribute(t,!0===e?"":e)})))}))}function At(t){var e=t.state,n={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,n.popper),e.elements.arrow&&Object.assign(e.elements.arrow.style,n.arrow),function(){Object.keys(e.elements).forEach((function(t){var r=e.elements[t],i=e.attributes[t]||{},a=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:n[t]),o=a.reduce((function(t,e){return t[e]="",t}),{});v(r)&&b(r)&&(Object.assign(r.style,o),Object.keys(i).forEach((function(t){r.removeAttribute(t)})))}))}}var _t={name:"applyStyles",enabled:!0,phase:"write",fn:Ct,effect:At,requires:["computeStyles"]};function Dt(t,e,n){var r=ft(t),i=[j,M].indexOf(r)>=0?-1:1,a="function"===typeof n?n(Object.assign(Object.assign({},e),{},{placement:t})):n,o=a[0],s=a[1];return o=o||0,s=(s||0)*i,[j,L].indexOf(r)>=0?{x:s,y:o}:{x:o,y:s}}function Tt(t){var e=t.state,n=t.options,r=t.name,i=n.offset,a=void 0===i?[0,0]:i,o=X.reduce((function(t,n){return t[n]=Dt(n,e.rects,a),t}),{}),s=o[e.placement],l=s.x,c=s.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[r]=o}var Et={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:Tt},Ot={left:"right",right:"left",bottom:"top",top:"bottom"};function Pt(t){return t.replace(/left|right|bottom|top/g,(function(t){return Ot[t]}))}var It={start:"end",end:"start"};function Mt(t){return t.replace(/start|end/g,(function(t){return It[t]}))}function Vt(t){var e=d(t),n=x(t),r=e.visualViewport,i=n.clientWidth,a=n.clientHeight,o=0,s=0;return r&&(i=r.width,a=r.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(o=r.offsetLeft,s=r.offsetTop)),{width:i,height:a,x:o+w(t),y:s}}function Lt(t){var e=x(t),n=f(t),r=t.ownerDocument.body,i=Math.max(e.scrollWidth,e.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),a=Math.max(e.scrollHeight,e.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),o=-n.scrollLeft+w(t),s=-n.scrollTop;return"rtl"===k(r||e).direction&&(o+=Math.max(e.clientWidth,r?r.clientWidth:0)-i),{width:i,height:a,x:o,y:s}}function jt(t,e){var n=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(g(n)){var r=e;do{if(r&&t.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function Bt(t){return Object.assign(Object.assign({},t),{},{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Rt(t){var e=h(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}function Ft(t,e){return e===$?Bt(Vt(t)):v(e)?Rt(e):Bt(Lt(x(t)))}function Nt(t){var e=T(_(t)),n=["absolute","fixed"].indexOf(k(t).position)>=0,r=n&&v(t)?I(t):t;return p(r)?e.filter((function(t){return p(t)&&jt(t,r)&&"body"!==b(t)})):[]}function zt(t,e,n){var r="clippingParents"===e?Nt(t):[].concat(e),i=[].concat(r,[n]),a=i[0],o=i.reduce((function(e,n){var r=Ft(t,n);return e.top=Math.max(r.top,e.top),e.right=Math.min(r.right,e.right),e.bottom=Math.min(r.bottom,e.bottom),e.left=Math.max(r.left,e.left),e}),Ft(t,a));return o.width=o.right-o.left,o.height=o.bottom-o.top,o.x=o.left,o.y=o.top,o}function $t(){return{top:0,right:0,bottom:0,left:0}}function Yt(t){return Object.assign(Object.assign({},$t()),t)}function Ht(t,e){return e.reduce((function(e,n){return e[n]=t,e}),{})}function Wt(t,e){void 0===e&&(e={});var n=e,r=n.placement,i=void 0===r?t.placement:r,a=n.boundary,o=void 0===a?z:a,s=n.rootBoundary,l=void 0===s?$:s,c=n.elementContext,u=void 0===c?Y:c,d=n.altBoundary,f=void 0!==d&&d,v=n.padding,g=void 0===v?0:v,m=Yt("number"!==typeof g?g:Ht(g,R)),y=u===Y?H:Y,b=t.elements.reference,w=t.rects.popper,k=t.elements[f?y:u],S=zt(p(k)?k:k.contextElement||x(t.elements.popper),o,l),C=h(b),A=gt({reference:C,element:w,strategy:"absolute",placement:i}),_=Bt(Object.assign(Object.assign({},w),A)),D=u===Y?_:C,T={top:S.top-D.top+m.top,bottom:D.bottom-S.bottom+m.bottom,left:S.left-D.left+m.left,right:D.right-S.right+m.right},E=t.modifiersData.offset;if(u===Y&&E){var O=E[i];Object.keys(T).forEach((function(t){var e=[L,V].indexOf(t)>=0?1:-1,n=[M,V].indexOf(t)>=0?"y":"x";T[t]+=O[n]*e}))}return T}function Xt(t,e){void 0===e&&(e={});var n=e,r=n.placement,i=n.boundary,a=n.rootBoundary,o=n.padding,s=n.flipVariations,l=n.allowedAutoPlacements,c=void 0===l?X:l,u=pt(r),h=u?s?W:W.filter((function(t){return pt(t)===u})):R,d=h.filter((function(t){return c.indexOf(t)>=0}));0===d.length&&(d=h);var f=d.reduce((function(e,n){return e[n]=Wt(t,{placement:n,boundary:i,rootBoundary:a,padding:o})[ft(n)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}function Gt(t){if(ft(t)===B)return[];var e=Pt(t);return[Mt(t),e,Mt(e)]}function Ut(t){var e=t.state,n=t.options,r=t.name;if(!e.modifiersData[r]._skip){for(var i=n.mainAxis,a=void 0===i||i,o=n.altAxis,s=void 0===o||o,l=n.fallbackPlacements,c=n.padding,u=n.boundary,h=n.rootBoundary,d=n.altBoundary,f=n.flipVariations,p=void 0===f||f,v=n.allowedAutoPlacements,g=e.options.placement,m=ft(g),y=m===g,b=l||(y||!p?[Pt(g)]:Gt(g)),x=[g].concat(b).reduce((function(t,n){return t.concat(ft(n)===B?Xt(e,{placement:n,boundary:u,rootBoundary:h,padding:c,flipVariations:p,allowedAutoPlacements:v}):n)}),[]),w=e.rects.reference,k=e.rects.popper,S=new Map,C=!0,A=x[0],_=0;_=0,P=O?"width":"height",I=Wt(e,{placement:D,boundary:u,rootBoundary:h,altBoundary:d,padding:c}),R=O?E?L:j:E?V:M;w[P]>k[P]&&(R=Pt(R));var N=Pt(R),z=[];if(a&&z.push(I[T]<=0),s&&z.push(I[R]<=0,I[N]<=0),z.every((function(t){return t}))){A=D,C=!1;break}S.set(D,z)}if(C)for(var $=p?3:1,Y=function(t){var e=x.find((function(e){var n=S.get(e);if(n)return n.slice(0,t).every((function(t){return t}))}));if(e)return A=e,"break"},H=$;H>0;H--){var W=Y(H);if("break"===W)break}e.placement!==A&&(e.modifiersData[r]._skip=!0,e.placement=A,e.reset=!0)}}var qt={name:"flip",enabled:!0,phase:"main",fn:Ut,requiresIfExists:["offset"],data:{_skip:!1}};function Zt(t){return"x"===t?"y":"x"}function Kt(t,e,n){return Math.max(t,Math.min(e,n))}function Jt(t){var e=t.state,n=t.options,r=t.name,i=n.mainAxis,a=void 0===i||i,o=n.altAxis,s=void 0!==o&&o,l=n.boundary,c=n.rootBoundary,u=n.altBoundary,h=n.padding,d=n.tether,f=void 0===d||d,p=n.tetherOffset,v=void 0===p?0:p,g=Wt(e,{boundary:l,rootBoundary:c,padding:h,altBoundary:u}),m=ft(e.placement),y=pt(e.placement),b=!y,x=vt(m),w=Zt(x),k=e.modifiersData.popperOffsets,S=e.rects.reference,C=e.rects.popper,_="function"===typeof v?v(Object.assign(Object.assign({},e.rects),{},{placement:e.placement})):v,D={x:0,y:0};if(k){if(a){var T="y"===x?M:j,E="y"===x?V:L,O="y"===x?"height":"width",P=k[x],B=k[x]+g[T],R=k[x]-g[E],N=f?-C[O]/2:0,z=y===F?S[O]:C[O],$=y===F?-C[O]:-S[O],Y=e.elements.arrow,H=f&&Y?A(Y):{width:0,height:0},W=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:$t(),X=W[T],G=W[E],U=Kt(0,S[O],H[O]),q=b?S[O]/2-N-U-X-_:z-U-X-_,Z=b?-S[O]/2+N+U+G+_:$+U+G+_,K=e.elements.arrow&&I(e.elements.arrow),J=K?"y"===x?K.clientTop||0:K.clientLeft||0:0,Q=e.modifiersData.offset?e.modifiersData.offset[e.placement][x]:0,tt=k[x]+q-Q-J,et=k[x]+Z-Q,nt=Kt(f?Math.min(B,tt):B,P,f?Math.max(R,et):R);k[x]=nt,D[x]=nt-P}if(s){var rt="x"===x?M:j,it="x"===x?V:L,at=k[w],ot=at+g[rt],st=at-g[it],lt=Kt(ot,at,st);k[w]=lt,D[w]=lt-at}e.modifiersData[r]=D}}var Qt={name:"preventOverflow",enabled:!0,phase:"main",fn:Jt,requiresIfExists:["offset"]};function te(t){var e,n=t.state,r=t.name,i=n.elements.arrow,a=n.modifiersData.popperOffsets,o=ft(n.placement),s=vt(o),l=[j,L].indexOf(o)>=0,c=l?"height":"width";if(i&&a){var u=n.modifiersData[r+"#persistent"].padding,h=A(i),d="y"===s?M:j,f="y"===s?V:L,p=n.rects.reference[c]+n.rects.reference[s]-a[s]-n.rects.popper[c],v=a[s]-n.rects.reference[s],g=I(i),m=g?"y"===s?g.clientHeight||0:g.clientWidth||0:0,y=p/2-v/2,b=u[d],x=m-h[c]-u[f],w=m/2-h[c]/2+y,k=Kt(b,w,x),S=s;n.modifiersData[r]=(e={},e[S]=k,e.centerOffset=k-w,e)}}function ee(t){var e=t.state,n=t.options,r=t.name,i=n.element,a=void 0===i?"[data-popper-arrow]":i,o=n.padding,s=void 0===o?0:o;null!=a&&("string"!==typeof a||(a=e.elements.popper.querySelector(a),a))&&jt(e.elements.popper,a)&&(e.elements.arrow=a,e.modifiersData[r+"#persistent"]={padding:Yt("number"!==typeof s?s:Ht(s,R))})}var ne={name:"arrow",enabled:!0,phase:"main",fn:te,effect:ee,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function re(t,e,n){return void 0===n&&(n={x:0,y:0}),{top:t.top-e.height-n.y,right:t.right-e.width+n.x,bottom:t.bottom-e.height+n.y,left:t.left-e.width-n.x}}function ie(t){return[M,L,V,j].some((function(e){return t[e]>=0}))}function ae(t){var e=t.state,n=t.name,r=e.rects.reference,i=e.rects.popper,a=e.modifiersData.preventOverflow,o=Wt(e,{elementContext:"reference"}),s=Wt(e,{altBoundary:!0}),l=re(o,r),c=re(s,i,a),u=ie(l),h=ie(c);e.modifiersData[n]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:u,hasPopperEscaped:h},e.attributes.popper=Object.assign(Object.assign({},e.attributes.popper),{},{"data-popper-reference-hidden":u,"data-popper-escaped":h})}var oe={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:ae},se=[dt,yt,St,_t,Et,qt,Qt,ne,oe],le=ct({defaultModifiers:se}),ce=n("6679"),ue=n.n(ce),he=n("501e"),de=n.n(he),fe=n("e2a0"),pe=n.n(fe),ve=n("dcbe"),ge=n.n(ve),me=n("9520"),ye=n.n(me),be=n("4cfe"),xe=n.n(be),we=n("6220"),ke=n.n(we),Se=n("f678"),Ce=n.n(Se),Ae=n("9b02"),_e=n.n(Ae),De=n("0f5c"),Te=n.n(De),Ee=n("9e86"),Oe=n.n(Ee),Pe=n("f542"),Ie=n.n(Pe),Me=n("95ae"),Ve=n.n(Me),Le=n("3f84"),je=n.n(Le),Be=n("2593"),Re=n.n(Be),Fe=n("3eea"),Ne=n.n(Fe),ze=n("3852"),$e=n.n(ze),Ye=n("dd61"),He=n.n(Ye),We=n("a59b"),Xe=n.n(We),Ge=n("4416"),Ue=n.n(Ge),qe=n("3092"),Ze=n.n(qe);const Ke=function(t){return Object.prototype.toString.call(t).slice(8,-1)},Je=function(t){return ke()(t)&&!isNaN(t.getTime())},Qe=function(t){return"Object"===Ke(t)},tn=$e.a,en=function(t,e){return Ze()(e,(function(e){return $e()(t,e)}))},nn=Ze.a,rn=function(t,e,n="0"){t=null!==t&&void 0!==t?String(t):"",e=e||2;while(t.lengthe.month:t.year>e.year)},cn=function(t,e,n){return!!t&&!sn(t,e)&&!ln(t,n)},un=function(t,e){return!(!t&&e)&&(!(t&&!e)&&(!t&&!e||t.month===e.month&&t.year===e.year))},hn=function({month:t,year:e},n){const r=n>0?1:-1;for(let i=0;i12?(t=1,e++):t<1&&(t=12,e--);return{month:t,year:e}},dn=function(t,e){if(!on(t)||!on(e))return[];const n=[];while(!ln(t,e))n.push(t),t=hn(t,1);return n};function fn(t,e){const n=Je(t),r=Je(e);return!n&&!r||n===r&&t.getTime()===e.getTime()}const pn=function(t){return ge()(t)&&t.length},vn=function(t,e,n){const r=[];return n.forEach((function(n){const i=n.name||n.toString(),a=n.mixin,o=n.validate;if(Object.prototype.hasOwnProperty.call(t,i)){const n=o?o(t[i]):t[i];e[i]=a&&Qe(n)?{...a,...n}:n,r.push(i)}})),{target:e,assigned:r.length?r:null}},gn=function(t,e,n,r){t&&e&&n&&t.addEventListener(e,n,r)},mn=function(t,e,n,r){t&&e&&t.removeEventListener(e,n,r)},yn=function(t,e){return!!t&&!!e&&(t===e||t.contains(e))},bn=function(t,e){" "!==t.key&&"Enter"!==t.key||(e(t),t.preventDefault())},xn=function(){function t(){return(65536*(1+Math.random())|0).toString(16).substring(1)}return`${t()+t()}-${t()}-${t()}-${t()}-${t()}${t()}${t()}`};function wn(t){let e,n=0,r=0;if(0===t.length)return n;for(r=0;r1?e[1]:"",["start","top","left"].includes(e)?t?"top":"left":["end","bottom","right"].includes(e)?t?"bottom":"right":t?"middle":"center"},state(){return this.$popovers[this.id]}},watch:{opts(t,e){e&&e.callback&&e.callback({...e,completed:!t,reason:t?"Overridden by action":null})}},mounted(){this.popoverEl=this.$refs.popover,this.addEvents()},beforeDestroy(){this.destroyPopper(),this.removeEvents(),this.popoverEl=null},methods:{addEvents(){gn(this.popoverEl,"click",this.onClick),gn(this.popoverEl,"mouseover",this.onMouseOver),gn(this.popoverEl,"mouseleave",this.onMouseLeave),gn(this.popoverEl,"focusin",this.onFocusIn),gn(this.popoverEl,"focusout",this.onFocusOut),gn(document,"keydown",this.onDocumentKeydown),gn(document,"click",this.onDocumentClick),gn(document,"show-popover",this.onDocumentShowPopover),gn(document,"hide-popover",this.onDocumentHidePopover),gn(document,"toggle-popover",this.onDocumentTogglePopover),gn(document,"update-popover",this.onDocumentUpdatePopover)},removeEvents(){mn(this.popoverEl,"click",this.onClick),mn(this.popoverEl,"mouseover",this.onMouseOver),mn(this.popoverEl,"mouseleave",this.onMouseLeave),mn(this.popoverEl,"focusin",this.onFocusIn),mn(this.popoverEl,"focusout",this.onFocusOut),mn(document,"keydown",this.onDocumentKeydown),mn(document,"click",this.onDocumentClick),mn(document,"show-popover",this.onDocumentShowPopover),mn(document,"hide-popover",this.onDocumentHidePopover),mn(document,"toggle-popover",this.onDocumentTogglePopover),mn(document,"update-popover",this.onDocumentUpdatePopover)},onClick(t){t.stopPropagation()},onMouseOver(){this.isHovered=!0,this.isInteractive&&this.show()},onMouseLeave(){this.isHovered=!1,!this.autoHide||this.isFocused||this.ref&&this.ref===document.activeElement||this.hide()},onFocusIn(){this.isFocused=!0,this.isInteractive&&this.show()},onFocusOut(t){t.relatedTarget&&yn(this.popoverEl,t.relatedTarget)||(this.isFocused=!1,!this.isHovered&&this.autoHide&&this.hide())},onDocumentClick(t){this.$refs.popover&&this.ref&&(yn(this.popoverEl,t.target)||yn(this.ref,t.target)||this.hide())},onDocumentKeydown(t){"Esc"!==t.key&&"Escape"!==t.key||this.hide()},onDocumentShowPopover({detail:t}){t.id&&t.id===this.id&&this.show(t)},onDocumentHidePopover({detail:t}){t.id&&t.id===this.id&&this.hide(t)},onDocumentTogglePopover({detail:t}){t.id&&t.id===this.id&&this.toggle(t)},onDocumentUpdatePopover({detail:t}){t.id&&t.id===this.id&&this.update(t)},show(t={}){var e=this;t.action="show";const n=t.ref||this.ref,r=t.showDelay>=0?t.showDelay:this.showDelay;if(!n)return void(t.callback&&t.callback({completed:!1,reason:"Invalid reference element provided"}));clearTimeout(this.timeout),this.opts=t;const i=function(){Object.assign(e,t),e.setupPopper(),e.opts=null};r>0?this.timeout=setTimeout((function(){return i()}),r):i()},hide(t={}){var e=this;t.action="hide";const n=t.ref||this.ref,r=t.hideDelay>=0?t.hideDelay:this.hideDelay;if(!this.ref||n!==this.ref)return void(t.callback&&t.callback({...t,completed:!1,reason:this.ref?"Invalid reference element provided":"Popover already hidden"}));const i=function(){e.ref=null,e.opts=null};clearTimeout(this.timeout),this.opts=t,r>0?this.timeout=setTimeout(i,r):i()},toggle(t={}){this.isVisible&&t.ref===this.ref?this.hide(t):this.show(t)},update(t={}){Object.assign(this,t),this.setupPopper()},setupPopper(){var t=this;this.$nextTick((function(){t.ref&&t.$refs.popover&&(t.popper&&t.popper.reference!==t.ref&&t.destroyPopper(),t.popper?t.popper.update():t.popper=le(t.ref,t.popoverEl,t.popperOptions))}))},onPopperUpdate(t){t.placement?this.placement=t.placement:t.state&&(this.placement=t.state.placement)},beforeEnter(t){this.$emit("beforeShow",t)},afterEnter(t){this.$emit("afterShow",t)},beforeLeave(t){this.$emit("beforeHide",t)},afterLeave(t){this.destroyPopper(),this.$emit("afterHide",t)},destroyPopper(){this.popper&&(this.popper.destroy(),this.popper=null)}}},An=Cn;n("bdb3");function _n(t,e,n,r,i,a,o,s){var l,c="function"===typeof t?t.options:t;if(e&&(c.render=e,c.staticRenderFns=n,c._compiled=!0),r&&(c.functional=!0),a&&(c._scopeId="data-v-"+a),o?(l=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"===typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(o)},c._ssrRegister=l):i&&(l=s?function(){i.call(this,(c.functional?this.parent:this).$root.$options.shadowRoot)}:i),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(t,e){return l.call(e),u(t,e)}}else{var h=c.beforeCreate;c.beforeCreate=h?[].concat(h,l):[l]}return{exports:t,options:c}}var Dn=_n(An,kn,Sn,!1,null,"39b30300",null),Tn=Dn.exports,En=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"vc-day-popover-row"},[t.indicator?n("div",{staticClass:"vc-day-popover-row-indicator"},[n("span",{class:t.indicator.class,style:t.indicator.style})]):t._e(),n("div",{staticClass:"vc-day-popover-row-content"},[t._t("default",[t._v(t._s(t.attribute.popover?t.attribute.popover.label:"No content provided"))])],2)])},On=[],Pn=n("8bbf"),In=n.n(Pn),Mn=n("23a5"),Vn=n("7efe"),Ln=n("85a9");const jn={ar:{dow:7,L:"D/‏M/‏YYYY"},bg:{dow:2,L:"D.MM.YYYY"},ca:{dow:2,L:"DD/MM/YYYY"},"zh-CN":{dow:2,L:"YYYY/MM/DD"},"zh-TW":{dow:1,L:"YYYY/MM/DD"},hr:{dow:2,L:"DD.MM.YYYY"},cs:{dow:2,L:"DD.MM.YYYY"},da:{dow:2,L:"DD.MM.YYYY"},nl:{dow:2,L:"DD-MM-YYYY"},"en-US":{dow:1,L:"MM/DD/YYYY"},"en-AU":{dow:2,L:"DD/MM/YYYY"},"en-CA":{dow:1,L:"YYYY-MM-DD"},"en-GB":{dow:2,L:"DD/MM/YYYY"},"en-IE":{dow:2,L:"DD-MM-YYYY"},"en-NZ":{dow:2,L:"DD/MM/YYYY"},"en-ZA":{dow:1,L:"YYYY/MM/DD"},eo:{dow:2,L:"YYYY-MM-DD"},et:{dow:2,L:"DD.MM.YYYY"},fi:{dow:2,L:"DD.MM.YYYY"},fr:{dow:2,L:"DD/MM/YYYY"},"fr-CA":{dow:1,L:"YYYY-MM-DD"},"fr-CH":{dow:2,L:"DD.MM.YYYY"},de:{dow:2,L:"DD.MM.YYYY"},he:{dow:1,L:"DD.MM.YYYY"},id:{dow:2,L:"DD/MM/YYYY"},it:{dow:2,L:"DD/MM/YYYY"},ja:{dow:1,L:"YYYY年M月D日"},ko:{dow:1,L:"YYYY.MM.DD"},lv:{dow:2,L:"DD.MM.YYYY"},lt:{dow:2,L:"DD.MM.YYYY"},mk:{dow:2,L:"D.MM.YYYY"},nb:{dow:2,L:"D. MMMM YYYY"},nn:{dow:2,L:"D. MMMM YYYY"},pl:{dow:2,L:"DD.MM.YYYY"},pt:{dow:2,L:"DD/MM/YYYY"},ro:{dow:2,L:"DD.MM.YYYY"},ru:{dow:2,L:"DD.MM.YYYY"},sk:{dow:2,L:"DD.MM.YYYY"},"es-ES":{dow:2,L:"DD/MM/YYYY"},"es-MX":{dow:2,L:"DD/MM/YYYY"},sv:{dow:2,L:"YYYY-MM-DD"},th:{dow:1,L:"DD/MM/YYYY"},tr:{dow:2,L:"DD.MM.YYYY"},uk:{dow:2,L:"DD.MM.YYYY"},vi:{dow:2,L:"DD/MM/YYYY"}};jn.en=jn["en-US"],jn.es=jn["es-ES"],jn.no=jn.nb,jn.zh=jn["zh-CN"],Ie()(jn).forEach((function([t,{dow:e,L:n}]){jn[t]={id:t,firstDayOfWeek:e,masks:{L:n}}}));var Bn=jn;const Rn={componentPrefix:"v",navVisibility:"click",titlePosition:"center",transition:"slide-h",touch:Mn,masks:Vn,screens:Ln,locales:Bn,datePicker:{updateOnInput:!0,inputDebounce:1e3,popover:{visibility:"hover-focus",placement:"bottom-start",keepVisibleOnInput:!1,isInteractive:!0}}};let Fn=null;const Nn=function(t){return Fn||(Fn=new In.a({data(){return{defaults:je()(t,Rn)}},computed:{locales(){var t=this;return Oe()(this.defaults.locales,(function(e){return e.masks=je()(e.masks,t.defaults.masks),e}))}}})),Fn.defaults},zn={beforeCreate(){Nn()},computed:{$defaults(){return Fn.defaults},$locales(){return Fn.locales}},methods:{propOrDefault(t,e,n){return this.passedProp(t,_e()(this.$defaults,e),n)},passedProp(t,e,n){if(tn(this.$options.propsData,t)){const r=this[t];return Qe(r)&&"merge"===n?je()(r,e):r}return e}}},$n={inject:["sharedState"],mixins:[zn],computed:{masks(){return this.sharedState.masks},theme(){return this.sharedState.theme},locale(){return this.sharedState.locale},dayPopoverId(){return this.sharedState.dayPopoverId}},methods:{format(t,e){return this.locale.format(t,e)},pageForDate(t){return this.locale.getDateParts(this.locale.normalizeDate(t))}}},Yn=["base","start","end","startEnd"],Hn=["class","contentClass","style","contentStyle","color","fillMode"],Wn={color:"blue",isDark:!1,highlight:{base:{fillMode:"light"},start:{fillMode:"solid"},end:{fillMode:"solid"}},dot:{base:{fillMode:"solid"},start:{fillMode:"solid"},end:{fillMode:"solid"}},bar:{base:{fillMode:"solid"},start:{fillMode:"solid"},end:{fillMode:"solid"}},content:{base:{},start:{},end:{}}};class Xn{constructor(t){Object.assign(this,Wn,t)}normalizeAttr({config:t,type:e}){let n=this.color,r={};const i=this[e];if(!0===t||pe()(t))n=pe()(t)?t:n,r={...i};else{if(!Qe(t))return null;r=en(t,Yn)?{...t}:{base:{...t},start:{...t},end:{...t}}}return Ve()(r,{start:r.startEnd,end:r.startEnd},i),Ie()(r).forEach((function([t,e]){let i=n;!0===e||pe()(e)?(i=pe()(e)?e:i,r[t]={color:i}):Qe(e)&&(en(e,Hn)?r[t]={...e}:r[t]={}),tn(r,t+".color")||Te()(r,t+".color",i)})),r}normalizeHighlight(t){var e=this;const n=this.normalizeAttr({config:t,type:"highlight"});return Ie()(n).forEach((function([t,n]){const r=Ve()(n,{isDark:e.isDark,color:e.color});n.style={...e.getHighlightBgStyle(r),...n.style},n.contentStyle={...e.getHighlightContentStyle(r),...n.contentStyle}})),n}getHighlightBgStyle({fillMode:t,color:e,isDark:n}){switch(t){case"outline":case"none":return{backgroundColor:n?"var(--gray-900)":"var(--white)",border:"2px solid",borderColor:n?`var(--${e}-200)`:`var(--${e}-700)`,borderRadius:"var(--rounded-full)"};case"light":return{backgroundColor:n?`var(--${e}-800)`:`var(--${e}-200)`,opacity:n?.75:1,borderRadius:"var(--rounded-full)"};case"solid":return{backgroundColor:n?`var(--${e}-500)`:`var(--${e}-600)`,borderRadius:"var(--rounded-full)"};default:return{borderRadius:"var(--rounded-full)"}}}getHighlightContentStyle({fillMode:t,color:e,isDark:n}){switch(t){case"outline":case"none":return{fontWeight:"var(--font-bold)",color:n?`var(--${e}-100)`:`var(--${e}-900)`};case"light":return{fontWeight:"var(--font-bold)",color:n?`var(--${e}-100)`:`var(--${e}-900)`};case"solid":return{fontWeight:"var(--font-bold)",color:"var(--white)"};default:return""}}bgAccentHigh({color:t,isDark:e}){return{backgroundColor:e?`var(--${t}-500)`:`var(--${t}-600)`}}contentAccent({color:t,isDark:e}){return t?{fontWeight:"var(--font-bold)",color:e?`var(--${t}-100)`:`var(--${t}-900)`}:null}normalizeDot(t){return this.normalizeNonHighlight("dot",t,this.bgAccentHigh)}normalizeBar(t){return this.normalizeNonHighlight("bar",t,this.bgAccentHigh)}normalizeContent(t){return this.normalizeNonHighlight("content",t,this.contentAccent)}normalizeNonHighlight(t,e,n){var r=this;const i=this.normalizeAttr({type:t,config:e});return Ie()(i).forEach((function([t,e]){Ve()(e,{isDark:r.isDark,color:r.color}),e.style={...n(e),...e.style}})),i}}n("5319");function Gn(t){var e=new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getMilliseconds()));return e.setUTCFullYear(t.getFullYear()),t.getTime()-e.getTime()}function Un(t,e){var n=Qn(e);return n.formatToParts?Zn(n,t):Kn(n,t)}var qn={year:0,month:1,day:2,hour:3,minute:4,second:5};function Zn(t,e){for(var n=t.formatToParts(e),r=[],i=0;i=0&&(r[a]=parseInt(n[i].value,10))}return r}function Kn(t,e){var n=t.format(e).replace(/\u200E/g,""),r=/(\d+)\/(\d+)\/(\d+),? (\d+):(\d+):(\d+)/.exec(n);return[r[3],r[1],r[2],r[4],r[5],r[6]]}var Jn={};function Qn(t){if(!Jn[t]){var e=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:"America/New_York",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}).format(new Date("2014-06-25T04:00:00.123Z")),n="06/25/2014, 00:00:00"===e||"‎06‎/‎25‎/‎2014‎ ‎00‎:‎00‎:‎00"===e;Jn[t]=n?new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}):new Intl.DateTimeFormat("en-US",{hourCycle:"h23",timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"})}return Jn[t]}var tr=36e5,er=6e4,nr={timezone:/([Z+-].*)$/,timezoneZ:/^(Z)$/,timezoneHH:/^([+-])(\d{2})$/,timezoneHHMM:/^([+-])(\d{2}):?(\d{2})$/,timezoneIANA:/(UTC|(?:[a-zA-Z]+\/[a-zA-Z_-]+(?:\/[a-zA-Z_]+)?))$/};function rr(t,e,n){var r,i,a;if(r=nr.timezoneZ.exec(t),r)return 0;if(r=nr.timezoneHH.exec(t),r)return a=parseInt(r[2],10),sr(a)?(i=a*tr,"+"===r[1]?-i:i):NaN;if(r=nr.timezoneHHMM.exec(t),r){a=parseInt(r[2],10);var o=parseInt(r[3],10);return sr(a,o)?(i=a*tr+o*er,"+"===r[1]?-i:i):NaN}if(r=nr.timezoneIANA.exec(t),r){e=new Date(e||Date.now());var s=n?e:ir(e),l=ar(s,t),c=n?l:or(e,l,t);return-c}return 0}function ir(t){return new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getMilliseconds()))}function ar(t,e){var n=Un(t,e),r=Date.UTC(n[0],n[1]-1,n[2],n[3]%24,n[4],n[5]),i=t.getTime(),a=i%1e3;return i-=a>=0?a:1e3+a,r-i}function or(t,e,n){var r=t.getTime(),i=r-e,a=ar(new Date(i),n);if(e===a)return e;i-=a-e;var o=ar(new Date(i),n);return a===o?a:Math.max(a,o)}function sr(t,e){return null==e||!(e<0||e>59)}var lr=36e5,cr=6e4,ur=2,hr={dateTimeDelimeter:/[T ]/,plainTime:/:/,timeZoneDelimeter:/[Z ]/i,YY:/^(\d{2})$/,YYY:[/^([+-]\d{2})$/,/^([+-]\d{3})$/,/^([+-]\d{4})$/],YYYY:/^(\d{4})/,YYYYY:[/^([+-]\d{4})/,/^([+-]\d{5})/,/^([+-]\d{6})/],MM:/^-(\d{2})$/,DDD:/^-?(\d{3})$/,MMDD:/^-?(\d{2})-?(\d{2})$/,Www:/^-?W(\d{2})$/,WwwD:/^-?W(\d{2})-?(\d{1})$/,HH:/^(\d{2}([.,]\d*)?)$/,HHMM:/^(\d{2}):?(\d{2}([.,]\d*)?)$/,HHMMSS:/^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/,timezone:/([Z+-].*| UTC|(?:[a-zA-Z]+\/[a-zA-Z_]+(?:\/[a-zA-Z_]+)?))$/};function dr(t,e){if(arguments.length<1)throw new TypeError("1 argument required, but only "+arguments.length+" present");if(null===t)return new Date(NaN);var n=e||{},r=null==n.additionalDigits?ur:a(n.additionalDigits);if(2!==r&&1!==r&&0!==r)throw new RangeError("additionalDigits must be 0, 1 or 2");if(t instanceof Date||"object"===typeof t&&"[object Date]"===Object.prototype.toString.call(t))return new Date(t.getTime());if("number"===typeof t||"[object Number]"===Object.prototype.toString.call(t))return new Date(t);if("string"!==typeof t&&"[object String]"!==Object.prototype.toString.call(t))return new Date(NaN);var i=fr(t),o=pr(i.date,r),s=o.year,l=o.restDateString,c=vr(l,s);if(isNaN(c))return new Date(NaN);if(c){var u,h=c.getTime(),d=0;if(i.time&&(d=gr(i.time),isNaN(d)))return new Date(NaN);if(i.timezone||n.timeZone){if(u=rr(i.timezone||n.timeZone,new Date(h+d)),isNaN(u))return new Date(NaN)}else u=Gn(new Date(h+d)),u=Gn(new Date(h+d+u));return new Date(h+d+u)}return new Date(NaN)}function fr(t){var e,n={},r=t.split(hr.dateTimeDelimeter);if(hr.plainTime.test(r[0])?(n.date=null,e=r[0]):(n.date=r[0],e=r[1],n.timezone=r[2],hr.timeZoneDelimeter.test(n.date)&&(n.date=t.split(hr.timeZoneDelimeter)[0],e=t.substr(n.date.length,t.length))),e){var i=hr.timezone.exec(e);i?(n.time=e.replace(i[1],""),n.timezone=i[1]):n.time=e}return n}function pr(t,e){var n,r=hr.YYY[e],i=hr.YYYYY[e];if(n=hr.YYYY.exec(t)||i.exec(t),n){var a=n[1];return{year:parseInt(a,10),restDateString:t.slice(a.length)}}if(n=hr.YY.exec(t)||r.exec(t),n){var o=n[1];return{year:100*parseInt(o,10),restDateString:t.slice(o.length)}}return{year:null}}function vr(t,e){if(null===e)return null;var n,r,i,a;if(0===t.length)return r=new Date(0),r.setUTCFullYear(e),r;if(n=hr.MM.exec(t),n)return r=new Date(0),i=parseInt(n[1],10)-1,wr(e,i)?(r.setUTCFullYear(e,i),r):new Date(NaN);if(n=hr.DDD.exec(t),n){r=new Date(0);var o=parseInt(n[1],10);return kr(e,o)?(r.setUTCFullYear(e,0,o),r):new Date(NaN)}if(n=hr.MMDD.exec(t),n){r=new Date(0),i=parseInt(n[1],10)-1;var s=parseInt(n[2],10);return wr(e,i,s)?(r.setUTCFullYear(e,i,s),r):new Date(NaN)}if(n=hr.Www.exec(t),n)return a=parseInt(n[1],10)-1,Sr(e,a)?mr(e,a):new Date(NaN);if(n=hr.WwwD.exec(t),n){a=parseInt(n[1],10)-1;var l=parseInt(n[2],10)-1;return Sr(e,a,l)?mr(e,a,l):new Date(NaN)}return null}function gr(t){var e,n,r;if(e=hr.HH.exec(t),e)return n=parseFloat(e[1].replace(",",".")),Cr(n)?n%24*lr:NaN;if(e=hr.HHMM.exec(t),e)return n=parseInt(e[1],10),r=parseFloat(e[2].replace(",",".")),Cr(n,r)?n%24*lr+r*cr:NaN;if(e=hr.HHMMSS.exec(t),e){n=parseInt(e[1],10),r=parseInt(e[2],10);var i=parseFloat(e[3].replace(",","."));return Cr(n,r,i)?n%24*lr+r*cr+1e3*i:NaN}return null}function mr(t,e,n){e=e||0,n=n||0;var r=new Date(0);r.setUTCFullYear(t,0,4);var i=r.getUTCDay()||7,a=7*e+n+1-i;return r.setUTCDate(r.getUTCDate()+a),r}var yr=[31,28,31,30,31,30,31,31,30,31,30,31],br=[31,29,31,30,31,30,31,31,30,31,30,31];function xr(t){return t%400===0||t%4===0&&t%100!==0}function wr(t,e,n){if(e<0||e>11)return!1;if(null!=n){if(n<1)return!1;var r=xr(t);if(r&&n>br[e])return!1;if(!r&&n>yr[e])return!1}return!0}function kr(t,e){if(e<1)return!1;var n=xr(t);return!(n&&e>366)&&!(!n&&e>365)}function Sr(t,e,n){return!(e<0||e>52)&&(null==n||!(n<0||n>6))}function Cr(t,e,n){return(null==t||!(t<0||t>=25))&&((null==e||!(e<0||e>=60))&&(null==n||!(n<0||n>=60)))}function Ar(t,e){o(1,arguments);var n=e||{},r=n.locale,i=r&&r.options&&r.options.weekStartsOn,l=null==i?0:a(i),c=null==n.weekStartsOn?l:a(n.weekStartsOn);if(!(c>=0&&c<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var u=s(t),h=u.getDay(),d=(h=i.getTime()?n+1:e.getTime()>=l.getTime()?n:n-1}function Tr(t){o(1,arguments);var e=Dr(t),n=new Date(0);n.setFullYear(e,0,4),n.setHours(0,0,0,0);var r=_r(n);return r}var Er=6048e5;function Or(t){o(1,arguments);var e=s(t),n=_r(e).getTime()-Tr(e).getTime();return Math.round(n/Er)+1}function Pr(t,e){var n,r;o(1,arguments);var i=s(t),l=i.getFullYear(),c=null===e||void 0===e||null===(n=e.locale)||void 0===n||null===(r=n.options)||void 0===r?void 0:r.firstWeekContainsDate,u=null==c?1:a(c),h=null==(null===e||void 0===e?void 0:e.firstWeekContainsDate)?u:a(e.firstWeekContainsDate);if(!(h>=1&&h<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var d=new Date(0);d.setFullYear(l+1,0,h),d.setHours(0,0,0,0);var f=Ar(d,e),p=new Date(0);p.setFullYear(l,0,h),p.setHours(0,0,0,0);var v=Ar(p,e);return i.getTime()>=f.getTime()?l+1:i.getTime()>=v.getTime()?l:l-1}function Ir(t,e){o(1,arguments);var n=e||{},r=n.locale,i=r&&r.options&&r.options.firstWeekContainsDate,s=null==i?1:a(i),l=null==n.firstWeekContainsDate?s:a(n.firstWeekContainsDate),c=Pr(t,e),u=new Date(0);u.setFullYear(c,0,l),u.setHours(0,0,0,0);var h=Ar(u,e);return h}var Mr=6048e5;function Vr(t,e){o(1,arguments);var n=s(t),r=Ar(n,e).getTime()-Ir(n,e).getTime();return Math.round(r/Mr)+1}var Lr=6048e5;function jr(t,e,n){o(2,arguments);var r=Ar(t,n),i=Ar(e,n),a=r.getTime()-Gn(r),s=i.getTime()-Gn(i);return Math.round((a-s)/Lr)}function Br(t){o(1,arguments);var e=s(t),n=e.getMonth();return e.setFullYear(e.getFullYear(),n+1,0),e.setHours(0,0,0,0),e}function Rr(t){o(1,arguments);var e=s(t);return e.setDate(1),e.setHours(0,0,0,0),e}function Fr(t,e){return o(1,arguments),jr(Br(t),Rr(t),e)+1}const Nr=864e5;class zr{constructor(t,{order:e=0,locale:n,isFullDay:r}={}){if(this.isDateInfo=!0,this.order=e,this.locale=n instanceof ai?n:new ai(n),this.firstDayOfWeek=this.locale.firstDayOfWeek,!Qe(t)){const e=this.locale.normalizeDate(t);t=r?{start:e,end:e}:{startOn:e,endOn:e}}let i=null,a=null;if(t.start?i=this.locale.normalizeDate(t.start,{...this.opts,time:"00:00:00"}):t.startOn&&(i=this.locale.normalizeDate(t.startOn,this.opts)),t.end?a=this.locale.normalizeDate(t.end,{...this.opts,time:"23:59:59"}):t.endOn&&(a=this.locale.normalizeDate(t.endOn,this.opts)),i&&a&&i>a){const t=i;i=a,a=t}else i&&t.span>=1&&(a=l(i,t.span-1));this.start=i,this.startTime=i?i.getTime():NaN,this.end=a,this.endTime=a?a.getTime():NaN,this.isDate=this.startTime&&this.startTime===this.endTime,this.isRange=!this.isDate;const o=vn(t,{},zr.patternProps);if(o.assigned&&(this.on={and:o.target}),t.on){const e=(ge()(t.on)?t.on:[t.on]).map((function(t){if(ye()(t))return t;const e=vn(t,{},zr.patternProps);return e.assigned?e.target:null})).filter((function(t){return t}));e.length&&(this.on={...this.on,or:e})}this.isComplex=!!this.on}get opts(){return{order:this.order,locale:this.locale}}toDateInfo(t){return t.isDateInfo?t:new zr(t,this.opts)}startOfWeek(t){const e=t.getDay()+1,n=e>=this.firstDayOfWeek?this.firstDayOfWeek-e:-(7-(this.firstDayOfWeek-e));return l(t,n)}diffInDays(t,e){return Math.round((e-t)/Nr)}diffInWeeks(t,e){return this.diffInDays(this.startOfWeek(t),this.startOfWeek(e))}diffInYears(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}diffInMonths(t,e){return 12*this.diffInYears(t,e)+(e.getMonth()-t.getMonth())}static get patterns(){return{dailyInterval:{test:function(t,e,n){return n.diffInDays(n.start||new Date,t.date)%e===0}},weeklyInterval:{test:function(t,e,n){return n.diffInWeeks(n.start||new Date,t.date)%e===0}},monthlyInterval:{test:function(t,e,n){return n.diffInMonths(n.start||new Date,t.date)%e===0}},yearlyInterval:{test:function(){return function(t,e,n){return n.diffInYears(n.start||new Date,t.date)%e===0}}},days:{validate:function(t){return ge()(t)?t:[parseInt(t,10)]},test:function(t,e){return e.includes(t.day)||e.includes(-t.dayFromEnd)}},weekdays:{validate:function(t){return ge()(t)?t:[parseInt(t,10)]},test:function(t,e){return e.includes(t.weekday)}},ordinalWeekdays:{validate:function(t){return Object.keys(t).reduce((function(e,n){const r=t[n];return r?(e[n]=ge()(r)?r:[parseInt(r,10)],e):e}),{})},test:function(t,e){return Object.keys(e).map((function(t){return parseInt(t,10)})).find((function(n){return e[n].includes(t.weekday)&&(n===t.weekdayOrdinal||n===-t.weekdayOrdinalFromEnd)}))}},weekends:{validate:function(t){return t},test:function(t){return 1===t.weekday||7===t.weekday}},workweek:{validate:function(t){return t},test:function(t){return t.weekday>=2&&t.weekday<=6}},weeks:{validate:function(t){return ge()(t)?t:[parseInt(t,10)]},test:function(t,e){return e.includes(t.week)||e.includes(-t.weekFromEnd)}},months:{validate:function(t){return ge()(t)?t:[parseInt(t,10)]},test:function(t,e){return e.includes(t.month)}},years:{validate:function(t){return ge()(t)?t:[parseInt(t,10)]},test:function(t,e){return e.includes(t.year)}}}}static get patternProps(){return Object.keys(zr.patterns).map((function(t){return{name:t,validate:zr.patterns[t].validate}}))}static testConfig(t,e,n){return ye()(t)?t(e):Qe(t)?Object.keys(t).every((function(r){return zr.patterns[r].test(e,t[r],n)})):null}iterateDatesInRange({start:t,end:e},n){if(!t||!e||!ye()(n))return null;t=this.locale.normalizeDate(t,{...this.opts,time:"00:00:00"});const r={i:0,date:t,day:this.locale.getDateParts(t),finished:!1};let i=null;for(;!r.finished&&r.date<=e;r.i++)i=n(r),r.date=l(r.date,1),r.day=this.locale.getDateParts(r.date);return i}shallowIntersectingRange(t){return this.rangeShallowIntersectingRange(this,this.toDateInfo(t))}rangeShallowIntersectingRange(t,e){if(!this.dateShallowIntersectsDate(t,e))return null;const n=t.toRange(),r=e.toRange();let i=null,a=null;return n.start?i=r.start?n.start>r.start?n.start:r.start:n.start:r.start&&(i=r.start),n.end?a=r.end?n.ende.end)&&!(t.end&&e.start&&t.endt.end):!(t.start&&(!e.start||e.startt.end))}intersectsDay(t){return this.shallowIntersectsDate(t.range)&&this.matchesDay(t)?this:null}matchesDay(t){var e=this;return!this.on||!(this.on.and&&!zr.testConfig(this.on.and,t,this))&&!(this.on.or&&!this.on.or.some((function(n){return zr.testConfig(n,t,e)})))}toRange(){return new zr({start:this.start,end:this.end},this.opts)}compare(t){if(this.order!==t.order)return this.order-t.order;if(this.isDate!==t.isDate)return this.isDate?1:-1;if(this.isDate)return 0;const e=this.start-t.start;return 0!==e?e:this.end-t.end}}const $r={DATE_TIME:1,DATE:2,TIME:3},Yr={1:["year","month","day","hours","minutes","seconds","milliseconds"],2:["year","month","day"],3:["hours","minutes","seconds","milliseconds"]},Hr=/d{1,2}|W{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|Z{1,4}|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,Wr=/\d\d?/,Xr=/\d{3}/,Gr=/\d{4}/,Ur=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF/]+(\s*?[\u0600-\u06FF]+){1,2}/i,qr=/\[([^]*?)\]/gm,Zr=function(){},Kr=function(t){return function(e,n,r){const i=r[t].indexOf(n.charAt(0).toUpperCase()+n.substr(1).toLowerCase());~i&&(e.month=i)}},Jr=["L","iso"],Qr=7,ti=[31,28,31,30,31,30,31,31,30,31,30,31],ei=[{value:0,label:"00"},{value:1,label:"01"},{value:2,label:"02"},{value:3,label:"03"},{value:4,label:"04"},{value:5,label:"05"},{value:6,label:"06"},{value:7,label:"07"},{value:8,label:"08"},{value:9,label:"09"},{value:10,label:"10"},{value:11,label:"11"},{value:12,label:"12"},{value:13,label:"13"},{value:14,label:"14"},{value:15,label:"15"},{value:16,label:"16"},{value:17,label:"17"},{value:18,label:"18"},{value:19,label:"19"},{value:20,label:"20"},{value:21,label:"21"},{value:22,label:"22"},{value:23,label:"23"}],ni={D(t){return t.day},DD(t){return rn(t.day)},Do(t,e){return e.DoFn(t.day)},d(t){return t.weekday-1},dd(t){return rn(t.weekday-1)},W(t,e){return e.dayNamesNarrow[t.weekday-1]},WW(t,e){return e.dayNamesShorter[t.weekday-1]},WWW(t,e){return e.dayNamesShort[t.weekday-1]},WWWW(t,e){return e.dayNames[t.weekday-1]},M(t){return t.month},MM(t){return rn(t.month)},MMM(t,e){return e.monthNamesShort[t.month-1]},MMMM(t,e){return e.monthNames[t.month-1]},YY(t){return String(t.year).substr(2)},YYYY(t){return rn(t.year,4)},h(t){return t.hours%12||12},hh(t){return rn(t.hours%12||12)},H(t){return t.hours},HH(t){return rn(t.hours)},m(t){return t.minutes},mm(t){return rn(t.minutes)},s(t){return t.seconds},ss(t){return rn(t.seconds)},S(t){return Math.round(t.milliseconds/100)},SS(t){return rn(Math.round(t.milliseconds/10),2)},SSS(t){return rn(t.milliseconds,3)},a(t,e){return t.hours<12?e.amPm[0]:e.amPm[1]},A(t,e){return t.hours<12?e.amPm[0].toUpperCase():e.amPm[1].toUpperCase()},Z(){return"Z"},ZZ(t){const e=t.timezoneOffset;return`${e>0?"-":"+"}${rn(Math.floor(Math.abs(e)/60),2)}`},ZZZ(t){const e=t.timezoneOffset;return`${e>0?"-":"+"}${rn(100*Math.floor(Math.abs(e)/60)+Math.abs(e)%60,4)}`},ZZZZ(t){const e=t.timezoneOffset;return`${e>0?"-":"+"}${rn(Math.floor(Math.abs(e)/60),2)}:${rn(Math.abs(e)%60,2)}`}},ri={D:[Wr,function(t,e){t.day=e}],Do:[new RegExp(Wr.source+Ur.source),function(t,e){t.day=parseInt(e,10)}],d:[Wr,Zr],W:[Ur,Zr],M:[Wr,function(t,e){t.month=e-1}],MMM:[Ur,Kr("monthNamesShort")],MMMM:[Ur,Kr("monthNames")],YY:[Wr,function(t,e){const n=new Date,r=+n.getFullYear().toString().substr(0,2);t.year=`${e>68?r-1:r}${e}`}],YYYY:[Gr,function(t,e){t.year=e}],S:[/\d/,function(t,e){t.millisecond=100*e}],SS:[/\d{2}/,function(t,e){t.millisecond=10*e}],SSS:[Xr,function(t,e){t.millisecond=e}],h:[Wr,function(t,e){t.hour=e}],m:[Wr,function(t,e){t.minute=e}],s:[Wr,function(t,e){t.second=e}],a:[Ur,function(t,e,n){const r=e.toLowerCase();r===n.amPm[0]?t.isPm=!1:r===n.amPm[1]&&(t.isPm=!0)}],Z:[/[^\s]*?[+-]\d\d:?\d\d|[^\s]*?Z?/,function(t,e){"Z"===e&&(e="+00:00");const n=(""+e).match(/([+-]|\d\d)/gi);if(n){const e=60*n[1]+parseInt(n[2],10);t.timezoneOffset="+"===n[0]?e:-e}}]};function ii(t,e){const n=(new Intl.DateTimeFormat).resolvedOptions().locale;let r;pe()(t)?r=t:tn(t,"id")&&(r=t.id),r=(r||n).toLowerCase();const i=Object.keys(e),a=function(t){return i.find((function(e){return e.toLowerCase()===t}))};r=a(r)||a(r.substring(0,2))||n;const o={...e["en-IE"],...e[r],id:r};return t=Qe(t)?je()(t,o):o,t}ri.DD=ri.D,ri.dd=ri.d,ri.WWWW=ri.WWW=ri.WW=ri.W,ri.MM=ri.M,ri.mm=ri.m,ri.hh=ri.H=ri.HH=ri.h,ri.ss=ri.s,ri.A=ri.a,ri.ZZZZ=ri.ZZZ=ri.ZZ=ri.Z;class ai{constructor(t,{locales:e=Bn,timezone:n}={}){const{id:r,firstDayOfWeek:i,masks:a}=ii(t,e);this.id=r,this.daysInWeek=Qr,this.firstDayOfWeek=Ce()(i,1,Qr),this.masks=a,this.timezone=n||void 0,this.dayNames=this.getDayNames("long"),this.dayNamesShort=this.getDayNames("short"),this.dayNamesShorter=this.dayNamesShort.map((function(t){return t.substring(0,2)})),this.dayNamesNarrow=this.getDayNames("narrow"),this.monthNames=this.getMonthNames("long"),this.monthNamesShort=this.getMonthNames("short"),this.amPm=["am","pm"],this.monthData={},this.getMonthComps=this.getMonthComps.bind(this),this.parse=this.parse.bind(this),this.format=this.format.bind(this),this.toPage=this.toPage.bind(this)}format(t,e){var n=this;if(t=this.normalizeDate(t),!t)return"";e=this.normalizeMasks(e)[0];const r=[];e=e.replace(qr,(function(t,e){return r.push(e),"??"}));const i=/Z$/.test(e)?"utc":this.timezone,a=this.getDateParts(t,i);return e=e.replace(Hr,(function(t){return t in ni?ni[t](a,n):t.slice(1,t.length-1)})),e.replace(/\?\?/g,(function(){return r.shift()}))}parse(t,e){var n=this;const r=this.normalizeMasks(e);return r.map((function(e){if("string"!==typeof e)throw new Error("Invalid mask in fecha.parse");let r=t;if(r.length>1e3)return!1;let i=!0;const a={};if(e.replace(Hr,(function(t){if(ri[t]){const e=ri[t],o=r.search(e[0]);~o?r.replace(e[0],(function(t){return e[1](a,t,n),r=r.substr(o+t.length),t})):i=!1}return ri[t]?"":t.slice(1,t.length-1)})),!i)return!1;const o=new Date;let s;return!0===a.isPm&&null!=a.hour&&12!==+a.hour?a.hour=+a.hour+12:!1===a.isPm&&12===+a.hour&&(a.hour=0),null!=a.timezoneOffset?(a.minute=+(a.minute||0)-+a.timezoneOffset,s=new Date(Date.UTC(a.year||o.getFullYear(),a.month||0,a.day||1,a.hour||0,a.minute||0,a.second||0,a.millisecond||0))):s=n.getDateFromParts({year:a.year||o.getFullYear(),month:(a.month||0)+1,day:a.day||1,hours:a.hour||0,minutes:a.minute||0,seconds:a.second||0,milliseconds:a.millisecond||0}),s})).find((function(t){return t}))||new Date(t)}normalizeMasks(t){var e=this;return(pn(t)&&t||[pe()(t)&&t||"YYYY-MM-DD"]).map((function(t){return Jr.reduce((function(t,n){return t.replace(n,e.masks[n]||"")}),t)}))}normalizeDate(t,e={}){let n=null,{type:r,fillDate:i}=e;const{mask:a,patch:o,time:s}=e,l="auto"===r||!r;if(de()(t)?(r="number",n=new Date(+t)):pe()(t)?(r="string",n=t?this.parse(t,a||"iso"):null):Qe(t)?(r="object",n=this.getDateFromParts(t)):(r="date",n=Je(t)?new Date(t.getTime()):null),n&&o){i=null==i?new Date:this.normalizeDate(i);const t={...this.getDateParts(i),...Re()(this.getDateParts(n),Yr[o])};n=this.getDateFromParts(t)}return l&&(e.type=r),n&&!isNaN(n.getTime())?(s&&(n=this.adjustTimeForDate(n,{timeAdjust:s})),n):null}denormalizeDate(t,{type:e,mask:n}={}){switch(e){case"number":return t?t.getTime():NaN;case"string":return t?this.format(t,n||"iso"):"";default:return t?new Date(t):null}}hourIsValid(t,e,n){if(!e)return!0;if(ge()(e))return e.includes(t);if(Qe(e)){const n=e.min||0,r=e.max||24;return n<=t&&r>=t}return e(t,n)}getHourOptions(t,e){var n=this;return ei.filter((function(r){return n.hourIsValid(r.value,t,e)}))}getMinuteOptions(t){const e=[];t=t>0?t:1;for(let n=0;n<=59;n+=t)e.push({value:n,label:rn(n,2)});return e}nearestOptionValue(t,e){if(null==t)return t;const n=e.reduce((function(e,n){if(n.disabled)return e;if(isNaN(e))return n.value;const r=Math.abs(e-t),i=Math.abs(n.value-t);return i=s,u=l&&c,h=l||c,d={isDate:i,isComplex:a,onStart:l,onEnd:c,onStartAndEnd:u,onStartOrEnd:h};t.processHighlight(n,d,e),t.processNonHighlight(n,"content",d,e.content),t.processNonHighlight(n,"dot",d,e.dots),t.processNonHighlight(n,"bar",d,e.bars),t.processPopover(n,e)})),this.glyphs=e},processHighlight({key:t,highlight:e},{isDate:n,isComplex:r,onStart:i,onEnd:a,onStartAndEnd:o},{backgrounds:s,content:l}){if(!e)return;const{base:c,start:u,end:h}=e;n||r||o?(s.push({key:t,wrapperClass:"vc-day-layer vc-day-box-center-center",class:["vc-highlight",u.class],style:u.style}),l.push({key:t+"-content",class:u.contentClass,style:u.contentStyle})):i?(s.push({key:t+"-base",wrapperClass:"vc-day-layer vc-day-box-right-center",class:["vc-highlight vc-highlight-base-start",c.class],style:c.style}),s.push({key:t,wrapperClass:"vc-day-layer vc-day-box-center-center",class:["vc-highlight",u.class],style:u.style}),l.push({key:t+"-content",class:u.contentClass,style:u.contentStyle})):a?(s.push({key:t+"-base",wrapperClass:"vc-day-layer vc-day-box-left-center",class:["vc-highlight vc-highlight-base-end",c.class],style:c.style}),s.push({key:t,wrapperClass:"vc-day-layer vc-day-box-center-center",class:["vc-highlight",h.class],style:h.style}),l.push({key:t+"-content",class:h.contentClass,style:h.contentStyle})):(s.push({key:t+"-middle",wrapperClass:"vc-day-layer vc-day-box-center-center",class:["vc-highlight vc-highlight-base-middle",c.class],style:c.style}),l.push({key:t+"-content",class:c.contentClass,style:c.contentStyle}))},processNonHighlight(t,e,{isDate:n,onStart:r,onEnd:i},a){if(!t[e])return;const{key:o}=t,s="vc-"+e,{base:l,start:c,end:u}=t[e];n||r?a.push({key:o,class:[s,c.class],style:c.style}):i?a.push({key:o,class:[s,u.class],style:u.style}):a.push({key:o,class:[s,l.class],style:l.style})},processPopover(t,{popovers:e}){const{key:n,customData:r,popover:i}=t;if(!i)return;const a=Ve()({key:n,customData:r,attribute:t},{...i},{visibility:i.label?"hover":"click",placement:"bottom",isInteractive:!i.label});e.splice(0,0,a)},refreshPopovers(){let t={};pn(this.popovers)&&(t=zi(Ve()({id:this.dayPopoverId,data:this.day},...this.popovers))),this.dayContentEvents=an({click:this.click,mouseenter:this.mouseenter,mouseleave:this.mouseleave,focusin:this.focusin,focusout:this.focusout,keydown:this.keydown},t),Ni({id:this.dayPopoverId,data:this.day})}}},qi=Ui,Zi=(n("1f64"),_n(qi,$i,Yi,!1,null,"4420d078",null)),Ki=Zi.exports,Ji={name:"CalendarPane",mixins:[pi,gi],render(t){var e=this;const n=this.safeScopedSlot("header",this.page)||t("div",{class:"vc-header align-"+this.titlePosition},[t("div",{class:"vc-title",on:this.navPopoverEvents},[this.safeScopedSlot("header-title",this.page,this.page.title)])]),r=this.weekdayLabels.map((function(e,n){return t("div",{key:n+1,class:"vc-weekday"},[e])})),i=this.showWeeknumbers_.startsWith("left"),a=this.showWeeknumbers_.startsWith("right");i?r.unshift(t("div",{class:"vc-weekday"})):a&&r.push(t("div",{class:"vc-weekday"}));const o=function(n){return t("div",{class:["vc-weeknumber"]},[t("span",{class:["vc-weeknumber-content","is-"+e.showWeeknumbers_],on:{click:function(t){e.$emit("weeknumberclick",{weeknumber:n,days:e.page.days.filter((function(t){return t[e.weeknumberKey]===n})),event:t})}}},[n])])},s=[],{daysInWeek:l}=this.locale;this.page.days.forEach((function(n,r){const c=r%l;(i&&0===c||a&&c===l)&&s.push(o(n[e.weeknumberKey])),s.push(t(Ki,{attrs:{day:n},on:{...e.$listeners},scopedSlots:e.$scopedSlots,key:n.id,ref:"days",refInFor:!0})),a&&c===l-1&&s.push(o(n[e.weeknumberKey]))}));const c=t("div",{class:{"vc-weeks":!0,"vc-show-weeknumbers":this.showWeeknumbers_,"is-left":i,"is-right":a}},[r,s]);return t("div",{class:["vc-pane","row-from-end-"+this.rowFromEnd,"column-from-end-"+this.columnFromEnd],ref:"pane"},[n,c])},inheritAttrs:!1,props:{page:Object,position:Number,row:Number,rowFromEnd:Number,column:Number,columnFromEnd:Number,titlePosition:String,navVisibility:String,showWeeknumbers:[Boolean,String],showIsoWeeknumbers:[Boolean,String]},computed:{weeknumberKey(){return this.showWeeknumbers?"weeknumber":"isoWeeknumber"},showWeeknumbers_(){const t=this.showWeeknumbers||this.showIsoWeeknumbers;return null==t?"":ue()(t)?t?"left":"":t.startsWith("right")?this.columnFromEnd>1?"right":t:this.column>1?"left":t},navVisibility_(){return this.propOrDefault("navVisibility","navVisibility")},navPlacement(){switch(this.titlePosition){case"left":return"bottom-start";case"right":return"bottom-end";default:return"bottom"}},navPopoverEvents(){const{sharedState:t,navVisibility_:e,navPlacement:n,page:r,position:i}=this;return zi({id:t.navPopoverId,visibility:e,placement:n,modifiers:[{name:"flip",options:{fallbackPlacements:["bottom"]}}],data:{page:r,position:i},isInteractive:!0})},weekdayLabels(){var t=this;return this.locale.getWeekdayDates().map((function(e){return t.format(e,t.masks.weekdays)}))}},methods:{refresh(){this.$refs.days.forEach((function(t){return t.refresh()}))}}},Qi=Ji,ta=(n("fccf"),n("4889"),_n(Qi,Hi,Wi,!1,null,"74ad501d",null)),ea=ta.exports,na={name:"CustomTransition",render(t){return t("transition",{props:{name:this.name_,appear:this.appear},on:{beforeEnter:this.beforeEnter,afterEnter:this.afterEnter}},[this.$slots.default])},props:{name:String,appear:Boolean},computed:{name_(){return this.name||"none"}},methods:{beforeEnter(t){this.$emit("beforeEnter",t),this.$emit("beforeTransition",t)},afterEnter(t){this.$emit("afterEnter",t),this.$emit("afterTransition",t)}}},ra=na,ia=(n("2285"),_n(ra,Xi,Gi,!1,null,"5be4b00c",null)),aa=ia.exports;class oa{constructor(t,e,n){this.theme=t,this.locale=e,this.map={},this.refresh(n,!0)}destroy(){this.theme=null,this.locale=null,this.map={},this.list=[],this.pinAttr=null}refresh(t,e){var n=this;const r={},i=[];let a=null;const o=[],s=e?new Set:new Set(Object.keys(this.map));return pn(t)&&t.forEach((function(t,l){if(!t||!t.dates)return;const c=t.key?t.key.toString():l.toString(),u=t.order||0,h=wn(JSON.stringify(t));let d=n.map[c];!e&&d&&d.hashcode===h?s.delete(c):(d=new hi({key:c,order:u,hashcode:h,...t},n.theme,n.locale),o.push(d)),d&&d.pinPage&&(a=d),r[c]=d,i.push(d)})),this.map=r,this.list=i,this.pinAttr=a,{adds:o,deletes:Array.from(s)}}}const sa=function(t,e,{maxSwipeTime:n,minHorizontalSwipeDistance:r,maxVerticalSwipeDistance:i}){if(!t||!t.addEventListener||!ye()(e))return null;let a=0,o=0,s=null,l=!1;function c(t){const e=t.changedTouches[0];a=e.screenX,o=e.screenY,s=(new Date).getTime(),l=!0}function u(t){if(!l)return;l=!1;const c=t.changedTouches[0],u=c.screenX-a,h=c.screenY-o,d=(new Date).getTime()-s;if(d=r&&Math.abs(h)<=i){const t={toLeft:!1,toRight:!1};u<0?t.toLeft=!0:t.toRight=!0,e(t)}}return gn(t,"touchstart",c,{passive:!0}),gn(t,"touchend",u,{passive:!0}),function(){mn(t,"touchstart",c),mn(t,"touchend",u)}};n("3ee2");var la,ca,ua={name:"Calendar",render(t){var e=this;const n=this.pages.map((function(n,r){const i=r+1,a=Math.ceil((r+1)/e.columns),o=e.rows-a+1,s=i%e.columns||e.columns,l=e.columns-s+1;return t(ea,{attrs:{...e.$attrs,attributes:e.store},props:{page:n,position:i,row:a,rowFromEnd:o,column:s,columnFromEnd:l,titlePosition:e.titlePosition_},on:{...e.$listeners,dayfocusin:function(t){e.lastFocusedDay=t,e.$emit("dayfocusin",t)},dayfocusout:function(t){e.lastFocusedDay=null,e.$emit("dayfocusout",t)}},scopedSlots:e.$scopedSlots,key:n.key,ref:"pages",refInFor:!0})})),r=function(n){const r=function(){return e.move(n?-e.step_:e.step_)},i=function(t){return bn(t,r)},a=n?!e.canMovePrev:!e.canMoveNext;return t("div",{class:["vc-arrow","is-"+(n?"left":"right"),{"is-disabled":a}],attrs:{role:"button"},on:{click:r,keydown:i}},[(n?e.safeScopedSlot("header-left-button",{click:r}):e.safeScopedSlot("header-right-button",{click:r}))||t(Pi,{props:{name:n?"left-arrow":"right-arrow"}})])},i=function(){return t(Tn,{props:{id:e.sharedState.navPopoverId,contentClass:"vc-nav-popover-container"},ref:"navPopover",scopedSlots:{default:function({data:n}){const{position:r,page:i}=n;return t(ji,{props:{value:i,position:r,validator:function(t){return e.canMove(t,{position:r})}},on:{input:function(t){return e.move(t,{position:r})}},scopedSlots:e.$scopedSlots})}}})},a=function(){return t(Tn,{props:{id:e.sharedState.dayPopoverId,contentClass:"vc-day-popover-container"},scopedSlots:{default:function({data:n,updateLayout:r,hide:i}){const a=Object.values(n.attributes).filter((function(t){return t.popover})),o=e.$locale.masks,s=e.formatDate,l=s(n.date,o.dayPopover);return e.safeScopedSlot("day-popover",{day:n,attributes:a,masks:o,format:s,dayTitle:l,updateLayout:r,hide:i})||t("div",[o.dayPopover&&t("div",{class:["vc-day-popover-header"]},[l]),a.map((function(e){return t(xi,{key:e.key,props:{attribute:e}})}))])}}})};return t("div",{attrs:{"data-helptext":"Press the arrow keys to navigate by day, Home and End to navigate to week ends, PageUp and PageDown to navigate by month, Alt+PageUp and Alt+PageDown to navigate by year"},class:["vc-container","vc-"+this.$theme.color,{"vc-is-expanded":this.isExpanded,"vc-is-dark":this.$theme.isDark}],on:{keydown:this.handleKeydown,mouseup:function(t){return t.preventDefault()}},ref:"container"},[i(),t("div",{class:["vc-pane-container",{"in-transition":this.inTransition}]},[t(aa,{props:{name:this.transitionName},on:{beforeEnter:function(){e.inTransition=!0},afterEnter:function(){e.inTransition=!1}}},[t("div",{class:"vc-pane-layout",style:{gridTemplateColumns:`repeat(${this.columns}, 1fr)`},attrs:{...this.$attrs},key:pn(this.pages)?this.pages[0].key:""},n)]),t("div",{class:["vc-arrows-container title-"+this.titlePosition_]},[r(!0),r(!1)]),this.$scopedSlots.footer&&this.$scopedSlots.footer()]),a()])},mixins:[vi,gi],provide(){return{sharedState:this.sharedState}},props:{rows:{type:Number,default:1},columns:{type:Number,default:1},step:Number,titlePosition:String,isExpanded:Boolean,fromDate:Date,toDate:Date,fromPage:Object,toPage:Object,minPage:Object,maxPage:Object,transition:String,attributes:[Object,Array],trimWeeks:Boolean,disablePageSwipe:Boolean},data(){return{pages:[],store:null,lastFocusedDay:null,focusableDay:(new Date).getDate(),transitionName:"",inTransition:!1,sharedState:{navPopoverId:xn(),dayPopoverId:xn(),theme:{},masks:{},locale:{}}}},computed:{titlePosition_(){return this.propOrDefault("titlePosition","titlePosition")},firstPage(){return Xe()(this.pages)},lastPage(){return Ue()(this.pages)},minPage_(){return this.minPage||this.pageForDate(this.minDate)},maxPage_(){return this.maxPage||this.pageForDate(this.maxDate)},count(){return this.rows*this.columns},step_(){return this.step||this.count},canMovePrev(){return this.canMove(-this.step_)},canMoveNext(){return this.canMove(this.step_)}},watch:{$locale(){this.refreshLocale(),this.refreshPages({page:this.firstPage,ignoreCache:!0}),this.initStore()},$theme(){this.refreshTheme(),this.initStore()},fromDate(){this.refreshPages()},fromPage(t){const e=this.pages&&this.pages[0];un(t,e)||this.refreshPages()},toPage(t){const e=this.pages&&this.pages[this.pages.length-1];un(t,e)||this.refreshPages()},count(){this.refreshPages()},attributes:{handler(t){const{adds:e,deletes:n}=this.store.refresh(t);this.refreshAttrs(this.pages,e,n)},deep:!0},pages(t){this.refreshAttrs(t,this.store.list,null,!0)},disabledAttribute(){this.refreshDisabledDays()},lastFocusedDay(t){t&&(this.focusableDay=t.day,this.refreshFocusableDays())},inTransition(t){t?this.$emit("transition-start"):(this.$emit("transition-end"),this.transitionPromise&&(this.transitionPromise.resolve(!0),this.transitionPromise=null))}},created(){this.refreshLocale(),this.refreshTheme(),this.initStore(),this.refreshPages()},mounted(){var t=this;this.disablePageSwipe||(this.removeHandlers=sa(this.$refs.container,(function({toLeft:e,toRight:n}){e?t.moveNext():n&&t.movePrev()}),this.$defaults.touch))},destroyed(){this.pages=[],this.store.destroy(),this.store=null,this.sharedState=null,this.removeHandlers&&this.removeHandlers()},methods:{refreshLocale(){this.sharedState.locale=this.$locale,this.sharedState.masks=this.$locale.masks},refreshTheme(){this.sharedState.theme=this.$theme},canMove(t,e={}){var n=this;const r=this.$locale.toPage(t,this.firstPage);let{position:i}=e;if(de()(t)&&(i=1),!r)return Promise.reject(new Error("Invalid argument provided: "+t));if(!i)if(sn(r,this.firstPage))i=-1;else{if(!ln(r,this.lastPage))return Promise.resolve(!0);i=1}return Object.assign(e,this.getTargetPageRange(r,{position:i,force:!0})),dn(e.fromPage,e.toPage).some((function(t){return cn(t,n.minPage_,n.maxPage_)}))},movePrev(t){return this.move(-this.step_,t)},moveNext(t){return this.move(this.step_,t)},move(t,e={}){const n=this.canMove(t,e);return e.force||n?(this.$refs.navPopover.hide({hideDelay:0}),e.fromPage&&!un(e.fromPage,this.firstPage)?this.refreshPages({...e,page:e.fromPage,position:1,force:!0}):Promise.resolve(!0)):Promise.reject(new Error("Move target is disabled: "+JSON.stringify(e)))},focusDate(t,e={}){var n=this;return this.move(t,e).then((function(){const e=n.$el.querySelector(`.id-${n.$locale.getDayId(t)}.in-month .vc-focusable`);return e?(e.focus(),Promise.resolve(!0)):Promise.resolve(!1)}))},showPageRange(t,e){let n,r;if(Je(t))n=this.pageForDate(t);else{if(!Qe(t))return Promise.reject(new Error("Invalid page range provided."));{const{month:e,year:i}=t,{from:a,to:o}=t;de()(e)&&de()(i)?n=t:(a||o)&&(n=Je(a)?this.pageForDate(a):a,r=Je(o)?this.pageForDate(o):o)}}const i=this.lastPage;let a=n;return ln(r,i)&&(a=hn(r,-(this.pages.length-1))),sn(a,n)&&(a=n),this.refreshPages({...e,page:a})},getTargetPageRange(t,{position:e,force:n}={}){let r=null,i=null;if(on(t)){let n=0;e=+e,isNaN(e)||(n=e>0?1-e:-(this.count+e)),r=hn(t,n)}else r=this.getDefaultInitialPage();return i=hn(r,this.count-1),n||(sn(r,this.minPage_)?r=this.minPage_:ln(i,this.maxPage_)&&(r=hn(this.maxPage_,1-this.count)),i=hn(r,this.count-1)),{fromPage:r,toPage:i}},getDefaultInitialPage(){let t=this.fromPage||this.pageForDate(this.fromDate);if(!on(t)){const e=this.toPage||this.pageForDate(this.toPage);on(e)&&(t=hn(e,1-this.count))}return on(t)||(t=this.getPageForAttributes()),on(t)||(t=this.pageForThisMonth()),t},refreshPages({page:t,position:e=1,force:n,transition:r,ignoreCache:i}={}){var a=this;return new Promise((function(o,s){const{fromPage:l,toPage:c}=a.getTargetPageRange(t,{position:e,force:n}),u=[];for(let t=0;t1||!on(t)||!on(e))return"fade";const r=sn(e,t);return"slide-v"===n?r?"slide-down":"slide-up":r?"slide-right":"slide-left"},getPageForAttributes(){let t=null;const e=this.store.pinAttr;if(e&&e.hasDates){let[n]=e.dates;n=n.start||n.date,t=this.pageForDate(n)}return t},buildPage({month:t,year:e},n){var r=this;const i=`${e.toString()}-${t.toString()}`;let a=this.pages.find((function(t){return t.key===i}));if(!a||n){const n=new Date(e,t-1,15),o=this.$locale.getMonthComps(t,e),s=this.$locale.getPrevMonthComps(t,e),l=this.$locale.getNextMonthComps(t,e);a={key:i,month:t,year:e,weeks:this.trimWeeks?o.weeks:6,title:this.$locale.format(n,this.$locale.masks.title),shortMonthLabel:this.$locale.format(n,"MMM"),monthLabel:this.$locale.format(n,"MMMM"),shortYearLabel:e.toString().substring(2),yearLabel:e.toString(),monthComps:o,prevMonthComps:s,nextMonthComps:l,canMove:function(t){return r.canMove(t)},move:function(t){return r.move(t)},moveThisMonth:function(){return r.moveThisMonth()},movePrevMonth:function(){return r.move(s)},moveNextMonth:function(){return r.move(l)},refresh:!0},a.days=this.$locale.getCalendarDays(a)}return a},initStore(){this.store=new oa(this.$theme,this.$locale,this.attributes),this.refreshAttrs(this.pages,this.store.list,[],!0)},refreshAttrs(t=[],e=[],n=[],r){var i=this;pn(t)&&(t.forEach((function(t){t.days.forEach((function(t){let i={};r?t.refresh=!0:en(t.attributesMap,n)?(i=Ne()(t.attributesMap,n),t.refresh=!0):i=t.attributesMap||{},e.forEach((function(e){const n=e.intersectsDay(t);if(n){const r={...e,targetDate:n};i[e.key]=r,t.refresh=!0}})),t.refresh&&(t.attributesMap=i)}))})),this.$nextTick((function(){i.$refs.pages.forEach((function(t){return t.refresh()}))})))},handleKeydown(t){const e=this.lastFocusedDay;null!=e&&(e.event=t,this.handleDayKeydown(e))},handleDayKeydown(t){const{dateFromTime:e,event:n}=t,r=e(12);let i=null;switch(n.key){case"ArrowLeft":i=l(r,-1);break;case"ArrowRight":i=l(r,1);break;case"ArrowUp":i=l(r,-7);break;case"ArrowDown":i=l(r,7);break;case"Home":i=l(r,1-t.weekdayPosition);break;case"End":i=l(r,t.weekdayPositionFromEnd);break;case"PageUp":i=n.altKey?u(r,-1):c(r,-1);break;case"PageDown":i=n.altKey?u(r,1):c(r,1);break}i&&(n.preventDefault(),this.focusDate(i).catch((function(){})))}}},ha=ua,da=(n("de5e"),_n(ha,la,ca,!1,null,null,null)),fa=da.exports,pa=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"vc-time-picker",class:[{"vc-disabled":t.isDisabled,"vc-bordered":t.showBorder}]},[n("div",[n("svg",{staticClass:"vc-time-icon",attrs:{fill:"none","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",viewBox:"0 0 24 24",stroke:"currentColor"}},[n("path",{attrs:{d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"}})])]),n("div",{staticClass:"vc-date-time"},[t.date?n("div",{staticClass:"vc-date"},[n("span",{staticClass:"vc-weekday"},[t._v(" "+t._s(t.locale.format(t.date,"WWW"))+" ")]),n("span",{staticClass:"vc-month"},[t._v(" "+t._s(t.locale.format(t.date,"MMM"))+" ")]),n("span",{staticClass:"vc-day"},[t._v(" "+t._s(t.locale.format(t.date,"D"))+" ")]),n("span",{staticClass:"vc-year"},[t._v(" "+t._s(t.locale.format(t.date,"YYYY"))+" ")])]):t._e(),n("div",{staticClass:"vc-time"},[n("time-select",{attrs:{options:t.hourOptions_},model:{value:t.hours,callback:function(e){t.hours=t._n(e)},expression:"hours"}}),n("span",{staticStyle:{margin:"0 4px"}},[t._v(":")]),n("time-select",{attrs:{options:t.minuteOptions},model:{value:t.minutes,callback:function(e){t.minutes=t._n(e)},expression:"minutes"}}),t.is24hr?t._e():n("div",{staticClass:"vc-am-pm",class:{"vc-disabled":!(t.hours>=0)}},[n("button",{class:{active:t.isAM,"vc-disabled":t.amDisabled},attrs:{type:"button"},on:{click:function(e){e.preventDefault(),t.isAM=!0}}},[t._v(" AM ")]),n("button",{class:{active:!t.isAM,"vc-disabled":t.pmDisabled},attrs:{type:"button"},on:{click:function(e){e.preventDefault(),t.isAM=!1}}},[t._v(" PM ")])])],1)])])},va=[],ga=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"vc-select"},[n("select",t._b({directives:[{name:"model",rawName:"v-model",value:t.model,expression:"model"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,(function(t){return t.selected})).map((function(t){var e="_value"in t?t._value:t.value;return e}));t.model=e.target.multiple?n:n[0]}}},"select",t.$attrs,!1),t._l(t.options,(function(e){return n("option",{key:e.value,attrs:{disabled:e.disabled},domProps:{value:e.value}},[t._v(" "+t._s(e.label)+" ")])})),0),n("div",{staticClass:"vc-select-arrow"},[n("svg",{attrs:{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20"}},[n("path",{attrs:{d:"M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"}})])])])},ma=[],ya={inheritAttrs:!1,props:{options:Array,value:Number},computed:{model:{get(){return this.value},set(t){this.$emit("input",t)}}}},ba=ya,xa=(n("87a9"),_n(ba,ga,ma,!1,null,"7b2eaf0a",null)),wa=xa.exports;const ka=[{value:0,label:"12"},{value:1,label:"1"},{value:2,label:"2"},{value:3,label:"3"},{value:4,label:"4"},{value:5,label:"5"},{value:6,label:"6"},{value:7,label:"7"},{value:8,label:"8"},{value:9,label:"9"},{value:10,label:"10"},{value:11,label:"11"}],Sa=[{value:12,label:"12"},{value:13,label:"1"},{value:14,label:"2"},{value:15,label:"3"},{value:16,label:"4"},{value:17,label:"5"},{value:18,label:"6"},{value:19,label:"7"},{value:20,label:"8"},{value:21,label:"9"},{value:22,label:"10"},{value:23,label:"11"}];var Ca={name:"TimePicker",components:{TimeSelect:wa},props:{value:{type:Object,required:!0},locale:{type:Object,required:!0},theme:{type:Object,required:!0},is24hr:{type:Boolean,default:!0},showBorder:Boolean,isDisabled:Boolean,hourOptions:Array,minuteOptions:Array},computed:{date(){let t=this.locale.normalizeDate(this.value);return 24===this.value.hours&&(t=new Date(t.getTime()-1)),t},hours:{get(){return this.value.hours},set(t){this.updateValue(t,this.minutes)}},minutes:{get(){return this.value.minutes},set(t){this.updateValue(this.hours,t)}},isAM:{get(){return this.value.hours<12},set(t){let e=this.hours;t&&e>=12?e-=12:!t&&e<12&&(e+=12),this.updateValue(e,this.minutes)}},amHourOptions(){var t=this;return ka.filter((function(e){return t.hourOptions.some((function(t){return t.value===e.value}))}))},pmHourOptions(){var t=this;return Sa.filter((function(e){return t.hourOptions.some((function(t){return t.value===e.value}))}))},hourOptions_(){return this.is24hr?this.hourOptions:this.isAM?this.amHourOptions:this.pmHourOptions},amDisabled(){return!pn(this.amHourOptions)},pmDisabled(){return!pn(this.pmHourOptions)}},methods:{updateValue(t,e){t===this.hours&&e===this.minutes||this.$emit("input",{...this.value,hours:t,minutes:e,seconds:0,milliseconds:0})}}},Aa=Ca,_a=(n("27e3"),_n(Aa,pa,va,!1,null,"f4e11af8",null)),Da=_a.exports;const Ta={type:"auto",mask:"iso",timeAdjust:""},Ea=[Ta,Ta],Oa={DATE:"date",DATE_TIME:"datetime",TIME:"time"},Pa={NONE:0,START:1,END:2,BOTH:3};var Ia,Ma,Va={name:"DatePicker",render(t){var e=this;const n=function(){if(!e.dateParts)return null;const n=e.isRange?e.dateParts:[e.dateParts[0]];return t("div",[...n.map((function(n,r){const i=e.$locale.getHourOptions(e.modelConfig_[r].validHours,n),a=e.$locale.getMinuteOptions(e.modelConfig_[r].minuteIncrement,n);return t(Da,{props:{value:n,locale:e.$locale,theme:e.$theme,is24hr:e.is24hr,minuteIncrement:e.minuteIncrement,showBorder:!e.isTime,isDisabled:e.isDateTime&&!n.isValid||e.isDragging,hourOptions:i,minuteOptions:a},on:{input:function(t){return e.onTimeInput(t,0===r)}}})})),e.$scopedSlots.footer&&e.$scopedSlots.footer()])},r=function(){return t(fa,{attrs:{...e.$attrs,attributes:e.attributes_,theme:e.$theme,locale:e.$locale},props:{minDate:e.minDateExact||e.minDate,maxDate:e.maxDateExact||e.maxDate,disabledDates:e.disabledDates,availableDates:e.availableDates},on:{...e.$listeners,dayclick:e.onDayClick,daykeydown:e.onDayKeydown,daymouseenter:e.onDayMouseEnter},scopedSlots:{...e.$scopedSlots,footer:e.isDateTime?n:e.$scopedSlots.footer},ref:"calendar"})},i=function(){return e.isTime?t("div",{class:["vc-container","vc-"+e.$theme.color,{"vc-is-dark":e.$theme.isDark}]},[n()]):r()};return this.$scopedSlots.default&&t("span",[this.$scopedSlots.default(this.slotArgs),t(Tn,{props:{id:this.datePickerPopoverId,placement:"bottom-start",contentClass:"vc-container"+(this.isDark?" vc-is-dark":"")},on:{beforeShow:function(t){return e.$emit("popoverWillShow",t)},afterShow:function(t){return e.$emit("popoverDidShow",t)},beforeHide:function(t){return e.$emit("popoverWillHide",t)},afterHide:function(t){return e.$emit("popoverDidHide",t)}},scopedSlots:{default(){return i()}},ref:"popover"})])||i()},mixins:[vi],props:{mode:{type:String,default:Oa.DATE},value:{type:null,required:!0},modelConfig:{type:Object,default:function(){return{}}},is24hr:Boolean,minuteIncrement:Number,isRequired:Boolean,isRange:Boolean,updateOnInput:Boolean,inputDebounce:Number,popover:{type:Object,default:function(){return{}}},dragAttribute:Object,selectAttribute:Object,attributes:Array,validHours:[Object,Array,Function]},data(){return{value_:null,dateParts:null,activeDate:"",dragValue:null,inputValues:["",""],updateTimeout:null,watchValue:!0,datePickerPopoverId:xn()}},computed:{updateOnInput_(){return this.propOrDefault("updateOnInput","datePicker.updateOnInput")},inputDebounce_(){return this.propOrDefault("inputDebounce","datePicker.inputDebounce")},isDate(){return this.mode.toLowerCase()===Oa.DATE},isDateTime(){return this.mode.toLowerCase()===Oa.DATE_TIME},isTime(){return this.mode.toLowerCase()===Oa.TIME},isDragging(){return!!this.dragValue&&this.isRange},modelConfig_(){return this.normalizeConfig(this.modelConfig,Ea)},inputMask(){const t=this.$locale.masks;return this.isTime?this.is24hr?t.inputTime24hr:t.inputTime:this.isDateTime?this.is24hr?t.inputDateTime24hr:t.inputDateTime:this.$locale.masks.input},inputMaskHasTime(){return/[Hh]/g.test(this.inputMask)},inputMaskHasDate(){return/[dD]{1,2}|Do|W{1,4}|M{1,4}|YY(?:YY)?/g.test(this.inputMask)},inputMaskPatch(){return this.inputMaskHasTime&&this.inputMaskHasDate?$r.DATE_TIME:this.inputMaskHasDate?$r.DATE:this.inputMaskHasTime?$r.TIME:void 0},slotArgs(){var t=this;const{isRange:e,isDragging:n,updateValue:r,showPopover:i,hidePopover:a,togglePopover:o}=this,s=e?{start:this.inputValues[0],end:this.inputValues[1]}:this.inputValues[0],l=[!0,!1].map((function(e){return{input:t.onInputInput(e),change:t.onInputChange(e),keyup:t.onInputKeyup,...zi({...t.popover_,id:t.datePickerPopoverId,callback:function(n){"show"===n.action&&n.completed&&t.onInputShow(e)}})}})),c=e?{start:l[0],end:l[1]}:l[0];return{inputValue:s,inputEvents:c,isDragging:n,updateValue:r,showPopover:i,hidePopover:a,togglePopover:o,getPopoverTriggerEvents:zi}},popover_(){return this.propOrDefault("popover","datePicker.popover","merge")},selectAttribute_(){if(!this.hasValue(this.value_))return null;const t={key:"select-drag",...this.selectAttribute,dates:this.value_,pinPage:!0},{dot:e,bar:n,highlight:r,content:i}=t;return e||n||r||i||(t.highlight=!0),t},dragAttribute_(){if(!this.isRange||!this.hasValue(this.dragValue))return null;const t={key:"select-drag",...this.dragAttribute,dates:this.dragValue},{dot:e,bar:n,highlight:r,content:i}=t;return e||n||r||i||(t.highlight={startEnd:{fillMode:"outline"}}),t},attributes_(){const t=ge()(this.attributes)?[...this.attributes]:[];return this.dragAttribute_?t.push(this.dragAttribute_):this.selectAttribute_&&t.push(this.selectAttribute_),t}},watch:{inputMask(){this.formatInput()},value(t){this.watchValue&&this.forceUpdateValue(t,{config:this.modelConfig_,notify:!1,formatInput:!0,hidePopover:!1})},value_(){this.refreshDateParts()},dragValue(){this.refreshDateParts()},timezone(){this.refreshDateParts(),this.forceUpdateValue(this.value_,{formatInput:!0})}},created(){this.value_=this.normalizeValue(this.value,this.modelConfig_,$r.DATE_TIME,Pa.BOTH),this.forceUpdateValue(this.value,{config:this.modelConfig_,formatInput:!0,hidePopover:!1}),this.refreshDateParts()},mounted(){gn(document,"keydown",this.onDocumentKeyDown),gn(document,"click",this.onDocumentClick)},destroyed(){mn(document,"keydown",this.onDocumentKeyDown),mn(document,"click",this.onDocumentClick)},methods:{getDateParts(t){return this.$locale.getDateParts(t)},getDateFromParts(t){return this.$locale.getDateFromParts(t)},refreshDateParts(){var t=this;const e=this.dragValue||this.value_,n=[];this.isRange?(e&&e.start?n.push(this.getDateParts(e.start)):n.push({}),e&&e.end?n.push(this.getDateParts(e.end)):n.push({})):e?e&&e.start?n.push(this.getDateParts(e.start)):n.push(this.getDateParts(e)):n.push({}),this.$nextTick((function(){return t.dateParts=n}))},onDocumentKeyDown(t){this.dragValue&&"Escape"===t.key&&(this.dragValue=null)},onDocumentClick(t){document.body.contains(t.target)&&!yn(this.$el,t.target)&&(this.dragValue=null,this.formatInput())},onDayClick(t){this.handleDayClick(t),this.$emit("dayclick",t)},onDayKeydown(t){switch(t.event.key){case" ":case"Enter":this.handleDayClick(t),t.event.preventDefault();break;case"Escape":this.hidePopover()}this.$emit("daykeydown",t)},handleDayClick(t){const{keepVisibleOnInput:e,visibility:n}=this.popover_,r={patch:$r.DATE,adjustTime:!0,formatInput:!0,hidePopover:this.isDate&&!e&&"visible"!==n};this.isRange?(this.isDragging?this.dragTrackingValue.end=t.date:this.dragTrackingValue={...t.range},r.isDragging=!this.isDragging,r.rangePriority=r.isDragging?Pa.NONE:Pa.BOTH,r.hidePopover=r.hidePopover&&!r.isDragging,this.updateValue(this.dragTrackingValue,r)):(r.clearIfEqual=!this.isRequired,this.updateValue(t.date,r))},onDayMouseEnter(t){this.isDragging&&(this.dragTrackingValue.end=t.date,this.updateValue(this.dragTrackingValue,{patch:$r.DATE,adjustTime:!0,formatInput:!0,hidePopover:!1,rangePriority:Pa.NONE}))},onTimeInput(t,e){var n=this;let r=null;if(this.isRange){const n=e?t:this.dateParts[0],i=e?this.dateParts[1]:t;r={start:n,end:i}}else r=t;this.updateValue(r,{patch:$r.TIME,rangePriority:e?Pa.START:Pa.END}).then((function(){return n.adjustPageRange(e)}))},onInputInput(t){var e=this;return function(n){e.updateOnInput_&&e.onInputUpdate(n.target.value,t,{formatInput:!1,hidePopover:!1,debounce:e.inputDebounce_})}},onInputChange(t){var e=this;return function(n){e.onInputUpdate(n.target.value,t,{formatInput:!0,hidePopover:!1})}},onInputUpdate(t,e,n){var r=this;this.inputValues.splice(e?0:1,1,t);const i=this.isRange?{start:this.inputValues[0],end:this.inputValues[1]||this.inputValues[0]}:t,a={type:"string",mask:this.inputMask};this.updateValue(i,{...n,config:a,patch:this.inputMaskPatch,rangePriority:e?Pa.START:Pa.END}).then((function(){return r.adjustPageRange(e)}))},onInputShow(t){this.adjustPageRange(t)},onInputKeyup(t){"Escape"===t.key&&this.updateValue(this.value_,{formatInput:!0,hidePopover:!0})},normalizeConfig(t,e=this.modelConfig_){var n=this;return t=ge()(t)?t:[t.start||t,t.end||t],e.map((function(e,r){return{validHours:n.validHours,minuteIncrement:n.minuteIncrement,...e,...t[r]}}))},updateValue(t,e={}){var n=this;return clearTimeout(this.updateTimeout),new Promise((function(r){const{debounce:i,...a}=e;i>0?n.updateTimeout=setTimeout((function(){n.forceUpdateValue(t,a),r(n.value_)}),i):(n.forceUpdateValue(t,a),r(n.value_))}))},forceUpdateValue(t,{config:e=this.modelConfig_,patch:n=$r.DATE_TIME,clearIfEqual:r=!1,formatInput:i=!0,hidePopover:a=!1,isDragging:o=this.isDragging,rangePriority:s=Pa.BOTH}={}){var l=this;e=this.normalizeConfig(e);let c=this.normalizeValue(t,e,n,s);!c&&this.isRequired&&(c=this.value_),c=this.adjustTimeForValue(c,e);const u=this.valueIsDisabled(c);if(u){if(o)return;c=this.value_,a=!1}const h=o?"dragValue":"value_";let d=!this.valuesAreEqual(this[h],c);if(u||d||!r||(c=null,d=!0),d){this.$set(this,h,c),o||(this.dragValue=null);const t=this.denormalizeValue(c),e=this.isDragging?"drag":"input";this.watchValue=!1,this.$emit(e,t),this.$nextTick((function(){return l.watchValue=!0}))}a&&this.hidePopover(),i&&this.formatInput()},hasValue(t){return this.isRange?Qe(t)&&!!t.start&&!!t.end:!!t},normalizeValue(t,e,n,r){if(!this.hasValue(t))return null;if(this.isRange){const i={},a=t.start>t.end?t.end:t.start;i.start=this.normalizeDate(a,{...e[0],fillDate:this.value_&&this.value_.start||e[0].fillDate,patch:n});const o=t.start>t.end?t.start:t.end;return i.end=this.normalizeDate(o,{...e[1],fillDate:this.value_&&this.value_.end||e[1].fillDate,patch:n}),this.sortRange(i,r)}return this.normalizeDate(t,{...e[0],fillDate:this.value_||e[0].fillDate,patch:n})},adjustTimeForValue(t,e){return this.hasValue(t)?this.isRange?{start:this.$locale.adjustTimeForDate(t.start,e[0]),end:this.$locale.adjustTimeForDate(t.end,e[1])}:this.$locale.adjustTimeForDate(t,e[0]):null},sortRange(t,e=Pa.NONE){const{start:n,end:r}=t;if(n>r)switch(e){case Pa.START:return{start:n,end:n};case Pa.END:return{start:r,end:r};case Pa.BOTH:return{start:r,end:n}}return{start:n,end:r}},denormalizeValue(t,e=this.modelConfig_){return this.isRange?this.hasValue(t)?{start:this.$locale.denormalizeDate(t.start,e[0]),end:this.$locale.denormalizeDate(t.end,e[1])}:null:this.$locale.denormalizeDate(t,e[0])},valuesAreEqual(t,e){if(this.isRange){const n=this.hasValue(t),r=this.hasValue(e);return!n&&!r||n===r&&(fn(t.start,e.start)&&fn(t.end,e.end))}return fn(t,e)},valueIsDisabled(t){return this.hasValue(t)&&this.disabledAttribute&&this.disabledAttribute.intersectsDate(t)},formatInput(){var t=this;this.$nextTick((function(){const e=t.normalizeConfig({type:"string",mask:t.inputMask}),n=t.denormalizeValue(t.dragValue||t.value_,e);t.isRange?t.inputValues=[n&&n.start,n&&n.end]:t.inputValues=[n,""]}))},showPopover(t={}){Bi({ref:this.$el,...this.popover_,...t,isInteractive:!0,id:this.datePickerPopoverId})},hidePopover(t={}){Ri({hideDelay:10,...this.popover_,...t,id:this.datePickerPopoverId})},togglePopover(t){Fi({ref:this.$el,...this.popover_,...t,isInteractive:!0,id:this.datePickerPopoverId})},adjustPageRange(t){var e=this;this.$nextTick((function(){const n=e.$refs.calendar,r=e.getPageForValue(t),i=t?1:-1;r&&n&&!cn(r,n.firstPage,n.lastPage)&&n.move(r,{position:i,transition:"fade"})}))},getPageForValue(t){return this.hasValue(this.value_)?this.pageForDate(this.isRange?this.value_[t?"start":"end"]:this.value_):null},move(t,e){return this.$refs.calendar?this.$refs.calendar.move(t,e):Promise.reject(new Error("Navigation disabled while calendar is not yet displayed"))},focusDate(t,e){return this.$refs.calendar?this.$refs.calendar.focusDate(t,e):Promise.reject(new Error("Navigation disabled while calendar is not yet displayed"))}}},La=Va,ja=_n(La,Ia,Ma,!1,null,null,null),Ba=ja.exports;e["default"]=Ba},fba5:function(t,e,n){var r=n("cb5a");function i(t){return r(this.__data__,t)>-1}t.exports=i},fc6a:function(t,e,n){var r=n("44ad"),i=n("1d80");t.exports=function(t){return r(i(t))}},fccf:function(t,e,n){"use strict";var r=n("53b1"),i=n.n(r);i.a},fce3:function(t,e,n){var r=n("d039");t.exports=r((function(){var t=RegExp(".","string".charAt(0));return!(t.dotAll&&t.exec("\n")&&"s"===t.flags)}))},fcff:function(t,e,n){var r=n("24fb");e=r(!1),e.push([t.i,".vc-svg-icon[data-v-63f7b5ec]{display:inline-block;stroke:currentColor;stroke-width:0}.vc-svg-icon path[data-v-63f7b5ec]{fill:currentColor}",""]),t.exports=e},fdbc:function(t,e){t.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},fdbf:function(t,e,n){var r=n("4930");t.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},ffd6:function(t,e,n){var r=n("3729"),i=n("1310"),a="[object Symbol]";function o(t){return"symbol"==typeof t||i(t)&&r(t)==a}t.exports=o}})["default"]}))},"408c":function(t,e,n){var r=n("2b3e"),i=function(){return r.Date.now()};t.exports=i},"40c3":function(t,e,n){var r=n("6b4c"),i=n("5168")("toStringTag"),a="Arguments"==r(function(){return arguments}()),o=function(t,e){try{return t[e]}catch(n){}};t.exports=function(t){var e,n,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=o(e=Object(t),i))?n:a?r(e):"Object"==(s=r(e))&&"function"==typeof e.callee?"Arguments":s}},4178:function(t,e,n){var r,i,a,o=n("d864"),s=n("3024"),l=n("32fc"),c=n("1ec9"),u=n("e53d"),h=u.process,d=u.setImmediate,f=u.clearImmediate,p=u.MessageChannel,v=u.Dispatch,g=0,m={},y="onreadystatechange",b=function(){var t=+this;if(m.hasOwnProperty(t)){var e=m[t];delete m[t],e()}},x=function(t){b.call(t.data)};d&&f||(d=function(t){var e=[],n=1;while(arguments.length>n)e.push(arguments[n++]);return m[++g]=function(){s("function"==typeof t?t:Function(t),e)},r(g),g},f=function(t){delete m[t]},"process"==n("6b4c")(h)?r=function(t){h.nextTick(o(b,t,1))}:v&&v.now?r=function(t){v.now(o(b,t,1))}:p?(i=new p,a=i.port2,i.port1.onmessage=x,r=o(a.postMessage,a,1)):u.addEventListener&&"function"==typeof postMessage&&!u.importScripts?(r=function(t){u.postMessage(t+"","*")},u.addEventListener("message",x,!1)):r=y in c("script")?function(t){l.appendChild(c("script"))[y]=function(){l.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),t.exports={set:d,clear:f}},"41a0":function(t,e,n){"use strict";var r=n("2aeb"),i=n("4630"),a=n("7f20"),o={};n("32e9")(o,n("2b4c")("iterator"),(function(){return this})),t.exports=function(t,e,n){t.prototype=r(o,{next:i(1,n)}),a(t,e+" Iterator")}},"41c3":function(t,e,n){var r=n("1a8c"),i=n("eac5"),a=n("ec8c"),o=Object.prototype,s=o.hasOwnProperty;function l(t){if(!r(t))return a(t);var e=i(t),n=[];for(var o in t)("constructor"!=o||!e&&s.call(t,o))&&n.push(o);return n}t.exports=l},4208:function(t,e,n){!function(e,n){t.exports=n()}(0,(function(){"use strict";return function(t,e,n){t=t||{};var r=e.prototype,i={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function a(t,e,n,i){return r.fromToBase(t,e,n,i)}n.en.relativeTime=i,r.fromToBase=function(e,r,a,o,s){for(var l,c,u,h=a.$locale().relativeTime||i,d=t.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],f=d.length,p=0;p0,g<=v.r||!v.r){g<=1&&p>0&&(v=d[p-1]);var m=h[v.l];s&&(g=s(""+g)),c="string"==typeof m?m.replace("%d",g):m(g,r,v.l,u);break}}if(r)return c;var y=u?h.future:h.past;return"function"==typeof y?y(c):y.replace("%s",c)},r.to=function(t,e){return a(t,e,this,!0)},r.from=function(t,e){return a(t,e,this)};var o=function(t){return t.$u?n.utc():n()};r.toNow=function(t){return this.to(o(this),t)},r.fromNow=function(t){return this.from(o(this),t)}}}))},4245:function(t,e,n){var r=n("1290");function i(t,e){var n=t.__data__;return r(e)?n["string"==typeof e?"string":"hash"]:n.map}t.exports=i},42454:function(t,e,n){var r=n("f909"),i=n("2ec1"),a=i((function(t,e,n){r(t,e,n)}));t.exports=a},4284:function(t,e){function n(t,e){var n=-1,r=null==t?0:t.length;while(++ne?1:0},e.require(t,"_$_$_cmp"),e.spread((function(t){var e=t.sort(_$_$_cmp);resolve(e)})).then((function(e){for(var i=function(r,i,a){i=Math.min(i,n),a=Math.min(a,n);for(var o=r,s=i,l=[],c=o;c=a||t(u,h)<=0)?(l.push(u),r++):(l.push(h),i++)}for(c=0;c1?", "+JSON.stringify(n):"")+" );"," "," resolve = origResolve;"," resolve( res.length > 0 ? res : ret );","}"].join("\n"))}};util.extend(thdfn,{reduce:defineFnal({name:"reduce"}),reduceRight:defineFnal({name:"reduceRight"}),map:defineFnal({name:"map"})});var fn=thdfn;fn.promise=fn.run,fn.terminate=fn.halt=fn.stop,fn.include=fn.require,util.extend(thdfn,{on:define.on(),one:define.on({unbindSelfOnTrigger:!0}),off:define.off(),trigger:define.trigger()}),define.eventAliasesOn(thdfn),module.exports=Thread},{"./define":1,"./event":2,"./is":5,"./promise":6,"./util":8,"./window":9,child_process:void 0,path:void 0}],8:[function(t,e,n){"use strict";var r,i=t("./is");r={extend:function(){var t,e,n,a,o,s,l=arguments[0]||{},c=1,u=arguments.length,h=!1;for("boolean"===typeof l&&(h=l,l=arguments[1]||{},c=2),"object"===typeof l||i.fn(l)||(l={}),u===c&&(l=this,--c);c0?r:n)(t)}},4589:function(t,e){function n(){var t={};t._next=t._prev=t,this._sentinel=t}function r(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function i(t,e){if("_next"!==t&&"_prev"!==t)return e}t.exports=n,n.prototype.dequeue=function(){var t=this._sentinel,e=t._prev;if(e!==t)return r(e),e},n.prototype.enqueue=function(t){var e=this._sentinel;t._prev&&t._next&&r(t),t._next=e._next,e._next._prev=t,e._next=t,t._prev=e},n.prototype.toString=function(){var t=[],e=this._sentinel,n=e._prev;while(n!==e)t.push(JSON.stringify(n,i)),n=n._prev;return"["+t.join(", ")+"]"}},"45ee":function(t,e,n){"use strict";var r=n("6f9c"),i=n("b50e");function a(t){t.graph().dummyChains=[],r.forEach(t.edges(),(function(e){o(t,e)}))}function o(t,e){var n=e.v,r=t.node(n).rank,a=e.w,o=t.node(a).rank,s=e.name,l=t.edge(e),c=l.labelRank;if(o!==r+1){var u,h,d;for(t.removeEdge(e),d=0,++r;rc)l.call(t,o=s[c++])&&e.push(o)}return e}},"47f5":function(t,e,n){var r=n("2b03"),i=n("d9a8"),a=n("099a");function o(t,e,n){return e===e?a(t,e,n):r(t,i,n)}t.exports=o},"481b":function(t,e){t.exports={}},"48a0":function(t,e,n){var r=n("242e"),i=n("950a"),a=i(r);t.exports=a},4917:function(t,e,n){"use strict";var r=n("cb7c"),i=n("9def"),a=n("0390"),o=n("5f1b");n("214f")("match",1,(function(t,e,n,s){return[function(n){var r=t(this),i=void 0==n?void 0:n[e];return void 0!==i?i.call(n,r):new RegExp(n)[e](String(r))},function(t){var e=s(n,t,this);if(e.done)return e.value;var l=r(t),c=String(this);if(!l.global)return o(l,c);var u=l.unicode;l.lastIndex=0;var h,d=[],f=0;while(null!==(h=o(l,c))){var p=String(h[0]);d[f]=p,""===p&&(l.lastIndex=a(c,i(l.lastIndex),u)),f++}return 0===f?null:d}]}))},"49f4":function(t,e,n){var r=n("6044");function i(){this.__data__=r?r(null):{},this.size=0}t.exports=i},"4a59":function(t,e,n){var r=n("9b43"),i=n("1fa8"),a=n("33a4"),o=n("cb7c"),s=n("9def"),l=n("27ee"),c={},u={};e=t.exports=function(t,e,n,h,d){var f,p,v,g,m=d?function(){return t}:l(t),y=r(n,h,e?2:1),b=0;if("function"!=typeof m)throw TypeError(t+" is not iterable!");if(a(m)){for(f=s(t.length);f>b;b++)if(g=e?y(o(p=t[b])[0],p[1]):y(t[b]),g===c||g===u)return g}else for(v=m.call(t);!(p=v.next()).done;)if(g=i(v,y,p.value,e),g===c||g===u)return g};e.BREAK=c,e.RETURN=u},"4b17":function(t,e,n){var r=n("6428");function i(t){var e=r(t),n=e%1;return e===e?n?e-n:e:0}t.exports=i},"4bf8":function(t,e,n){var r=n("be13");t.exports=function(t){return Object(r(t))}},"4c95":function(t,e,n){"use strict";var r=n("e53d"),i=n("584a"),a=n("d9f6"),o=n("8e60"),s=n("5168")("species");t.exports=function(t){var e="function"==typeof i[t]?i[t]:r[t];o&&e&&!e[s]&&a.f(e,s,{configurable:!0,get:function(){return this}})}},"4cef":function(t,e){var n=/\s/;function r(t){var e=t.length;while(e--&&n.test(t.charAt(e)));return e}t.exports=r},"4cfe":function(t,e){function n(t){return void 0===t}t.exports=n},"4d8c":function(t,e,n){var r=n("5c69");function i(t){var e=null==t?0:t.length;return e?r(t,1):[]}t.exports=i},"4ee1":function(t,e,n){var r=n("5168")("iterator"),i=!1;try{var a=[7][r]();a["return"]=function(){i=!0},Array.from(a,(function(){throw 2}))}catch(o){}t.exports=function(t,e){if(!e&&!i)return!1;var n=!1;try{var a=[7],s=a[r]();s.next=function(){return{done:n=!0}},a[r]=function(){return s},t(a)}catch(o){}return n}},"4f17":function(t,e,n){var r=n("df2e");function i(t,e){return r(t,e,"post")}t.exports=i},"4f50":function(t,e,n){var r=n("b760"),i=n("e538"),a=n("c8fe"),o=n("4359"),s=n("fa21"),l=n("d370"),c=n("6747"),u=n("dcbe"),h=n("0d24"),d=n("9520"),f=n("1a8c"),p=n("60ed"),v=n("73ac"),g=n("8adb"),m=n("8de2");function y(t,e,n,y,b,x,w){var k=g(t,n),S=g(e,n),C=w.get(S);if(C)r(t,n,C);else{var A=x?x(k,S,n+"",t,e,w):void 0,_=void 0===A;if(_){var D=c(S),T=!D&&h(S),E=!D&&!T&&v(S);A=S,D||T||E?c(k)?A=k:u(k)?A=o(k):T?(_=!1,A=i(S,!0)):E?(_=!1,A=a(S,!0)):A=[]:p(S)||l(S)?(A=k,l(k)?A=m(k):f(k)&&!d(k)||(A=s(S))):_=!1}_&&(w.set(S,A),b(A,S,y,x,w),w["delete"](S)),r(t,n,A)}}t.exports=y},"4f7f":function(t,e,n){"use strict";var r=n("c26b"),i=n("b39a"),a="Set";t.exports=n("e0b8")(a,(function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}}),{add:function(t){return r.def(i(this,a),t=0===t?0:t,t)}},r)},"504c":function(t,e,n){var r=n("9e1e"),i=n("0d58"),a=n("6821"),o=n("52a7").f;t.exports=function(t){return function(e){var n,s=a(e),l=i(s),c=l.length,u=0,h=[];while(c>u)n=l[u++],r&&!o.call(s,n)||h.push(t?[n,s[n]]:s[n]);return h}}},"50ca":function(t,e,n){var r=n("8057"),i=n("7530"),a=n("242e"),o=n("badf"),s=n("2dcb"),l=n("6747"),c=n("0d24"),u=n("9520"),h=n("1a8c"),d=n("73ac");function f(t,e,n){var f=l(t),p=f||c(t)||d(t);if(e=o(e,4),null==n){var v=t&&t.constructor;n=p?f?new v:[]:h(t)&&u(v)?i(s(t)):{}}return(p?r:a)(t,(function(t,r,i){return e(n,t,r,i)})),n}t.exports=f},"50d8":function(t,e){function n(t,e){var n=-1,r=Array(t);while(++n1&&a.call(o[0],n,(function(){for(u=1;u1?arguments[1]:void 0,g=void 0!==v,m=0,y=u(d);if(g&&(v=r(v,p>2?arguments[2]:void 0,2)),void 0==y||f==Array&&s(y))for(e=l(d.length),n=new f(e);e>m;m++)c(n,m,g?v(d[m],m):d[m]);else for(h=y.call(d),n=new f;!(i=h.next()).done;m++)c(n,m,g?o(h,v,[i.value,m],!0):i.value);return n.length=m,n}})},"54eb":function(t,e,n){var r=n("8eeb"),i=n("32f4");function a(t,e){return r(t,i(t),e)}t.exports=a},"551c":function(t,e,n){"use strict";var r,i,a,o,s=n("2d00"),l=n("7726"),c=n("9b43"),u=n("23c6"),h=n("5ca1"),d=n("d3f4"),f=n("d8e8"),p=n("f605"),v=n("4a59"),g=n("ebd6"),m=n("1991").set,y=n("8079")(),b=n("a5b8"),x=n("9c80"),w=n("a25f"),k=n("bcaa"),S="Promise",C=l.TypeError,A=l.process,_=A&&A.versions,D=_&&_.v8||"",T=l[S],E="process"==u(A),O=function(){},P=i=b.f,I=!!function(){try{var t=T.resolve(1),e=(t.constructor={})[n("2b4c")("species")]=function(t){t(O,O)};return(E||"function"==typeof PromiseRejectionEvent)&&t.then(O)instanceof e&&0!==D.indexOf("6.6")&&-1===w.indexOf("Chrome/66")}catch(r){}}(),M=function(t){var e;return!(!d(t)||"function"!=typeof(e=t.then))&&e},V=function(t,e){if(!t._n){t._n=!0;var n=t._c;y((function(){var r=t._v,i=1==t._s,a=0,o=function(e){var n,a,o,s=i?e.ok:e.fail,l=e.resolve,c=e.reject,u=e.domain;try{s?(i||(2==t._h&&B(t),t._h=1),!0===s?n=r:(u&&u.enter(),n=s(r),u&&(u.exit(),o=!0)),n===e.promise?c(C("Promise-chain cycle")):(a=M(n))?a.call(n,l,c):l(n)):c(r)}catch(h){u&&!o&&u.exit(),c(h)}};while(n.length>a)o(n[a++]);t._c=[],t._n=!1,e&&!t._h&&L(t)}))}},L=function(t){m.call(l,(function(){var e,n,r,i=t._v,a=j(t);if(a&&(e=x((function(){E?A.emit("unhandledRejection",i,t):(n=l.onunhandledrejection)?n({promise:t,reason:i}):(r=l.console)&&r.error&&r.error("Unhandled promise rejection",i)})),t._h=E||j(t)?2:1),t._a=void 0,a&&e.e)throw e.v}))},j=function(t){return 1!==t._h&&0===(t._a||t._c).length},B=function(t){m.call(l,(function(){var e;E?A.emit("rejectionHandled",t):(e=l.onrejectionhandled)&&e({promise:t,reason:t._v})}))},R=function(t){var e=this;e._d||(e._d=!0,e=e._w||e,e._v=t,e._s=2,e._a||(e._a=e._c.slice()),V(e,!0))},F=function(t){var e,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===t)throw C("Promise can't be resolved itself");(e=M(t))?y((function(){var r={_w:n,_d:!1};try{e.call(t,c(F,r,1),c(R,r,1))}catch(i){R.call(r,i)}})):(n._v=t,n._s=1,V(n,!1))}catch(r){R.call({_w:n,_d:!1},r)}}};I||(T=function(t){p(this,T,S,"_h"),f(t),r.call(this);try{t(c(F,this,1),c(R,this,1))}catch(e){R.call(this,e)}},r=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},r.prototype=n("dcbc")(T.prototype,{then:function(t,e){var n=P(g(this,T));return n.ok="function"!=typeof t||t,n.fail="function"==typeof e&&e,n.domain=E?A.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&V(this,!1),n.promise},catch:function(t){return this.then(void 0,t)}}),a=function(){var t=new r;this.promise=t,this.resolve=c(F,t,1),this.reject=c(R,t,1)},b.f=P=function(t){return t===T||t===o?new a(t):i(t)}),h(h.G+h.W+h.F*!I,{Promise:T}),n("7f20")(T,S),n("7a56")(S),o=n("8378")[S],h(h.S+h.F*!I,S,{reject:function(t){var e=P(this),n=e.reject;return n(t),e.promise}}),h(h.S+h.F*(s||!I),S,{resolve:function(t){return k(s&&this===o?T:this,t)}}),h(h.S+h.F*!(I&&n("5cc5")((function(t){T.all(t)["catch"](O)}))),S,{all:function(t){var e=this,n=P(e),r=n.resolve,i=n.reject,a=x((function(){var n=[],a=0,o=1;v(t,!1,(function(t){var s=a++,l=!1;n.push(void 0),o++,e.resolve(t).then((function(t){l||(l=!0,n[s]=t,--o||r(n))}),i)})),--o||r(n)}));return a.e&&i(a.v),n.promise},race:function(t){var e=this,n=P(e),r=n.reject,i=x((function(){v(t,!1,(function(t){e.resolve(t).then(n.resolve,r)}))}));return i.e&&r(i.v),n.promise}})},5537:function(t,e,n){var r=n("8378"),i=n("7726"),a="__core-js_shared__",o=i[a]||(i[a]={});(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n("2d00")?"pure":"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})},5559:function(t,e,n){var r=n("dbdb")("keys"),i=n("62a0");t.exports=function(t){return r[t]||(r[t]=i(t))}},"55a3":function(t,e){function n(t){return this.__data__.has(t)}t.exports=n},"55dd":function(t,e,n){"use strict";var r=n("5ca1"),i=n("d8e8"),a=n("4bf8"),o=n("79e5"),s=[].sort,l=[1,2,3];r(r.P+r.F*(o((function(){l.sort(void 0)}))||!o((function(){l.sort(null)}))||!n("2f21")(s)),"Array",{sort:function(t){return void 0===t?s.call(a(this)):s.call(a(this),i(t))}})},"57a5":function(t,e,n){var r=n("91e9"),i=r(Object.keys,Object);t.exports=i},"57dc":function(t,e){function n(t,e){return t>e}t.exports=n},"584a":function(t,e){var n=t.exports={version:"2.6.12"};"number"==typeof __e&&(__e=n)},"585a":function(t,e,n){(function(e){var n="object"==typeof e&&e&&e.Object===Object&&e;t.exports=n}).call(this,n("c8ba"))},"58f7":function(t,e){function n(t,e,n,r,i){return i(t,(function(t,i,a){n=r?(r=!1,t):e(n,t,i,a)})),n}t.exports=n},"5a0c":function(t,e,n){!function(e,n){t.exports=n()}(0,(function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",a="minute",o="hour",s="day",l="week",c="month",u="quarter",h="year",d="date",f="Invalid Date",p=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,v=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,g={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},y={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()1)return t(o[0])}else{var s=e.name;x[s]=e,i=s}return!r&&i&&(b=i),i||!r&&b},C=function(t,e){if(k(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},A=y;A.l=S,A.i=k,A.w=function(t,e){return C(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function g(t){this.$L=S(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[w]=!0}var m=g.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(A.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(p);if(r){var i=r[2]-1||0,a=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,a)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,a)}}return new Date(e)}(t),this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return A},m.isValid=function(){return!(this.$d.toString()===f)},m.isSame=function(t,e){var n=C(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return C(t)u)if(s=l[u++],s!=s)return!0}else for(;c>u;u++)if((t||u in l)&&l[u]===n)return t||u||0;return!t&&-1}}},"5c69":function(t,e,n){var r=n("087d"),i=n("0621");function a(t,e,n,o,s){var l=-1,c=t.length;n||(n=i),s||(s=[]);while(++l0&&n(u)?e>1?a(u,e-1,n,o,s):r(s,u):o||(s[s.length]=u)}return s}t.exports=a},"5c95":function(t,e,n){var r=n("35e8");t.exports=function(t,e,n){for(var i in e)n&&t[i]?t[i]=e[i]:r(t,i,e[i]);return t}},"5ca0":function(t,e,n){var r=n("badf"),i=n("30c9"),a=n("ec69");function o(t){return function(e,n,o){var s=Object(e);if(!i(e)){var l=r(n,3);e=a(e),n=function(t){return l(s[t],t,s)}}var c=t(e,n,o);return c>-1?s[l?e[c]:c]:void 0}}t.exports=o},"5ca1":function(t,e,n){var r=n("7726"),i=n("8378"),a=n("32e9"),o=n("2aba"),s=n("9b43"),l="prototype",c=function(t,e,n){var u,h,d,f,p=t&c.F,v=t&c.G,g=t&c.S,m=t&c.P,y=t&c.B,b=v?r:g?r[e]||(r[e]={}):(r[e]||{})[l],x=v?i:i[e]||(i[e]={}),w=x[l]||(x[l]={});for(u in v&&(n=e),n)h=!p&&b&&void 0!==b[u],d=(h?b:n)[u],f=y&&h?s(d,r):m&&"function"==typeof d?s(Function.call,d):d,b&&o(b,u,d,t&c.U),x[u]!=d&&a(x,u,f),m&&w[u]!=d&&(w[u]=d)};r.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},"5cc5":function(t,e,n){var r=n("2b4c")("iterator"),i=!1;try{var a=[7][r]();a["return"]=function(){i=!0},Array.from(a,(function(){throw 2}))}catch(o){}t.exports=function(t,e){if(!e&&!i)return!1;var n=!1;try{var a=[7],s=a[r]();s.next=function(){return{done:n=!0}},a[r]=function(){return s},t(a)}catch(o){}return n}},"5d89":function(t,e,n){var r=n("f8af");function i(t,e){var n=e?r(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)}t.exports=i},"5dbc":function(t,e,n){var r=n("d3f4"),i=n("8b97").set;t.exports=function(t,e,n){var a,o=e.constructor;return o!==n&&"function"==typeof o&&(a=o.prototype)!==n.prototype&&r(a)&&i&&i(t,a),t}},"5df3":function(t,e,n){"use strict";var r=n("02f4")(!0);n("01f9")(String,"String",(function(t){this._t=String(t),this._i=0}),(function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})}))},"5e2e":function(t,e,n){var r=n("28c9"),i=n("69d5"),a=n("b4c0"),o=n("fba5"),s=n("67ca");function l(t){var e=-1,n=null==t?0:t.length;this.clear();while(++e0){if(n=l.removeMin(),r.has(s,n))o.setEdge(n,s[n]);else{if(u)throw new Error("Input graph is not connected: "+t);u=!0}t.nodeEdges(n).forEach(c)}return o}t.exports=o},"626a":function(t,e,n){var r=n("2d95");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},"62a0":function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},"62e4":function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},"63b6":function(t,e,n){var r=n("e53d"),i=n("584a"),a=n("d864"),o=n("35e8"),s=n("07e3"),l="prototype",c=function(t,e,n){var u,h,d,f=t&c.F,p=t&c.G,v=t&c.S,g=t&c.P,m=t&c.B,y=t&c.W,b=p?i:i[e]||(i[e]={}),x=b[l],w=p?r:v?r[e]:(r[e]||{})[l];for(u in p&&(n=e),n)h=!f&&w&&void 0!==w[u],h&&s(b,u)||(d=h?w[u]:n[u],b[u]=p&&"function"!=typeof w[u]?n[u]:m&&h?a(d,r):y&&w[u]==d?function(t){var e=function(e,n,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,r)}return t.apply(this,arguments)};return e[l]=t[l],e}(d):g&&"function"==typeof d?a(Function.call,d):d,g&&((b.virtual||(b.virtual={}))[u]=d,t&c.R&&x&&!x[u]&&o(x,u,d)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},6428:function(t,e,n){var r=n("b4b0"),i=1/0,a=17976931348623157e292;function o(t){if(!t)return 0===t?t:0;if(t=r(t),t===i||t===-i){var e=t<0?-1:1;return e*a}return t===t?t:0}t.exports=o},"642a":function(t,e,n){var r=n("966f"),i=n("3bb4"),a=n("20ec");function o(t){var e=i(t);return 1==e.length&&e[0][2]?a(e[0][0],e[0][1]):function(n){return n===t||r(n,t,e)}}t.exports=o},"656b":function(t,e,n){var r=n("e2e4"),i=n("f4d6");function a(t,e){e=r(e,t);var n=0,a=e.length;while(null!=t&&n1?arguments[1]:void 0)}}),n("9c6c")("includes")},"67ab":function(t,e,n){var r=n("ca5a")("meta"),i=n("d3f4"),a=n("69a8"),o=n("86cc").f,s=0,l=Object.isExtensible||function(){return!0},c=!n("79e5")((function(){return l(Object.preventExtensions({}))})),u=function(t){o(t,r,{value:{i:"O"+ ++s,w:{}}})},h=function(t,e){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!a(t,r)){if(!l(t))return"F";if(!e)return"E";u(t)}return t[r].i},d=function(t,e){if(!a(t,r)){if(!l(t))return!0;if(!e)return!1;u(t)}return t[r].w},f=function(t){return c&&p.NEED&&l(t)&&!a(t,r)&&u(t),t},p=t.exports={KEY:r,NEED:!1,fastKey:h,getWeak:d,onFreeze:f}},"67ca":function(t,e,n){var r=n("cb5a");function i(t,e){var n=this.__data__,i=r(n,t);return i<0?(++this.size,n.push([t,e])):n[i][1]=e,this}t.exports=i},6821:function(t,e,n){var r=n("626a"),i=n("be13");t.exports=function(t){return r(i(t))}},6882:function(t,e,n){(function(e,r){t.exports=r(n("44c8"))})(0,(function(t){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.i=function(t){return t},n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(t,e,n){var r=n(3).Thread,i=n(2),a={animate:!0,ready:void 0,stop:void 0,fit:!0,minDist:20,padding:20,expandingFactor:-1,prelayout:{name:"cose"},maxExpandIterations:4,boundingBox:void 0,randomize:!1};function o(t){var e=this.options={};for(var n in a)e[n]=a[n];for(var n in t)e[n]=t[n]}o.prototype.run=function(){var t=this,e=this.options,n=e.cy,a=e.boundingBox||{x1:0,y1:0,w:n.width(),h:n.height()};void 0===a.x2&&(a.x2=a.x1+a.w),void 0===a.w&&(a.w=a.x2-a.x1),void 0===a.y2&&(a.y2=a.y1+a.h),void 0===a.h&&(a.h=a.y2-a.y1);var o=n.nodes(),s=n.edges(),l=n.width(),c=n.height(),u=a,h=e.padding,d=Math.max(1,.8*Math.log(o.length));o.length<100&&(d/=2),t.trigger({type:"layoutstart",layout:t});var f={x1:0,y1:0,x2:l*d,y2:c*d};u&&(f.x1=u.x1,f.y1=u.y1,f.x2=u.x2,f.y2=u.y2),f.x1+=h,f.y1+=h,f.x2-=h,f.y2-=h;var p=f.x2-f.x1,v=f.y2-f.y1,g=Date.now();if(o.size()<=1){o.positions({x:Math.round((f.x1+f.x2)/2),y:Math.round((f.y1+f.y2)/2)}),e.fit&&n.fit(e.padding);var m=Date.now();return console.info("Layout on "+o.size()+" nodes took "+(m-g)+" ms"),t.one("layoutready",e.ready),t.trigger("layoutready"),t.one("layoutstop",e.stop),void t.trigger("layoutstop")}for(var y={width:p,height:v,minDist:e.minDist,expFact:e.expandingFactor,expIt:0,maxExpIt:e.maxExpandIterations,vertices:[],edges:[],startTime:g},b=o.length-1;b>=0;b--){var x=o[b].id(),w=o[b].position();e.randomize&&(w={x:Math.round(f.x1+(f.x2-f.x1)*Math.random()),y:Math.round(f.y1+(f.y2-f.y1)*Math.random())}),y["vertices"].push({id:x,x:w.x,y:w.y})}for(b=s.length-1;b>=0;b--){var k=s[b].source().id(),S=s[b].target().id();y["edges"].push({src:k,tgt:S})}var C=t.thread;function A(t){for(var r=t["vertices"],i=[],a=0;a=E||P>=4)&&(I>=l?O=!0:(r+=r*s,a+=a*s,b={xl:0,xr:r,yt:0,yb:a},++I,P=0)),E=V,c(),u()}return c(),t})).then((function(n){var r=n["vertices"];A(n);var i=n["startTime"],a=new Date;console.info("Layout on "+r.length+" nodes took "+(a-i)+" ms"),t.one("layoutstop",e.stop),e.animate||t.trigger("layoutready"),t.trigger("layoutstop"),C.stop()}))}return this},o.prototype.stop=function(){this.thread&&this.thread.stop(),this.trigger("layoutstop")},o.prototype.destroy=function(){this.thread&&this.thread.stop()},t.exports=o},function(t,e,n){"use strict";var r=n(0),i=function(t){t("layout","spread",r)};"undefined"!==typeof cytoscape&&i(cytoscape),t.exports=i},function(t,e){ +/*! +Copyright (C) 2010-2013 Raymond Hill: https://github.com/gorhill/Javascript-Voronoi +MIT License: See https://github.com/gorhill/Javascript-Voronoi/LICENSE.md +*/ +function n(){this.vertices=null,this.edges=null,this.cells=null,this.toRecycle=null,this.beachsectionJunkyard=[],this.circleEventJunkyard=[],this.vertexJunkyard=[],this.edgeJunkyard=[],this.cellJunkyard=[]}n.prototype.reset=function(){if(this.beachline||(this.beachline=new this.RBTree),this.beachline.root){var t=this.beachline.getFirst(this.beachline.root);while(t)this.beachsectionJunkyard.push(t),t=t.rbNext}this.beachline.root=null,this.circleEvents||(this.circleEvents=new this.RBTree),this.circleEvents.root=this.firstCircleEvent=null,this.vertices=[],this.edges=[],this.cells=[]},n.prototype.sqrt=function(t){return Math.sqrt(t)},n.prototype.abs=function(t){return Math.abs(t)},n.prototype.ε=n.ε=1e-9,n.prototype.invε=n.invε=1/n.ε,n.prototype.equalWithEpsilon=function(t,e){return this.abs(t-e)<1e-9},n.prototype.greaterThanWithEpsilon=function(t,e){return t-e>1e-9},n.prototype.greaterThanOrEqualWithEpsilon=function(t,e){return e-t<1e-9},n.prototype.lessThanWithEpsilon=function(t,e){return e-t>1e-9},n.prototype.lessThanOrEqualWithEpsilon=function(t,e){return t-e<1e-9},n.prototype.RBTree=function(){this.root=null},n.prototype.RBTree.prototype.rbInsertSuccessor=function(t,e){var n,r,i;if(t){if(e.rbPrevious=t,e.rbNext=t.rbNext,t.rbNext&&(t.rbNext.rbPrevious=e),t.rbNext=e,t.rbRight){t=t.rbRight;while(t.rbLeft)t=t.rbLeft;t.rbLeft=e}else t.rbRight=e;n=t}else this.root?(t=this.getFirst(this.root),e.rbPrevious=null,e.rbNext=t,t.rbPrevious=e,t.rbLeft=e,n=t):(e.rbPrevious=e.rbNext=null,this.root=e,n=null);e.rbLeft=e.rbRight=null,e.rbParent=n,e.rbRed=!0,t=e;while(n&&n.rbRed)r=n.rbParent,n===r.rbLeft?(i=r.rbRight,i&&i.rbRed?(n.rbRed=i.rbRed=!1,r.rbRed=!0,t=r):(t===n.rbRight&&(this.rbRotateLeft(n),t=n,n=t.rbParent),n.rbRed=!1,r.rbRed=!0,this.rbRotateRight(r))):(i=r.rbLeft,i&&i.rbRed?(n.rbRed=i.rbRed=!1,r.rbRed=!0,t=r):(t===n.rbLeft&&(this.rbRotateRight(n),t=n,n=t.rbParent),n.rbRed=!1,r.rbRed=!0,this.rbRotateLeft(r))),n=t.rbParent;this.root.rbRed=!1},n.prototype.RBTree.prototype.rbRemoveNode=function(t){t.rbNext&&(t.rbNext.rbPrevious=t.rbPrevious),t.rbPrevious&&(t.rbPrevious.rbNext=t.rbNext),t.rbNext=t.rbPrevious=null;var e,n,r=t.rbParent,i=t.rbLeft,a=t.rbRight;if(e=i?a?this.getFirst(a):i:a,r?r.rbLeft===t?r.rbLeft=e:r.rbRight=e:this.root=e,i&&a?(n=e.rbRed,e.rbRed=t.rbRed,e.rbLeft=i,i.rbParent=e,e!==a?(r=e.rbParent,e.rbParent=t.rbParent,t=e.rbRight,r.rbLeft=t,e.rbRight=a,a.rbParent=e):(e.rbParent=r,r=e,t=e.rbRight)):(n=t.rbRed,t=e),t&&(t.rbParent=r),!n)if(t&&t.rbRed)t.rbRed=!1;else{var o;do{if(t===this.root)break;if(t===r.rbLeft){if(o=r.rbRight,o.rbRed&&(o.rbRed=!1,r.rbRed=!0,this.rbRotateLeft(r),o=r.rbRight),o.rbLeft&&o.rbLeft.rbRed||o.rbRight&&o.rbRight.rbRed){o.rbRight&&o.rbRight.rbRed||(o.rbLeft.rbRed=!1,o.rbRed=!0,this.rbRotateRight(o),o=r.rbRight),o.rbRed=r.rbRed,r.rbRed=o.rbRight.rbRed=!1,this.rbRotateLeft(r),t=this.root;break}}else if(o=r.rbLeft,o.rbRed&&(o.rbRed=!1,r.rbRed=!0,this.rbRotateRight(r),o=r.rbLeft),o.rbLeft&&o.rbLeft.rbRed||o.rbRight&&o.rbRight.rbRed){o.rbLeft&&o.rbLeft.rbRed||(o.rbRight.rbRed=!1,o.rbRed=!0,this.rbRotateLeft(o),o=r.rbLeft),o.rbRed=r.rbRed,r.rbRed=o.rbLeft.rbRed=!1,this.rbRotateRight(r),t=this.root;break}o.rbRed=!0,t=r,r=r.rbParent}while(!t.rbRed);t&&(t.rbRed=!1)}},n.prototype.RBTree.prototype.rbRotateLeft=function(t){var e=t,n=t.rbRight,r=e.rbParent;r?r.rbLeft===e?r.rbLeft=n:r.rbRight=n:this.root=n,n.rbParent=r,e.rbParent=n,e.rbRight=n.rbLeft,e.rbRight&&(e.rbRight.rbParent=e),n.rbLeft=e},n.prototype.RBTree.prototype.rbRotateRight=function(t){var e=t,n=t.rbLeft,r=e.rbParent;r?r.rbLeft===e?r.rbLeft=n:r.rbRight=n:this.root=n,n.rbParent=r,e.rbParent=n,e.rbLeft=n.rbRight,e.rbLeft&&(e.rbLeft.rbParent=e),n.rbRight=e},n.prototype.RBTree.prototype.getFirst=function(t){while(t.rbLeft)t=t.rbLeft;return t},n.prototype.RBTree.prototype.getLast=function(t){while(t.rbRight)t=t.rbRight;return t},n.prototype.Diagram=function(t){this.site=t},n.prototype.Cell=function(t){this.site=t,this.halfedges=[],this.closeMe=!1},n.prototype.Cell.prototype.init=function(t){return this.site=t,this.halfedges=[],this.closeMe=!1,this},n.prototype.createCell=function(t){var e=this.cellJunkyard.pop();return e?e.init(t):new this.Cell(t)},n.prototype.Cell.prototype.prepareHalfedges=function(){var t,e=this.halfedges,n=e.length;while(n--)t=e[n].edge,t.vb&&t.va||e.splice(n,1);return e.sort((function(t,e){return e.angle-t.angle})),e.length},n.prototype.Cell.prototype.getNeighborIds=function(){var t,e=[],n=this.halfedges.length;while(n--)t=this.halfedges[n].edge,null!==t.lSite&&t.lSite.voronoiId!=this.site.voronoiId?e.push(t.lSite.voronoiId):null!==t.rSite&&t.rSite.voronoiId!=this.site.voronoiId&&e.push(t.rSite.voronoiId);return e},n.prototype.Cell.prototype.getBbox=function(){var t,e,n,r=this.halfedges,i=r.length,a=1/0,o=1/0,s=-1/0,l=-1/0;while(i--)t=r[i].getStartpoint(),e=t.x,n=t.y,es&&(s=e),n>l&&(l=n);return{x:a,y:o,width:s-a,height:l-o}},n.prototype.Cell.prototype.pointIntersection=function(t,e){var n,r,i,a,o=this.halfedges,s=o.length;while(s--){if(n=o[s],r=n.getStartpoint(),i=n.getEndpoint(),a=(e-r.y)*(i.x-r.x)-(t-r.x)*(i.y-r.y),!a)return 0;if(a>0)return-1}return 1},n.prototype.Vertex=function(t,e){this.x=t,this.y=e},n.prototype.Edge=function(t,e){this.lSite=t,this.rSite=e,this.va=this.vb=null},n.prototype.Halfedge=function(t,e,n){if(this.site=e,this.edge=t,n)this.angle=Math.atan2(n.y-e.y,n.x-e.x);else{var r=t.va,i=t.vb;this.angle=t.lSite===e?Math.atan2(i.x-r.x,r.y-i.y):Math.atan2(r.x-i.x,i.y-r.y)}},n.prototype.createHalfedge=function(t,e,n){return new this.Halfedge(t,e,n)},n.prototype.Halfedge.prototype.getStartpoint=function(){return this.edge.lSite===this.site?this.edge.va:this.edge.vb},n.prototype.Halfedge.prototype.getEndpoint=function(){return this.edge.lSite===this.site?this.edge.vb:this.edge.va},n.prototype.createVertex=function(t,e){var n=this.vertexJunkyard.pop();return n?(n.x=t,n.y=e):n=new this.Vertex(t,e),this.vertices.push(n),n},n.prototype.createEdge=function(t,e,n,r){var i=this.edgeJunkyard.pop();return i?(i.lSite=t,i.rSite=e,i.va=i.vb=null):i=new this.Edge(t,e),this.edges.push(i),n&&this.setEdgeStartpoint(i,t,e,n),r&&this.setEdgeEndpoint(i,t,e,r),this.cells[t.voronoiId].halfedges.push(this.createHalfedge(i,t,e)),this.cells[e.voronoiId].halfedges.push(this.createHalfedge(i,e,t)),i},n.prototype.createBorderEdge=function(t,e,n){var r=this.edgeJunkyard.pop();return r?(r.lSite=t,r.rSite=null):r=new this.Edge(t,null),r.va=e,r.vb=n,this.edges.push(r),r},n.prototype.setEdgeStartpoint=function(t,e,n,r){t.va||t.vb?t.lSite===n?t.vb=r:t.va=r:(t.va=r,t.lSite=e,t.rSite=n)},n.prototype.setEdgeEndpoint=function(t,e,n,r){this.setEdgeStartpoint(t,n,e,r)},n.prototype.Beachsection=function(){},n.prototype.createBeachsection=function(t){var e=this.beachsectionJunkyard.pop();return e||(e=new this.Beachsection),e.site=t,e},n.prototype.leftBreakPoint=function(t,e){var n=t.site,r=n.x,i=n.y,a=i-e;if(!a)return r;var o=t.rbPrevious;if(!o)return-1/0;n=o.site;var s=n.x,l=n.y,c=l-e;if(!c)return s;var u=s-r,h=1/a-1/c,d=u/c;return h?(-d+this.sqrt(d*d-2*h*(u*u/(-2*c)-l+c/2+i-a/2)))/h+r:(r+s)/2},n.prototype.rightBreakPoint=function(t,e){var n=t.rbNext;if(n)return this.leftBreakPoint(n,e);var r=t.site;return r.y===e?r.x:1/0},n.prototype.detachBeachsection=function(t){this.detachCircleEvent(t),this.beachline.rbRemoveNode(t),this.beachsectionJunkyard.push(t)},n.prototype.removeBeachsection=function(t){var e=t.circleEvent,n=e.x,r=e.ycenter,i=this.createVertex(n,r),a=t.rbPrevious,o=t.rbNext,s=[t],l=Math.abs;this.detachBeachsection(t);var c=a;while(c.circleEvent&&l(n-c.circleEvent.x)<1e-9&&l(r-c.circleEvent.ycenter)<1e-9)a=c.rbPrevious,s.unshift(c),this.detachBeachsection(c),c=a;s.unshift(c),this.detachCircleEvent(c);var u=o;while(u.circleEvent&&l(n-u.circleEvent.x)<1e-9&&l(r-u.circleEvent.ycenter)<1e-9)o=u.rbNext,s.push(u),this.detachBeachsection(u),u=o;s.push(u),this.detachCircleEvent(u);var h,d=s.length;for(h=1;h1e-9)s=s.rbLeft;else{if(i=a-this.rightBreakPoint(s,o),!(i>1e-9)){r>-1e-9?(e=s.rbPrevious,n=s):i>-1e-9?(e=s,n=s.rbNext):e=n=s;break}if(!s.rbRight){e=s;break}s=s.rbRight}var l=this.createBeachsection(t);if(this.beachline.rbInsertSuccessor(e,l),e||n){if(e===n)return this.detachCircleEvent(e),n=this.createBeachsection(e.site),this.beachline.rbInsertSuccessor(l,n),l.edge=n.edge=this.createEdge(e.site,l.site),this.attachCircleEvent(e),void this.attachCircleEvent(n);if(!e||n){if(e!==n){this.detachCircleEvent(e),this.detachCircleEvent(n);var c=e.site,u=c.x,h=c.y,d=t.x-u,f=t.y-h,p=n.site,v=p.x-u,g=p.y-h,m=2*(d*g-f*v),y=d*d+f*f,b=v*v+g*g,x=this.createVertex((g*y-f*b)/m+u,(d*b-v*y)/m+h);return this.setEdgeStartpoint(n.edge,c,p,x),l.edge=this.createEdge(c,t,void 0,x),n.edge=this.createEdge(t,p,void 0,x),this.attachCircleEvent(e),void this.attachCircleEvent(n)}}else l.edge=this.createEdge(e.site,l.site)}},n.prototype.CircleEvent=function(){this.arc=null,this.rbLeft=null,this.rbNext=null,this.rbParent=null,this.rbPrevious=null,this.rbRed=!1,this.rbRight=null,this.site=null,this.x=this.y=this.ycenter=0},n.prototype.attachCircleEvent=function(t){var e=t.rbPrevious,n=t.rbNext;if(e&&n){var r=e.site,i=t.site,a=n.site;if(r!==a){var o=i.x,s=i.y,l=r.x-o,c=r.y-s,u=a.x-o,h=a.y-s,d=2*(l*h-c*u);if(!(d>=-2e-12)){var f=l*l+c*c,p=u*u+h*h,v=(h*f-c*p)/d,g=(l*p-u*f)/d,m=g+s,y=this.circleEventJunkyard.pop();y||(y=new this.CircleEvent),y.arc=t,y.site=i,y.x=v+o,y.y=m+this.sqrt(v*v+g*g),y.ycenter=m,t.circleEvent=y;var b=null,x=this.circleEvents.root;while(x)if(y.y=s)return!1;if(d>p){if(!a||a.y=c)return!1;n=this.createVertex(g,c)}else{if(!a||a.y>c)a=this.createVertex(g,c);else if(a.y1)if(d>p){if(!a||a.y=c)return!1;n=this.createVertex((c-i)/r,c)}else{if(!a||a.y>c)a=this.createVertex((c-i)/r,c);else if(a.y=s)return!1;n=this.createVertex(s,r*s+i)}else{if(!a||a.x>s)a=this.createVertex(s,r*s+i);else if(a.x0){if(h>s)return!1;h>o&&(o=h)}if(u=e.xr-n,0===l&&u<0)return!1;if(h=u/l,l<0){if(h>s)return!1;h>o&&(o=h)}else if(l>0){if(h0){if(h>s)return!1;h>o&&(o=h)}if(u=e.yb-r,0===c&&u<0)return!1;if(h=u/c,c<0){if(h>s)return!1;h>o&&(o=h)}else if(c>0){if(h0&&(t.va=this.createVertex(n+o*l,r+o*c)),s<1&&(t.vb=this.createVertex(n+s*l,r+s*c)),(o>0||s<1)&&(this.cells[t.lSite.voronoiId].closeMe=!0,this.cells[t.rSite.voronoiId].closeMe=!0),!0},n.prototype.clipEdges=function(t){var e,n=this.edges,r=n.length,i=Math.abs;while(r--)e=n[r],(!this.connectEdge(e,t)||!this.clipEdge(e,t)||i(e.va.x-e.vb.x)<1e-9&&i(e.va.y-e.vb.y)<1e-9)&&(e.va=e.vb=null,n.splice(r,1))},n.prototype.closeCells=function(t){var e,n,r,i,a,o,s,l,c,u=t.xl,h=t.xr,d=t.yt,f=t.yb,p=this.cells,v=p.length,g=Math.abs;while(v--)if(e=p[v],e.prepareHalfedges()&&e.closeMe){r=e.halfedges,i=r.length,n=0;while(n=1e-9||g(o.y-l.y)>=1e-9)switch(!0){case this.equalWithEpsilon(o.x,u)&&this.lessThanWithEpsilon(o.y,f):if(c=this.equalWithEpsilon(l.x,u),s=this.createVertex(u,c?l.y:f),a=this.createBorderEdge(e.site,o,s),n++,r.splice(n,0,this.createHalfedge(a,e.site,null)),i++,c)break;o=s;case this.equalWithEpsilon(o.y,f)&&this.lessThanWithEpsilon(o.x,h):if(c=this.equalWithEpsilon(l.y,f),s=this.createVertex(c?l.x:h,f),a=this.createBorderEdge(e.site,o,s),n++,r.splice(n,0,this.createHalfedge(a,e.site,null)),i++,c)break;o=s;case this.equalWithEpsilon(o.x,h)&&this.greaterThanWithEpsilon(o.y,d):if(c=this.equalWithEpsilon(l.x,h),s=this.createVertex(h,c?l.y:d),a=this.createBorderEdge(e.site,o,s),n++,r.splice(n,0,this.createHalfedge(a,e.site,null)),i++,c)break;o=s;case this.equalWithEpsilon(o.y,d)&&this.greaterThanWithEpsilon(o.x,u):if(c=this.equalWithEpsilon(l.y,d),s=this.createVertex(c?l.x:u,d),a=this.createBorderEdge(e.site,o,s),n++,r.splice(n,0,this.createHalfedge(a,e.site,null)),i++,c)break;if(o=s,c=this.equalWithEpsilon(l.x,u),s=this.createVertex(u,c?l.y:f),a=this.createBorderEdge(e.site,o,s),n++,r.splice(n,0,this.createHalfedge(a,e.site,null)),i++,c)break;if(o=s,c=this.equalWithEpsilon(l.y,f),s=this.createVertex(c?l.x:h,f),a=this.createBorderEdge(e.site,o,s),n++,r.splice(n,0,this.createHalfedge(a,e.site,null)),i++,c)break;if(o=s,c=this.equalWithEpsilon(l.x,h),s=this.createVertex(h,c?l.y:d),a=this.createBorderEdge(e.site,o,s),n++,r.splice(n,0,this.createHalfedge(a,e.site,null)),i++,c)break;default:throw"Voronoi.closeCells() > this makes no sense!"}n++}e.closeMe=!1}},n.prototype.quantizeSites=function(t){var e,n=this.ε,r=t.length;while(r--)e=t[r],e.x=Math.floor(e.x/n)*n,e.y=Math.floor(e.y/n)*n},n.prototype.recycle=function(t){if(t){if(!(t instanceof this.Diagram))throw"Voronoi.recycleDiagram() > Need a Diagram object.";this.toRecycle=t}},n.prototype.compute=function(t,e){var n=new Date;this.reset(),this.toRecycle&&(this.vertexJunkyard=this.vertexJunkyard.concat(this.toRecycle.vertices),this.edgeJunkyard=this.edgeJunkyard.concat(this.toRecycle.edges),this.cellJunkyard=this.cellJunkyard.concat(this.toRecycle.cells),this.toRecycle=null);var r=t.slice(0);r.sort((function(t,e){var n=e.y-t.y;return n||e.x-t.x}));for(var i,a,o,s=r.pop(),l=0,c=this.cells;;)if(o=this.firstCircleEvent,s&&(!o||s.y=c?t?"":void 0:(a=s.charCodeAt(l),a<55296||a>56319||l+1===c||(o=s.charCodeAt(l+1))<56320||o>57343?t?s.charAt(l):a:t?s.slice(l,l+2):o-56320+(a-55296<<10)+65536)}}},"72af":function(t,e,n){var r=n("99cd"),i=r();t.exports=i},"72f0":function(t,e){function n(t){return function(){return t}}t.exports=n},7333:function(t,e,n){"use strict";var r=n("9e1e"),i=n("0d58"),a=n("2621"),o=n("52a7"),s=n("4bf8"),l=n("626a"),c=Object.assign;t.exports=!c||n("79e5")((function(){var t={},e={},n=Symbol(),r="abcdefghijklmnopqrst";return t[n]=7,r.split("").forEach((function(t){e[t]=t})),7!=c({},t)[n]||Object.keys(c({},e)).join("")!=r}))?function(t,e){var n=s(t),c=arguments.length,u=1,h=a.f,d=o.f;while(c>u){var f,p=l(arguments[u++]),v=h?i(p).concat(h(p)):i(p),g=v.length,m=0;while(g>m)f=v[m++],r&&!d.call(p,f)||(n[f]=p[f])}return n}:c},"73ac":function(t,e,n){var r=n("743f"),i=n("b047"),a=n("99d3"),o=a&&a.isTypedArray,s=o?i(o):r;t.exports=s},"743f":function(t,e,n){var r=n("3729"),i=n("b218"),a=n("1310"),o="[object Arguments]",s="[object Array]",l="[object Boolean]",c="[object Date]",u="[object Error]",h="[object Function]",d="[object Map]",f="[object Number]",p="[object Object]",v="[object RegExp]",g="[object Set]",m="[object String]",y="[object WeakMap]",b="[object ArrayBuffer]",x="[object DataView]",w="[object Float32Array]",k="[object Float64Array]",S="[object Int8Array]",C="[object Int16Array]",A="[object Int32Array]",_="[object Uint8Array]",D="[object Uint8ClampedArray]",T="[object Uint16Array]",E="[object Uint32Array]",O={};function P(t){return a(t)&&i(t.length)&&!!O[r(t)]}O[w]=O[k]=O[S]=O[C]=O[A]=O[_]=O[D]=O[T]=O[E]=!0,O[o]=O[s]=O[b]=O[l]=O[x]=O[c]=O[u]=O[h]=O[d]=O[f]=O[p]=O[v]=O[g]=O[m]=O[y]=!1,t.exports=P},"74e8":function(t,e,n){"use strict";var r=n("6f9c"),i=n("1845"),a=n("e849").slack,o=n("e849").longestPath,s=n("17d5").alg.preorder,l=n("17d5").alg.postorder,c=n("b50e").simplify;function u(t){t=c(t),o(t);var e,n,r=i(t);p(r),h(r,t);while(e=g(r))n=m(r,t,e),y(r,t,e,n)}function h(t,e){var n=l(t,t.nodes());n=n.slice(0,n.length-1),r.forEach(n,(function(n){d(t,e,n)}))}function d(t,e,n){var r=t.node(n),i=r.parent;t.edge(n,i).cutvalue=f(t,e,n)}function f(t,e,n){var i=t.node(n),a=i.parent,o=!0,s=e.edge(n,a),l=0;return s||(o=!1,s=e.edge(a,n)),l=s.weight,r.forEach(e.nodeEdges(n),(function(r){var i=r.v===n,s=i?r.w:r.v;if(s!==a){var c=i===o,u=e.edge(r).weight;if(l+=c?u:-u,x(t,n,s)){var h=t.edge(n,s).cutvalue;l+=c?-h:h}}})),l}function p(t,e){arguments.length<2&&(e=t.nodes()[0]),v(t,{},1,e)}function v(t,e,n,i,a){var o=n,s=t.node(i);return e[i]=!0,r.forEach(t.neighbors(i),(function(a){r.has(e,a)||(n=v(t,e,n,a,i))})),s.low=o,s.lim=n++,a?s.parent=a:delete s.parent,n}function g(t){return r.find(t.edges(),(function(e){return t.edge(e).cutvalue<0}))}function m(t,e,n){var i=n.v,o=n.w;e.hasEdge(i,o)||(i=n.w,o=n.v);var s=t.node(i),l=t.node(o),c=s,u=!1;s.lim>l.lim&&(c=l,u=!0);var h=r.filter(e.edges(),(function(e){return u===w(t,t.node(e.v),c)&&u!==w(t,t.node(e.w),c)}));return r.minBy(h,(function(t){return a(e,t)}))}function y(t,e,n,r){var i=n.v,a=n.w;t.removeEdge(i,a),t.setEdge(r.v,r.w,{}),p(t),h(t,e),b(t,e)}function b(t,e){var n=r.find(t.nodes(),(function(t){return!e.node(t).parent})),i=s(t,n);i=i.slice(1),r.forEach(i,(function(n){var r=t.node(n).parent,i=e.edge(n,r),a=!1;i||(i=e.edge(r,n),a=!0),e.node(n).rank=e.node(r).rank+(a?i.minlen:-i.minlen)}))}function x(t,e,n){return t.hasEdge(e,n)}function w(t,e,n){return n.low<=e.lim&&e.lim<=n.lim}t.exports=u,u.initLowLimValues=p,u.initCutValues=h,u.calcCutValue=f,u.leaveEdge=g,u.enterEdge=m,u.exchangeEdges=y},"750a":function(t,e,n){var r=n("c869"),i=n("bcdf"),a=n("ac41"),o=1/0,s=r&&1/a(new r([,-0]))[1]==o?function(t){return new r(t)}:i;t.exports=s},7514:function(t,e,n){"use strict";var r=n("5ca1"),i=n("0a49")(5),a="find",o=!0;a in[]&&Array(1)[a]((function(){o=!1})),r(r.P+r.F*o,"Array",{find:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),n("9c6c")(a)},7530:function(t,e,n){var r=n("1a8c"),i=Object.create,a=function(){function t(){}return function(e){if(!r(e))return{};if(i)return i(e);t.prototype=e;var n=new t;return t.prototype=void 0,n}}();t.exports=a},"75fc":function(t,e,n){"use strict";n.d(e,"a",(function(){return g}));var r=n("f410"),i=n.n(r),a=n("db2a");function o(t){if(i()(t))return Object(a["a"])(t)}var s=n("f921"),l=n.n(s),c=n("d8d6"),u=n.n(c),h=n("d2d5"),d=n.n(h);function f(t){if("undefined"!=typeof l.a&&null!=t[u.a]||null!=t["@@iterator"])return d()(t)}var p=n("e630");function v(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function g(t){return o(t)||f(t)||Object(p["a"])(t)||v()}},7618:function(t,e,n){"use strict";n.d(e,"a",(function(){return s}));var r=n("f921"),i=n.n(r),a=n("d8d6"),o=n.n(a);function s(t){return s="function"==typeof i.a&&"symbol"==typeof o.a?function(t){return typeof t}:function(t){return t&&"function"==typeof i.a&&t.constructor===i.a&&t!==i.a.prototype?"symbol":typeof t},s(t)}},"765d":function(t,e,n){n("6718")("observable")},"768b":function(t,e,n){"use strict";n.d(e,"a",(function(){return f}));var r=n("f410"),i=n.n(r);function a(t){if(i()(t))return t}var o=n("f921"),s=n.n(o),l=n("d8d6"),c=n.n(l);function u(t,e){var n=null==t?null:"undefined"!=typeof s.a&&t[c.a]||t["@@iterator"];if(null!=n){var r,i,a,o,l=[],u=!0,h=!1;try{if(a=(n=n.call(t)).next,0===e){if(Object(n)!==n)return;u=!1}else for(;!(u=(r=a.call(n)).done)&&(l.push(r.value),l.length!==e);u=!0);}catch(t){h=!0,i=t}finally{try{if(!u&&null!=n["return"]&&(o=n["return"](),Object(o)!==o))return}finally{if(h)throw i}}return l}}var h=n("e630");function d(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function f(t,e){return a(t)||u(t,e)||Object(h["a"])(t,e)||d()}},"76dd":function(t,e,n){var r=n("ce86");function i(t){return null==t?"":r(t)}t.exports=i},"76e9":function(t,e,n){var r=n("ffd6");function i(t,e,n){var i=-1,a=t.length;while(++i{o[t]={value:t}}),Object.defineProperties(i,o),Object.defineProperty(a,"isAxiosError",{value:!0}),i.from=(t,e,n,o,s,l)=>{const c=Object.create(a);return r["a"].toFlatObject(t,c,(function(t){return t!==Error.prototype}),t=>"isAxiosError"!==t),i.call(c,t.message,e,n,o,s),c.cause=t,c.name=t.name,l&&Object.assign(c,l),c},e["a"]=i},7948:function(t,e){function n(t,e){var n=-1,r=null==t?0:t.length,i=Array(r);while(++nt.length)&&(e=t.length);for(var n=0,r=new Array(e);n=t.length?{done:!0}:{done:!1,value:t[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function s(t,e){if("object"!==typeof t||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}function l(t){var e=s(t,"string");return"symbol"===typeof e?e:String(e)}function c(){return{async:!1,baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,hooks:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}function u(e){t.defaults=e}t.defaults=c();var h=/[&<>"']/,d=new RegExp(h.source,"g"),f=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,p=new RegExp(f.source,"g"),v={"&":"&","<":"<",">":">",'"':""","'":"'"},g=function(t){return v[t]};function m(t,e){if(e){if(h.test(t))return t.replace(d,g)}else if(f.test(t))return t.replace(p,g);return t}var y=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function b(t){return t.replace(y,(function(t,e){return e=e.toLowerCase(),"colon"===e?":":"#"===e.charAt(0)?"x"===e.charAt(1)?String.fromCharCode(parseInt(e.substring(2),16)):String.fromCharCode(+e.substring(1)):""}))}var x=/(^|[^\[])\^/g;function w(t,e){t="string"===typeof t?t:t.source,e=e||"";var n={replace:function(e,r){return r=r.source||r,r=r.replace(x,"$1"),t=t.replace(e,r),n},getRegex:function(){return new RegExp(t,e)}};return n}var k=/[^\w:]/g,S=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function C(t,e,n){if(t){var r;try{r=decodeURIComponent(b(n)).replace(k,"").toLowerCase()}catch(i){return null}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:")||0===r.indexOf("data:"))return null}e&&!S.test(n)&&(n=E(e,n));try{n=encodeURI(n).replace(/%25/g,"%")}catch(i){return null}return n}var A={},_=/^[^:]+:\/*[^/]*$/,D=/^([^:]+:)[\s\S]*$/,T=/^([^:]+:\/*[^/]*)[\s\S]*$/;function E(t,e){A[" "+t]||(_.test(t)?A[" "+t]=t+"/":A[" "+t]=I(t,"/",!0)),t=A[" "+t];var n=-1===t.indexOf(":");return"//"===e.substring(0,2)?n?e:t.replace(D,"$1")+e:"/"===e.charAt(0)?n?e:t.replace(T,"$1")+e:t+e}var O={exec:function(){}};function P(t,e){var n=t.replace(/\|/g,(function(t,e,n){var r=!1,i=e;while(--i>=0&&"\\"===n[i])r=!r;return r?"|":" |"})),r=n.split(/ \|/),i=0;if(r[0].trim()||r.shift(),r.length>0&&!r[r.length-1].trim()&&r.pop(),r.length>e)r.splice(e);else while(r.length1)1&e&&(n+=t),e>>=1,t+=t;return n+t}function j(t,e,n,r){var i=e.href,a=e.title?m(e.title):null,o=t[1].replace(/\\([\[\]])/g,"$1");if("!"!==t[0].charAt(0)){r.state.inLink=!0;var s={type:"link",raw:n,href:i,title:a,text:o,tokens:r.inlineTokens(o)};return r.state.inLink=!1,s}return{type:"image",raw:n,href:i,title:a,text:m(o)}}function B(t,e){var n=t.match(/^(\s+)(?:```)/);if(null===n)return e;var r=n[1];return e.split("\n").map((function(t){var e=t.match(/^\s+/);if(null===e)return t;var n=e[0];return n.length>=r.length?t.slice(r.length):t})).join("\n")}var R=function(){function e(e){this.options=e||t.defaults}var n=e.prototype;return n.space=function(t){var e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}},n.code=function(t){var e=this.rules.block.code.exec(t);if(e){var n=e[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?n:I(n,"\n")}}},n.fences=function(t){var e=this.rules.block.fences.exec(t);if(e){var n=e[0],r=B(n,e[3]||"");return{type:"code",raw:n,lang:e[2]?e[2].trim().replace(this.rules.inline._escapes,"$1"):e[2],text:r}}},n.heading=function(t){var e=this.rules.block.heading.exec(t);if(e){var n=e[2].trim();if(/#$/.test(n)){var r=I(n,"#");this.options.pedantic?n=r.trim():r&&!/ $/.test(r)||(n=r.trim())}return{type:"heading",raw:e[0],depth:e[1].length,text:n,tokens:this.lexer.inline(n)}}},n.hr=function(t){var e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:e[0]}},n.blockquote=function(t){var e=this.rules.block.blockquote.exec(t);if(e){var n=e[0].replace(/^ *>[ \t]?/gm,""),r=this.lexer.state.top;this.lexer.state.top=!0;var i=this.lexer.blockTokens(n);return this.lexer.state.top=r,{type:"blockquote",raw:e[0],tokens:i,text:n}}},n.list=function(t){var e=this.rules.block.list.exec(t);if(e){var n,r,i,a,o,s,l,c,u,h,d,f,p=e[1].trim(),v=p.length>1,g={type:"list",raw:"",ordered:v,start:v?+p.slice(0,-1):"",loose:!1,items:[]};p=v?"\\d{1,9}\\"+p.slice(-1):"\\"+p,this.options.pedantic&&(p=v?p:"[*+-]");var m=new RegExp("^( {0,3}"+p+")((?:[\t ][^\\n]*)?(?:\\n|$))");while(t){if(f=!1,!(e=m.exec(t)))break;if(this.rules.block.hr.test(t))break;if(n=e[0],t=t.substring(n.length),c=e[2].split("\n",1)[0].replace(/^\t+/,(function(t){return" ".repeat(3*t.length)})),u=t.split("\n",1)[0],this.options.pedantic?(a=2,d=c.trimLeft()):(a=e[2].search(/[^ ]/),a=a>4?1:a,d=c.slice(a),a+=e[1].length),s=!1,!c&&/^ *$/.test(u)&&(n+=u+"\n",t=t.substring(u.length+1),f=!0),!f){var y=new RegExp("^ {0,"+Math.min(3,a-1)+"}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))"),b=new RegExp("^ {0,"+Math.min(3,a-1)+"}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)"),x=new RegExp("^ {0,"+Math.min(3,a-1)+"}(?:```|~~~)"),w=new RegExp("^ {0,"+Math.min(3,a-1)+"}#");while(t){if(h=t.split("\n",1)[0],u=h,this.options.pedantic&&(u=u.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),x.test(u))break;if(w.test(u))break;if(y.test(u))break;if(b.test(t))break;if(u.search(/[^ ]/)>=a||!u.trim())d+="\n"+u.slice(a);else{if(s)break;if(c.search(/[^ ]/)>=4)break;if(x.test(c))break;if(w.test(c))break;if(b.test(c))break;d+="\n"+u}s||u.trim()||(s=!0),n+=h+"\n",t=t.substring(h.length+1),c=u.slice(a)}}g.loose||(l?g.loose=!0:/\n *\n *$/.test(n)&&(l=!0)),this.options.gfm&&(r=/^\[[ xX]\] /.exec(d),r&&(i="[ ] "!==r[0],d=d.replace(/^\[[ xX]\] +/,""))),g.items.push({type:"list_item",raw:n,task:!!r,checked:i,loose:!1,text:d}),g.raw+=n}g.items[g.items.length-1].raw=n.trimRight(),g.items[g.items.length-1].text=d.trimRight(),g.raw=g.raw.trimRight();var k=g.items.length;for(o=0;o0&&S.some((function(t){return/\n.*\n/.test(t.raw)}));g.loose=C}if(g.loose)for(o=0;o$/,"$1").replace(this.rules.inline._escapes,"$1"):"",i=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline._escapes,"$1"):e[3];return{type:"def",tag:n,raw:e[0],href:r,title:i}}},n.table=function(t){var e=this.rules.block.table.exec(t);if(e){var n={type:"table",header:P(e[1]).map((function(t){return{text:t}})),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),rows:e[3]&&e[3].trim()?e[3].replace(/\n[ \t]*$/,"").split("\n"):[]};if(n.header.length===n.align.length){n.raw=e[0];var r,i,a,o,s=n.align.length;for(r=0;r/i.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):m(e[0]):e[0]}},n.link=function(t){var e=this.rules.inline.link.exec(t);if(e){var n=e[2].trim();if(!this.options.pedantic&&/^$/.test(n))return;var r=I(n.slice(0,-1),"\\");if((n.length-r.length)%2===0)return}else{var i=M(e[2],"()");if(i>-1){var a=0===e[0].indexOf("!")?5:4,o=a+e[1].length+i;e[2]=e[2].substring(0,i),e[0]=e[0].substring(0,o).trim(),e[3]=""}}var s=e[2],l="";if(this.options.pedantic){var c=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(s);c&&(s=c[1],l=c[3])}else l=e[3]?e[3].slice(1,-1):"";return s=s.trim(),/^$/.test(n)?s.slice(1):s.slice(1,-1)),j(e,{href:s?s.replace(this.rules.inline._escapes,"$1"):s,title:l?l.replace(this.rules.inline._escapes,"$1"):l},e[0],this.lexer)}},n.reflink=function(t,e){var n;if((n=this.rules.inline.reflink.exec(t))||(n=this.rules.inline.nolink.exec(t))){var r=(n[2]||n[1]).replace(/\s+/g," ");if(r=e[r.toLowerCase()],!r){var i=n[0].charAt(0);return{type:"text",raw:i,text:i}}return j(n,r,n[0],this.lexer)}},n.emStrong=function(t,e,n){void 0===n&&(n="");var r=this.rules.inline.emStrong.lDelim.exec(t);if(r&&(!r[3]||!n.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/))){var i=r[1]||r[2]||"";if(!i||i&&(""===n||this.rules.inline.punctuation.exec(n))){var a,o,s=r[0].length-1,l=s,c=0,u="*"===r[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;u.lastIndex=0,e=e.slice(-1*t.length+s);while(null!=(r=u.exec(e)))if(a=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],a)if(o=a.length,r[3]||r[4])l+=o;else if(!((r[5]||r[6])&&s%3)||(s+o)%3){if(l-=o,!(l>0)){o=Math.min(o,o+l+c);var h=t.slice(0,s+r.index+(r[0].length-a.length)+o);if(Math.min(s,o)%2){var d=h.slice(1,-1);return{type:"em",raw:h,text:d,tokens:this.lexer.inlineTokens(d)}}var f=h.slice(2,-2);return{type:"strong",raw:h,text:f,tokens:this.lexer.inlineTokens(f)}}}else c+=o}}},n.codespan=function(t){var e=this.rules.inline.code.exec(t);if(e){var n=e[2].replace(/\n/g," "),r=/[^ ]/.test(n),i=/^ /.test(n)&&/ $/.test(n);return r&&i&&(n=n.substring(1,n.length-1)),n=m(n,!0),{type:"codespan",raw:e[0],text:n}}},n.br=function(t){var e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}},n.del=function(t){var e=this.rules.inline.del.exec(t);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2])}},n.autolink=function(t,e){var n,r,i=this.rules.inline.autolink.exec(t);if(i)return"@"===i[2]?(n=m(this.options.mangle?e(i[1]):i[1]),r="mailto:"+n):(n=m(i[1]),r=n),{type:"link",raw:i[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}},n.url=function(t,e){var n;if(n=this.rules.inline.url.exec(t)){var r,i;if("@"===n[2])r=m(this.options.mangle?e(n[0]):n[0]),i="mailto:"+r;else{var a;do{a=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])[0]}while(a!==n[0]);r=m(n[0]),i="www."===n[1]?"http://"+n[0]:n[0]}return{type:"link",raw:n[0],text:r,href:i,tokens:[{type:"text",raw:r,text:r}]}}},n.inlineText=function(t,e){var n,r=this.rules.inline.text.exec(t);if(r)return n=this.lexer.state.inRawBlock?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(r[0]):m(r[0]):r[0]:m(this.options.smartypants?e(r[0]):r[0]),{type:"text",raw:r[0],text:n}},e}(),F={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,table:O,lheading:/^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\.|[^\[\]\\])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};F.def=w(F.def).replace("label",F._label).replace("title",F._title).getRegex(),F.bullet=/(?:[*+-]|\d{1,9}[.)])/,F.listItemStart=w(/^( *)(bull) */).replace("bull",F.bullet).getRegex(),F.list=w(F.list).replace(/bull/g,F.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+F.def.source+")").getRegex(),F._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",F._comment=/|$)/,F.html=w(F.html,"i").replace("comment",F._comment).replace("tag",F._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),F.paragraph=w(F._paragraph).replace("hr",F.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",F._tag).getRegex(),F.blockquote=w(F.blockquote).replace("paragraph",F.paragraph).getRegex(),F.normal=r({},F),F.gfm=r({},F.normal,{table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),F.gfm.table=w(F.gfm.table).replace("hr",F.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",F._tag).getRegex(),F.gfm.paragraph=w(F._paragraph).replace("hr",F.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("table",F.gfm.table).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",F._tag).getRegex(),F.pedantic=r({},F.normal,{html:w("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",F._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:O,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:w(F.normal._paragraph).replace("hr",F.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",F.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});var N={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:O,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(ref)\]/,nolink:/^!?\[(ref)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,rDelimUnd:/^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:O,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\.5&&(n="x"+n.toString(16)),r+="&#"+n+";";return r}N._punctuation="!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~",N.punctuation=w(N.punctuation).replace(/punctuation/g,N._punctuation).getRegex(),N.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,N.escapedEmSt=/(?:^|[^\\])(?:\\\\)*\\[*_]/g,N._comment=w(F._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),N.emStrong.lDelim=w(N.emStrong.lDelim).replace(/punct/g,N._punctuation).getRegex(),N.emStrong.rDelimAst=w(N.emStrong.rDelimAst,"g").replace(/punct/g,N._punctuation).getRegex(),N.emStrong.rDelimUnd=w(N.emStrong.rDelimUnd,"g").replace(/punct/g,N._punctuation).getRegex(),N._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,N._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,N._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,N.autolink=w(N.autolink).replace("scheme",N._scheme).replace("email",N._email).getRegex(),N._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,N.tag=w(N.tag).replace("comment",N._comment).replace("attribute",N._attribute).getRegex(),N._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,N._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,N._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,N.link=w(N.link).replace("label",N._label).replace("href",N._href).replace("title",N._title).getRegex(),N.reflink=w(N.reflink).replace("label",N._label).replace("ref",F._label).getRegex(),N.nolink=w(N.nolink).replace("ref",F._label).getRegex(),N.reflinkSearch=w(N.reflinkSearch,"g").replace("reflink",N.reflink).replace("nolink",N.nolink).getRegex(),N.normal=r({},N),N.pedantic=r({},N.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:w(/^!?\[(label)\]\((.*?)\)/).replace("label",N._label).getRegex(),reflink:w(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",N._label).getRegex()}),N.gfm=r({},N.normal,{escape:w(N.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\0?e[e.length-1].raw+="\n":e.push(n);else if(n=this.tokenizer.code(t))t=t.substring(n.raw.length),r=e[e.length-1],!r||"paragraph"!==r.type&&"text"!==r.type?e.push(n):(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=r.text);else if(n=this.tokenizer.fences(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.heading(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.hr(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.blockquote(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.list(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.html(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.def(t))t=t.substring(n.raw.length),r=e[e.length-1],!r||"paragraph"!==r.type&&"text"!==r.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(r.raw+="\n"+n.raw,r.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=r.text);else if(n=this.tokenizer.table(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.lheading(t))t=t.substring(n.raw.length),e.push(n);else if(i=t,this.options.extensions&&this.options.extensions.startBlock&&function(){var e=1/0,n=t.slice(1),r=void 0;o.options.extensions.startBlock.forEach((function(t){r=t.call({lexer:this},n),"number"===typeof r&&r>=0&&(e=Math.min(e,r))})),e<1/0&&e>=0&&(i=t.substring(0,e+1))}(),this.state.top&&(n=this.tokenizer.paragraph(i)))r=e[e.length-1],a&&"paragraph"===r.type?(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=r.text):e.push(n),a=i.length!==t.length,t=t.substring(n.raw.length);else if(n=this.tokenizer.text(t))t=t.substring(n.raw.length),r=e[e.length-1],r&&"text"===r.type?(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=r.text):e.push(n);else if(t){var s="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(s);break}throw new Error(s)}return this.state.top=!0,e},r.inline=function(t,e){return void 0===e&&(e=[]),this.inlineQueue.push({src:t,tokens:e}),e},r.inlineTokens=function(t,e){var n,r,i,a=this;void 0===e&&(e=[]);var o,s,l,c=t;if(this.tokens.links){var u=Object.keys(this.tokens.links);if(u.length>0)while(null!=(o=this.tokenizer.rules.inline.reflinkSearch.exec(c)))u.includes(o[0].slice(o[0].lastIndexOf("[")+1,-1))&&(c=c.slice(0,o.index)+"["+L("a",o[0].length-2)+"]"+c.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}while(null!=(o=this.tokenizer.rules.inline.blockSkip.exec(c)))c=c.slice(0,o.index)+"["+L("a",o[0].length-2)+"]"+c.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);while(null!=(o=this.tokenizer.rules.inline.escapedEmSt.exec(c)))c=c.slice(0,o.index+o[0].length-2)+"++"+c.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex),this.tokenizer.rules.inline.escapedEmSt.lastIndex--;while(t)if(s||(l=""),s=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some((function(r){return!!(n=r.call({lexer:a},t,e))&&(t=t.substring(n.raw.length),e.push(n),!0)}))))if(n=this.tokenizer.escape(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.tag(t))t=t.substring(n.raw.length),r=e[e.length-1],r&&"text"===n.type&&"text"===r.type?(r.raw+=n.raw,r.text+=n.text):e.push(n);else if(n=this.tokenizer.link(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.reflink(t,this.tokens.links))t=t.substring(n.raw.length),r=e[e.length-1],r&&"text"===n.type&&"text"===r.type?(r.raw+=n.raw,r.text+=n.text):e.push(n);else if(n=this.tokenizer.emStrong(t,c,l))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.codespan(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.br(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.del(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.autolink(t,$))t=t.substring(n.raw.length),e.push(n);else if(this.state.inLink||!(n=this.tokenizer.url(t,$))){if(i=t,this.options.extensions&&this.options.extensions.startInline&&function(){var e=1/0,n=t.slice(1),r=void 0;a.options.extensions.startInline.forEach((function(t){r=t.call({lexer:this},n),"number"===typeof r&&r>=0&&(e=Math.min(e,r))})),e<1/0&&e>=0&&(i=t.substring(0,e+1))}(),n=this.tokenizer.inlineText(i,z))t=t.substring(n.raw.length),"_"!==n.raw.slice(-1)&&(l=n.raw.slice(-1)),s=!0,r=e[e.length-1],r&&"text"===r.type?(r.raw+=n.raw,r.text+=n.text):e.push(n);else if(t){var h="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(h);break}throw new Error(h)}}else t=t.substring(n.raw.length),e.push(n);return e},n(e,null,[{key:"rules",get:function(){return{block:F,inline:N}}}]),e}(),H=function(){function e(e){this.options=e||t.defaults}var n=e.prototype;return n.code=function(t,e,n){var r=(e||"").match(/\S*/)[0];if(this.options.highlight){var i=this.options.highlight(t,r);null!=i&&i!==t&&(n=!0,t=i)}return t=t.replace(/\n$/,"")+"\n",r?'
'+(n?t:m(t,!0))+"
\n":"
"+(n?t:m(t,!0))+"
\n"},n.blockquote=function(t){return"
\n"+t+"
\n"},n.html=function(t){return t},n.heading=function(t,e,n,r){if(this.options.headerIds){var i=this.options.headerPrefix+r.slug(n);return"'+t+"\n"}return""+t+"\n"},n.hr=function(){return this.options.xhtml?"
\n":"
\n"},n.list=function(t,e,n){var r=e?"ol":"ul",i=e&&1!==n?' start="'+n+'"':"";return"<"+r+i+">\n"+t+"\n"},n.listitem=function(t){return"
  • "+t+"
  • \n"},n.checkbox=function(t){return" "},n.paragraph=function(t){return"

    "+t+"

    \n"},n.table=function(t,e){return e&&(e=""+e+""),"\n\n"+t+"\n"+e+"
    \n"},n.tablerow=function(t){return"\n"+t+"\n"},n.tablecell=function(t,e){var n=e.header?"th":"td",r=e.align?"<"+n+' align="'+e.align+'">':"<"+n+">";return r+t+"\n"},n.strong=function(t){return""+t+""},n.em=function(t){return""+t+""},n.codespan=function(t){return""+t+""},n.br=function(){return this.options.xhtml?"
    ":"
    "},n.del=function(t){return""+t+""},n.link=function(t,e,n){if(t=C(this.options.sanitize,this.options.baseUrl,t),null===t)return n;var r='
    ",r},n.image=function(t,e,n){if(t=C(this.options.sanitize,this.options.baseUrl,t),null===t)return n;var r=''+n+'":">",r},n.text=function(t){return t},e}(),W=function(){function t(){}var e=t.prototype;return e.strong=function(t){return t},e.em=function(t){return t},e.codespan=function(t){return t},e.del=function(t){return t},e.html=function(t){return t},e.text=function(t){return t},e.link=function(t,e,n){return""+n},e.image=function(t,e,n){return""+n},e.br=function(){return""},t}(),X=function(){function t(){this.seen={}}var e=t.prototype;return e.serialize=function(t){return t.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},e.getNextSafeSlug=function(t,e){var n=t,r=0;if(this.seen.hasOwnProperty(n)){r=this.seen[t];do{r++,n=t+"-"+r}while(this.seen.hasOwnProperty(n))}return e||(this.seen[t]=r,this.seen[n]=0),n},e.slug=function(t,e){void 0===e&&(e={});var n=this.serialize(t);return this.getNextSafeSlug(n,e.dryrun)},t}(),G=function(){function e(e){this.options=e||t.defaults,this.options.renderer=this.options.renderer||new H,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new W,this.slugger=new X}e.parse=function(t,n){var r=new e(n);return r.parse(t)},e.parseInline=function(t,n){var r=new e(n);return r.parseInline(t)};var n=e.prototype;return n.parse=function(t,e){void 0===e&&(e=!0);var n,r,i,a,o,s,l,c,u,h,d,f,p,v,g,m,y,x,w,k="",S=t.length;for(n=0;n0&&"paragraph"===g.tokens[0].type?(g.tokens[0].text=x+" "+g.tokens[0].text,g.tokens[0].tokens&&g.tokens[0].tokens.length>0&&"text"===g.tokens[0].tokens[0].type&&(g.tokens[0].tokens[0].text=x+" "+g.tokens[0].tokens[0].text)):g.tokens.unshift({type:"text",text:x}):v+=x),v+=this.parse(g.tokens,p),u+=this.renderer.listitem(v,y,m);k+=this.renderer.list(u,d,f);continue;case"html":k+=this.renderer.html(h.text);continue;case"paragraph":k+=this.renderer.paragraph(this.parseInline(h.tokens));continue;case"text":u=h.tokens?this.parseInline(h.tokens):h.text;while(n+1";return e?Promise.resolve(i):n?void n(null,i):i}if(e)return Promise.reject(r);if(!n)throw r;n(r)}}function Z(t,e){return function(n,i,a){"function"===typeof i&&(a=i,i=null);var o=r({},i);i=r({},K.defaults,o);var s=q(i.silent,i.async,a);if("undefined"===typeof n||null===n)return s(new Error("marked(): input parameter is undefined or null"));if("string"!==typeof n)return s(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(V(i),i.hooks&&(i.hooks.options=i),a){var l,c=i.highlight;try{i.hooks&&(n=i.hooks.preprocess(n)),l=t(n,i)}catch(p){return s(p)}var u=function(t){var n;if(!t)try{i.walkTokens&&K.walkTokens(l,i.walkTokens),n=e(l,i),i.hooks&&(n=i.hooks.postprocess(n))}catch(p){t=p}return i.highlight=c,t?s(t):a(null,n)};if(!c||c.length<3)return u();if(delete i.highlight,!l.length)return u();var h=0;return K.walkTokens(l,(function(t){"code"===t.type&&(h++,setTimeout((function(){c(t.text,t.lang,(function(e,n){if(e)return u(e);null!=n&&n!==t.text&&(t.text=n,t.escaped=!0),h--,0===h&&u()}))}),0))})),void(0===h&&u())}if(i.async)return Promise.resolve(i.hooks?i.hooks.preprocess(n):n).then((function(e){return t(e,i)})).then((function(t){return i.walkTokens?Promise.all(K.walkTokens(t,i.walkTokens)).then((function(){return t})):t})).then((function(t){return e(t,i)})).then((function(t){return i.hooks?i.hooks.postprocess(t):t}))["catch"](s);try{i.hooks&&(n=i.hooks.preprocess(n));var d=t(n,i);i.walkTokens&&K.walkTokens(d,i.walkTokens);var f=e(d,i);return i.hooks&&(f=i.hooks.postprocess(f)),f}catch(p){return s(p)}}}function K(t,e,n){return Z(Y.lex,G.parse)(t,e,n)}U.passThroughHooks=new Set(["preprocess","postprocess"]),K.options=K.setOptions=function(t){return K.defaults=r({},K.defaults,t),u(K.defaults),K},K.getDefaults=c,K.defaults=t.defaults,K.use=function(){for(var t=K.defaults.extensions||{renderers:{},childTokens:{}},e=arguments.length,n=new Array(e),i=0;il)r.f(t,n=o[l++],e[n]);return t}},"7ed2":function(t,e){var n="__lodash_hash_undefined__";function r(t){return this.__data__.set(t,n),this}t.exports=r},"7f20":function(t,e,n){var r=n("86cc").f,i=n("69a8"),a=n("2b4c")("toStringTag");t.exports=function(t,e,n){t&&!i(t=n?t:t.prototype,a)&&r(t,a,{configurable:!0,value:e})}},"7f7f":function(t,e,n){var r=n("86cc").f,i=Function.prototype,a=/^\s*function ([^ (]*)/,o="name";o in i||n("9e1e")&&r(i,o,{configurable:!0,get:function(){try{return(""+this).match(a)[1]}catch(t){return""}}})},"802a":function(t,e){function n(t){return this.__data__.get(t)}t.exports=n},8057:function(t,e){function n(t,e){var n=-1,r=null==t?0:t.length;while(++ni)Z(t,n=r[i++],e[n]);return t},J=function(t,e){return void 0===e?C(t):K(C(t),e)},Q=function(t){var e=F.call(this,t=k(t,!0));return!(this===Y&&i(z,t)&&!i($,t))&&(!(e||!i(this,t)||!i(z,t)||i(this,B)&&this[B][t])||e)},tt=function(t,e){if(t=w(t),e=k(e,!0),t!==Y||!i(z,e)||i($,e)){var n=O(t,e);return!n||!i(z,e)||i(t,B)&&t[B][e]||(n.enumerable=!0),n}},et=function(t){var e,n=I(w(t)),r=[],a=0;while(n.length>a)i(z,e=n[a++])||e==B||e==l||r.push(e);return r},nt=function(t){var e,n=t===Y,r=I(n?$:w(t)),a=[],o=0;while(r.length>o)!i(z,e=r[o++])||n&&!i(Y,e)||a.push(z[e]);return a};H||(M=function(){if(this instanceof M)throw TypeError("Symbol is not a constructor!");var t=d(arguments.length>0?arguments[0]:void 0),e=function(n){this===Y&&e.call($,n),i(this,B)&&i(this[B],t)&&(this[B][t]=!1),G(this,t,S(1,n))};return a&&X&&G(Y,t,{configurable:!0,set:e}),U(t)},s(M[j],"toString",(function(){return this._k})),_.f=tt,T.f=Z,n("9093").f=A.f=et,n("52a7").f=Q,D.f=nt,a&&!n("2d00")&&s(Y,"propertyIsEnumerable",Q,!0),p.f=function(t){return U(f(t))}),o(o.G+o.W+o.F*!H,{Symbol:M});for(var rt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),it=0;rt.length>it;)f(rt[it++]);for(var at=E(f.store),ot=0;at.length>ot;)v(at[ot++]);o(o.S+o.F*!H,"Symbol",{for:function(t){return i(N,t+="")?N[t]:N[t]=M(t)},keyFor:function(t){if(!q(t))throw TypeError(t+" is not a symbol!");for(var e in N)if(N[e]===t)return e},useSetter:function(){X=!0},useSimple:function(){X=!1}}),o(o.S+o.F*!H,"Object",{create:J,defineProperty:Z,defineProperties:K,getOwnPropertyDescriptor:tt,getOwnPropertyNames:et,getOwnPropertySymbols:nt});var st=c((function(){D.f(1)}));o(o.S+o.F*st,"Object",{getOwnPropertySymbols:function(t){return D.f(x(t))}}),V&&o(o.S+o.F*(!H||c((function(){var t=M();return"[null]"!=L([t])||"{}"!=L({a:t})||"{}"!=L(Object(t))}))),"JSON",{stringify:function(t){var e,n,r=[t],i=1;while(arguments.length>i)r.push(arguments[i++]);if(n=e=r[1],(b(e)||void 0!==t)&&!q(t))return m(e)||(e=function(t,e){if("function"==typeof n&&(e=n.call(this,t,e)),!q(e))return e}),r[1]=e,L.apply(V,r)}}),M[j][R]||n("32e9")(M[j],R,M[j].valueOf),h(M,"Symbol"),h(Math,"Math",!0),h(r.JSON,"JSON",!0)},"8adb":function(t,e){function n(t,e){if(("constructor"!==e||"function"!==typeof t[e])&&"__proto__"!=e)return t[e]}t.exports=n},"8b97":function(t,e,n){var r=n("d3f4"),i=n("cb7c"),a=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,r){try{r=n("9b43")(Function.call,n("11e9").f(Object.prototype,"__proto__").set,2),r(t,[]),e=!(t instanceof Array)}catch(i){e=!0}return function(t,n){return a(t,n),e?t.__proto__=n:r(t,n),t}}({},!1):void 0),check:a}},"8c4f":function(t,e,n){"use strict";function r(t,e){for(var n in e)t[n]=e[n];return t}n.d(e,"a",(function(){return ke}));var i=/[!'()*]/g,a=function(t){return"%"+t.charCodeAt(0).toString(16)},o=/%2C/g,s=function(t){return encodeURIComponent(t).replace(i,a).replace(o,",")};function l(t){try{return decodeURIComponent(t)}catch(e){0}return t}function c(t,e,n){void 0===e&&(e={});var r,i=n||h;try{r=i(t||"")}catch(s){r={}}for(var a in e){var o=e[a];r[a]=Array.isArray(o)?o.map(u):u(o)}return r}var u=function(t){return null==t||"object"===typeof t?t:String(t)};function h(t){var e={};return t=t.trim().replace(/^(\?|#|&)/,""),t?(t.split("&").forEach((function(t){var n=t.replace(/\+/g," ").split("="),r=l(n.shift()),i=n.length>0?l(n.join("=")):null;void 0===e[r]?e[r]=i:Array.isArray(e[r])?e[r].push(i):e[r]=[e[r],i]})),e):e}function d(t){var e=t?Object.keys(t).map((function(e){var n=t[e];if(void 0===n)return"";if(null===n)return s(e);if(Array.isArray(n)){var r=[];return n.forEach((function(t){void 0!==t&&(null===t?r.push(s(e)):r.push(s(e)+"="+s(t)))})),r.join("&")}return s(e)+"="+s(n)})).filter((function(t){return t.length>0})).join("&"):null;return e?"?"+e:""}var f=/\/?$/;function p(t,e,n,r){var i=r&&r.options.stringifyQuery,a=e.query||{};try{a=v(a)}catch(s){}var o={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:a,params:e.params||{},fullPath:y(e,i),matched:t?m(t):[]};return n&&(o.redirectedFrom=y(n,i)),Object.freeze(o)}function v(t){if(Array.isArray(t))return t.map(v);if(t&&"object"===typeof t){var e={};for(var n in t)e[n]=v(t[n]);return e}return t}var g=p(null,{path:"/"});function m(t){var e=[];while(t)e.unshift(t),t=t.parent;return e}function y(t,e){var n=t.path,r=t.query;void 0===r&&(r={});var i=t.hash;void 0===i&&(i="");var a=e||d;return(n||"/")+a(r)+i}function b(t,e,n){return e===g?t===e:!!e&&(t.path&&e.path?t.path.replace(f,"")===e.path.replace(f,"")&&(n||t.hash===e.hash&&x(t.query,e.query)):!(!t.name||!e.name)&&(t.name===e.name&&(n||t.hash===e.hash&&x(t.query,e.query)&&x(t.params,e.params))))}function x(t,e){if(void 0===t&&(t={}),void 0===e&&(e={}),!t||!e)return t===e;var n=Object.keys(t).sort(),r=Object.keys(e).sort();return n.length===r.length&&n.every((function(n,i){var a=t[n],o=r[i];if(o!==n)return!1;var s=e[n];return null==a||null==s?a===s:"object"===typeof a&&"object"===typeof s?x(a,s):String(a)===String(s)}))}function w(t,e){return 0===t.path.replace(f,"/").indexOf(e.path.replace(f,"/"))&&(!e.hash||t.hash===e.hash)&&k(t.query,e.query)}function k(t,e){for(var n in e)if(!(n in t))return!1;return!0}function S(t){for(var e=0;e=0&&(e=t.slice(r),t=t.slice(0,r));var i=t.indexOf("?");return i>=0&&(n=t.slice(i+1),t=t.slice(0,i)),{path:t,query:n,hash:e}}function E(t){return t.replace(/\/(?:\s*\/)+/g,"/")}var O=Array.isArray||function(t){return"[object Array]"==Object.prototype.toString.call(t)},P=Z,I=B,M=R,V=z,L=q,j=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function B(t,e){var n,r=[],i=0,a=0,o="",s=e&&e.delimiter||"/";while(null!=(n=j.exec(t))){var l=n[0],c=n[1],u=n.index;if(o+=t.slice(a,u),a=u+l.length,c)o+=c[1];else{var h=t[a],d=n[2],f=n[3],p=n[4],v=n[5],g=n[6],m=n[7];o&&(r.push(o),o="");var y=null!=d&&null!=h&&h!==d,b="+"===g||"*"===g,x="?"===g||"*"===g,w=n[2]||s,k=p||v;r.push({name:f||i++,prefix:d||"",delimiter:w,optional:x,repeat:b,partial:y,asterisk:!!m,pattern:k?Y(k):m?".*":"[^"+$(w)+"]+?"})}}return a1||!C.length)return 0===C.length?t():t("span",{},C)}if("a"===this.tag)S.on=k,S.attrs={href:l,"aria-current":y};else{var A=ot(this.$slots.default);if(A){A.isStatic=!1;var _=A.data=r({},A.data);for(var D in _.on=_.on||{},_.on){var T=_.on[D];D in k&&(_.on[D]=Array.isArray(T)?T:[T])}for(var E in k)E in _.on?_.on[E].push(k[E]):_.on[E]=x;var O=A.data.attrs=r({},A.data.attrs);O.href=l,O["aria-current"]=y}else S.on=k}return t(this.tag,S,this.$slots.default)}};function at(t){if(!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)&&!t.defaultPrevented&&(void 0===t.button||0===t.button)){if(t.currentTarget&&t.currentTarget.getAttribute){var e=t.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(e))return}return t.preventDefault&&t.preventDefault(),!0}}function ot(t){if(t)for(var e,n=0;n-1&&(s.params[h]=n.params[h]);return s.path=J(c.path,s.params,'named route "'+l+'"'),d(c,s,o)}if(s.path){s.params={};for(var f=0;f-1}function Xt(t,e){return Wt(t)&&t._isRouter&&(null==e||t.type===e)}function Gt(t,e,n){var r=function(i){i>=t.length?n():t[i]?e(t[i],(function(){r(i+1)})):r(i+1)};r(0)}function Ut(t){return function(e,n,r){var i=!1,a=0,o=null;qt(t,(function(t,e,n,s){if("function"===typeof t&&void 0===t.cid){i=!0,a++;var l,c=Qt((function(e){Jt(e)&&(e=e.default),t.resolved="function"===typeof e?e:tt.extend(e),n.components[s]=e,a--,a<=0&&r()})),u=Qt((function(t){var e="Failed to resolve async component "+s+": "+t;o||(o=Wt(t)?t:new Error(e),r(o))}));try{l=t(c,u)}catch(d){u(d)}if(l)if("function"===typeof l.then)l.then(c,u);else{var h=l.component;h&&"function"===typeof h.then&&h.then(c,u)}}})),i||r()}}function qt(t,e){return Zt(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Zt(t){return Array.prototype.concat.apply([],t)}var Kt="function"===typeof Symbol&&"symbol"===typeof Symbol.toStringTag;function Jt(t){return t.__esModule||Kt&&"Module"===t[Symbol.toStringTag]}function Qt(t){var e=!1;return function(){var n=[],r=arguments.length;while(r--)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var te=function(t,e){this.router=t,this.base=ee(e),this.current=g,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function ee(t){if(!t)if(lt){var e=document.querySelector("base");t=e&&e.getAttribute("href")||"/",t=t.replace(/^https?:\/\/[^\/]+/,"")}else t="/";return"/"!==t.charAt(0)&&(t="/"+t),t.replace(/\/$/,"")}function ne(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=Vt&&n;r&&this.listeners.push(kt());var i=function(){var n=t.current,i=he(t.base);t.current===g&&i===t._startLocation||t.transitionTo(i,(function(t){r&&St(e,t,n,!0)}))};window.addEventListener("popstate",i),this.listeners.push((function(){window.removeEventListener("popstate",i)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,i=this,a=i.current;this.transitionTo(t,(function(t){Lt(E(r.base+t.fullPath)),St(r.router,t,a,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,i=this,a=i.current;this.transitionTo(t,(function(t){jt(E(r.base+t.fullPath)),St(r.router,t,a,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(he(this.base)!==this.current.fullPath){var e=E(this.base+this.current.fullPath);t?Lt(e):jt(e)}},e.prototype.getCurrentLocation=function(){return he(this.base)},e}(te);function he(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(E(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var de=function(t){function e(e,n,r){t.call(this,e,n),r&&fe(this.base)||pe()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router,n=e.options.scrollBehavior,r=Vt&&n;r&&this.listeners.push(kt());var i=function(){var e=t.current;pe()&&t.transitionTo(ve(),(function(n){r&&St(t.router,n,e,!0),Vt||ye(n.fullPath)}))},a=Vt?"popstate":"hashchange";window.addEventListener(a,i),this.listeners.push((function(){window.removeEventListener(a,i)}))}},e.prototype.push=function(t,e,n){var r=this,i=this,a=i.current;this.transitionTo(t,(function(t){me(t.fullPath),St(r.router,t,a,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,i=this,a=i.current;this.transitionTo(t,(function(t){ye(t.fullPath),St(r.router,t,a,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;ve()!==e&&(t?me(e):ye(e))},e.prototype.getCurrentLocation=function(){return ve()},e}(te);function fe(t){var e=he(t);if(!/^\/#/.test(e))return window.location.replace(E(t+"/#"+e)),!0}function pe(){var t=ve();return"/"===t.charAt(0)||(ye("/"+t),!1)}function ve(){var t=window.location.href,e=t.indexOf("#");return e<0?"":(t=t.slice(e+1),t)}function ge(t){var e=window.location.href,n=e.indexOf("#"),r=n>=0?e.slice(0,n):e;return r+"#"+t}function me(t){Vt?Lt(ge(t)):window.location.hash=t}function ye(t){Vt?jt(ge(t)):window.location.replace(ge(t))}var be=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){Xt(t,Bt.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(te),xe=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=ft(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!Vt&&!1!==t.fallback,this.fallback&&(e="hash"),lt||(e="abstract"),this.mode=e,e){case"history":this.history=new ue(this,t.base);break;case"hash":this.history=new de(this,t.base,this.fallback);break;case"abstract":this.history=new be(this,t.base);break;default:0}},we={currentRoute:{configurable:!0}};xe.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},we.currentRoute.get=function(){return this.history&&this.history.current},xe.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof ue||n instanceof de){var r=function(t){var r=n.current,i=e.options.scrollBehavior,a=Vt&&i;a&&"fullPath"in t&&St(e,t,r,!1)},i=function(t){n.setupListeners(),r(t)};n.transitionTo(n.getCurrentLocation(),i,i)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},xe.prototype.beforeEach=function(t){return Se(this.beforeHooks,t)},xe.prototype.beforeResolve=function(t){return Se(this.resolveHooks,t)},xe.prototype.afterEach=function(t){return Se(this.afterHooks,t)},xe.prototype.onReady=function(t,e){this.history.onReady(t,e)},xe.prototype.onError=function(t){this.history.onError(t)},xe.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!==typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},xe.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!==typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},xe.prototype.go=function(t){this.history.go(t)},xe.prototype.back=function(){this.go(-1)},xe.prototype.forward=function(){this.go(1)},xe.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},xe.prototype.resolve=function(t,e,n){e=e||this.history.current;var r=Q(t,e,n,this),i=this.match(r,e),a=i.redirectedFrom||i.fullPath,o=this.history.base,s=Ce(o,a,this.mode);return{location:r,route:i,href:s,normalizedTo:r,resolved:i}},xe.prototype.getRoutes=function(){return this.matcher.getRoutes()},xe.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==g&&this.history.transitionTo(this.history.getCurrentLocation())},xe.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==g&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(xe.prototype,we);var ke=xe;function Se(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}function Ce(t,e,n){var r="hash"===n?"#"+e:e;return t?E(t+"/"+r):r}xe.install=st,xe.version="3.6.5",xe.isNavigationFailure=Xt,xe.NavigationFailureType=Bt,xe.START_LOCATION=g,lt&&window.Vue&&window.Vue.use(xe)},"8c55":function(t,e,n){"use strict";var r=n("6f9c"),i=n("17d5").Graph,a=n("b50e");function o(t,e){var n={};function i(e,i){var a=0,o=0,s=e.length,u=r.last(i);return r.forEach(i,(function(e,h){var d=l(t,e),f=d?t.node(d).order:s;(d||e===u)&&(r.forEach(i.slice(o,h+1),(function(e){r.forEach(t.predecessors(e),(function(r){var i=t.node(r),o=i.order;!(os)&&c(n,e,l)}))}))}function a(e,n){var a,o=-1,s=0;return r.forEach(n,(function(r,l){if("border"===t.node(r).dummy){var c=t.predecessors(r);c.length&&(a=t.node(c[0]).order,i(n,s,l,o,a),s=l,o=a)}i(n,s,n.length,a,e.length)})),n}return r.reduce(e,a),n}function l(t,e){if(t.node(e).dummy)return r.find(t.predecessors(e),(function(e){return t.node(e).dummy}))}function c(t,e,n){if(e>n){var r=e;e=n,n=r}var i=t[e];i||(t[e]=i={}),i[n]=!0}function u(t,e,n){if(e>n){var i=e;e=n,n=i}return r.has(t[e],n)}function h(t,e,n,i){var a={},o={},s={};return r.forEach(e,(function(t){r.forEach(t,(function(t,e){a[t]=t,o[t]=t,s[t]=e}))})),r.forEach(e,(function(t){var e=-1;r.forEach(t,(function(t){var l=i(t);if(l.length){l=r.sortBy(l,(function(t){return s[t]}));for(var c=(l.length-1)/2,h=Math.floor(c),d=Math.ceil(c);h<=d;++h){var f=l[h];o[t]===t&&e-1}t.exports=i},"8de2":function(t,e,n){var r=n("8eeb"),i=n("9934");function a(t){return r(t,i(t))}t.exports=a},"8e60":function(t,e,n){t.exports=!n("294c")((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},"8e6e":function(t,e,n){var r=n("5ca1"),i=n("990b"),a=n("6821"),o=n("11e9"),s=n("f1ae");r(r.S,"Object",{getOwnPropertyDescriptors:function(t){var e,n,r=a(t),l=o.f,c=i(r),u={},h=0;while(c.length>h)n=l(r,e=c[h++]),void 0!==n&&s(u,e,n);return u}})},"8eeb":function(t,e,n){var r=n("32b3"),i=n("872a");function a(t,e,n,a){var o=!n;n||(n={});var s=-1,l=e.length;while(++s */ +e.read=function(t,e,n,r,i){var a,o,s=8*i-r-1,l=(1<>1,u=-7,h=n?i-1:0,d=n?-1:1,f=t[e+h];for(h+=d,a=f&(1<<-u)-1,f>>=-u,u+=s;u>0;a=256*a+t[e+h],h+=d,u-=8);for(o=a&(1<<-u)-1,a>>=-u,u+=r;u>0;o=256*o+t[e+h],h+=d,u-=8);if(0===a)a=1-c;else{if(a===l)return o?NaN:1/0*(f?-1:1);o+=Math.pow(2,r),a-=c}return(f?-1:1)*o*Math.pow(2,a-r)},e.write=function(t,e,n,r,i,a){var o,s,l,c=8*a-i-1,u=(1<>1,d=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=r?0:a-1,p=r?1:-1,v=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(s=isNaN(e)?1:0,o=u):(o=Math.floor(Math.log(e)/Math.LN2),e*(l=Math.pow(2,-o))<1&&(o--,l*=2),e+=o+h>=1?d/l:d*Math.pow(2,1-h),e*l>=2&&(o++,l/=2),o+h>=u?(s=0,o=u):o+h>=1?(s=(e*l-1)*Math.pow(2,i),o+=h):(s=e*Math.pow(2,h-1)*Math.pow(2,i),o=0));i>=8;t[n+f]=255&s,f+=p,s/=256,i-=8);for(o=o<0;t[n+f]=255&o,f+=p,o/=256,c-=8);t[n+f-p]|=128*v}},"91e9":function(t,e){function n(t,e){return function(n){return t(e(n))}}t.exports=n},9214:function(t,e){t.exports="0.8.5"},9380:function(t,e,n){var r=n("2d7c"),i=n("9f74"),a=n("badf"),o=n("6747");function s(t,e){var n=o(t)?r:i;return n(t,a(e,3))}t.exports=s},"93ed":function(t,e,n){var r=n("4245");function i(t){var e=r(this,t)["delete"](t);return this.size-=e?1:0,e}t.exports=i},"950a":function(t,e,n){var r=n("30c9");function i(t,e){return function(n,i){if(null==n)return n;if(!r(n))return t(n,i);var a=n.length,o=e?a:-1,s=Object(n);while(e?o--:++o2?e[2]:void 0;c&&a(e[0],e[1],c)&&(r=1);while(++nl){var c=s;s=l,l=c}return s+o+l+o+(r.isUndefined(a)?i:a)}function h(t,e,n,r){var i=""+e,a=""+n;if(!t&&i>a){var o=i;i=a,a=o}var s={v:i,w:a};return r&&(s.name=r),s}function d(t,e){return u(t,e.v,e.w,e.name)}s.prototype._nodeCount=0,s.prototype._edgeCount=0,s.prototype.isDirected=function(){return this._isDirected},s.prototype.isMultigraph=function(){return this._isMultigraph},s.prototype.isCompound=function(){return this._isCompound},s.prototype.setGraph=function(t){return this._label=t,this},s.prototype.graph=function(){return this._label},s.prototype.setDefaultNodeLabel=function(t){return r.isFunction(t)||(t=r.constant(t)),this._defaultNodeLabelFn=t,this},s.prototype.nodeCount=function(){return this._nodeCount},s.prototype.nodes=function(){return r.keys(this._nodes)},s.prototype.sources=function(){var t=this;return r.filter(this.nodes(),(function(e){return r.isEmpty(t._in[e])}))},s.prototype.sinks=function(){var t=this;return r.filter(this.nodes(),(function(e){return r.isEmpty(t._out[e])}))},s.prototype.setNodes=function(t,e){var n=arguments,i=this;return r.each(t,(function(t){n.length>1?i.setNode(t,e):i.setNode(t)})),this},s.prototype.setNode=function(t,e){return r.has(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=a,this._children[t]={},this._children[a][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)},s.prototype.node=function(t){return this._nodes[t]},s.prototype.hasNode=function(t){return r.has(this._nodes,t)},s.prototype.removeNode=function(t){var e=this;if(r.has(this._nodes,t)){var n=function(t){e.removeEdge(e._edgeObjs[t])};delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],r.each(this.children(t),(function(t){e.setParent(t)})),delete this._children[t]),r.each(r.keys(this._in[t]),n),delete this._in[t],delete this._preds[t],r.each(r.keys(this._out[t]),n),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this},s.prototype.setParent=function(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(r.isUndefined(e))e=a;else{e+="";for(var n=e;!r.isUndefined(n);n=this.parent(n))if(n===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this},s.prototype._removeFromParentsChildList=function(t){delete this._children[this._parent[t]][t]},s.prototype.parent=function(t){if(this._isCompound){var e=this._parent[t];if(e!==a)return e}},s.prototype.children=function(t){if(r.isUndefined(t)&&(t=a),this._isCompound){var e=this._children[t];if(e)return r.keys(e)}else{if(t===a)return this.nodes();if(this.hasNode(t))return[]}},s.prototype.predecessors=function(t){var e=this._preds[t];if(e)return r.keys(e)},s.prototype.successors=function(t){var e=this._sucs[t];if(e)return r.keys(e)},s.prototype.neighbors=function(t){var e=this.predecessors(t);if(e)return r.union(e,this.successors(t))},s.prototype.isLeaf=function(t){var e;return e=this.isDirected()?this.successors(t):this.neighbors(t),0===e.length},s.prototype.filterNodes=function(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var n=this;r.each(this._nodes,(function(n,r){t(r)&&e.setNode(r,n)})),r.each(this._edgeObjs,(function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,n.edge(t))}));var i={};function a(t){var r=n.parent(t);return void 0===r||e.hasNode(r)?(i[t]=r,r):r in i?i[r]:a(r)}return this._isCompound&&r.each(e.nodes(),(function(t){e.setParent(t,a(t))})),e},s.prototype.setDefaultEdgeLabel=function(t){return r.isFunction(t)||(t=r.constant(t)),this._defaultEdgeLabelFn=t,this},s.prototype.edgeCount=function(){return this._edgeCount},s.prototype.edges=function(){return r.values(this._edgeObjs)},s.prototype.setPath=function(t,e){var n=this,i=arguments;return r.reduce(t,(function(t,r){return i.length>1?n.setEdge(t,r,e):n.setEdge(t,r),r})),this},s.prototype.setEdge=function(){var t,e,n,i,a=!1,o=arguments[0];"object"===typeof o&&null!==o&&"v"in o?(t=o.v,e=o.w,n=o.name,2===arguments.length&&(i=arguments[1],a=!0)):(t=o,e=arguments[1],n=arguments[3],arguments.length>2&&(i=arguments[2],a=!0)),t=""+t,e=""+e,r.isUndefined(n)||(n=""+n);var s=u(this._isDirected,t,e,n);if(r.has(this._edgeLabels,s))return a&&(this._edgeLabels[s]=i),this;if(!r.isUndefined(n)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[s]=a?i:this._defaultEdgeLabelFn(t,e,n);var c=h(this._isDirected,t,e,n);return t=c.v,e=c.w,Object.freeze(c),this._edgeObjs[s]=c,l(this._preds[e],t),l(this._sucs[t],e),this._in[e][s]=c,this._out[t][s]=c,this._edgeCount++,this},s.prototype.edge=function(t,e,n){var r=1===arguments.length?d(this._isDirected,arguments[0]):u(this._isDirected,t,e,n);return this._edgeLabels[r]},s.prototype.hasEdge=function(t,e,n){var i=1===arguments.length?d(this._isDirected,arguments[0]):u(this._isDirected,t,e,n);return r.has(this._edgeLabels,i)},s.prototype.removeEdge=function(t,e,n){var r=1===arguments.length?d(this._isDirected,arguments[0]):u(this._isDirected,t,e,n),i=this._edgeObjs[r];return i&&(t=i.v,e=i.w,delete this._edgeLabels[r],delete this._edgeObjs[r],c(this._preds[e],t),c(this._sucs[t],e),delete this._in[e][r],delete this._out[t][r],this._edgeCount--),this},s.prototype.inEdges=function(t,e){var n=this._in[t];if(n){var i=r.values(n);return e?r.filter(i,(function(t){return t.v===e})):i}},s.prototype.outEdges=function(t,e){var n=this._out[t];if(n){var i=r.values(n);return e?r.filter(i,(function(t){return t.w===e})):i}},s.prototype.nodeEdges=function(t,e){var n=this.inEdges(t,e);if(n)return n.concat(this.outEdges(t,e))}},"96cf":function(t,e,n){var r=function(t){"use strict";var e,n=Object.prototype,r=n.hasOwnProperty,i=Object.defineProperty||function(t,e,n){t[e]=n.value},a="function"===typeof Symbol?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",l=a.toStringTag||"@@toStringTag";function c(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{c({},"")}catch(M){c=function(t,e,n){return t[e]=n}}function u(t,e,n,r){var a=e&&e.prototype instanceof m?e:m,o=Object.create(a.prototype),s=new O(r||[]);return i(o,"_invoke",{value:_(t,n,s)}),o}function h(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(M){return{type:"throw",arg:M}}}t.wrap=u;var d="suspendedStart",f="suspendedYield",p="executing",v="completed",g={};function m(){}function y(){}function b(){}var x={};c(x,o,(function(){return this}));var w=Object.getPrototypeOf,k=w&&w(w(P([])));k&&k!==n&&r.call(k,o)&&(x=k);var S=b.prototype=m.prototype=Object.create(x);function C(t){["next","throw","return"].forEach((function(e){c(t,e,(function(t){return this._invoke(e,t)}))}))}function A(t,e){function n(i,a,o,s){var l=h(t[i],t,a);if("throw"!==l.type){var c=l.arg,u=c.value;return u&&"object"===typeof u&&r.call(u,"__await")?e.resolve(u.__await).then((function(t){n("next",t,o,s)}),(function(t){n("throw",t,o,s)})):e.resolve(u).then((function(t){c.value=t,o(c)}),(function(t){return n("throw",t,o,s)}))}s(l.arg)}var a;function o(t,r){function i(){return new e((function(e,i){n(t,r,e,i)}))}return a=a?a.then(i,i):i()}i(this,"_invoke",{value:o})}function _(t,e,n){var r=d;return function(i,a){if(r===p)throw new Error("Generator is already running");if(r===v){if("throw"===i)throw a;return I()}n.method=i,n.arg=a;while(1){var o=n.delegate;if(o){var s=D(o,n);if(s){if(s===g)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===d)throw r=v,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=p;var l=h(t,e,n);if("normal"===l.type){if(r=n.done?v:f,l.arg===g)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(r=v,n.method="throw",n.arg=l.arg)}}}function D(t,n){var r=n.method,i=t.iterator[r];if(i===e)return n.delegate=null,"throw"===r&&t.iterator["return"]&&(n.method="return",n.arg=e,D(t,n),"throw"===n.method)||"return"!==r&&(n.method="throw",n.arg=new TypeError("The iterator does not provide a '"+r+"' method")),g;var a=h(i,t.iterator,n.arg);if("throw"===a.type)return n.method="throw",n.arg=a.arg,n.delegate=null,g;var o=a.arg;return o?o.done?(n[t.resultName]=o.value,n.next=t.nextLoc,"return"!==n.method&&(n.method="next",n.arg=e),n.delegate=null,g):o:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,g)}function T(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function E(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function O(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(T,this),this.reset(!0)}function P(t){if(null!=t){var n=t[o];if(n)return n.call(t);if("function"===typeof t.next)return t;if(!isNaN(t.length)){var i=-1,a=function n(){while(++i=0;--a){var o=this.tryEntries[a],s=o.completion;if("root"===o.tryLoc)return i("end");if(o.tryLoc<=this.prev){var l=r.call(o,"catchLoc"),c=r.call(o,"finallyLoc");if(l&&c){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),E(n),g}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var i=r.arg;E(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,r){return this.delegate={iterator:P(t),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=e),g}},t}(t.exports);try{regeneratorRuntime=r}catch(i){"object"===typeof globalThis?globalThis.regeneratorRuntime=r:Function("r","regeneratorRuntime = r")(r)}},"96f3":function(t,e){var n=Object.prototype,r=n.hasOwnProperty;function i(t,e){return null!=t&&r.call(t,e)}t.exports=i},"97d3":function(t,e,n){var r=n("48a0"),i=n("30c9");function a(t,e){var n=-1,a=i(t)?Array(t.length):[];return r(t,(function(t,r,i){a[++n]=e(t,r,i)})),a}t.exports=a},"98dc":function(t,e,n){var r=n("76dd"),i=0;function a(t){var e=++i;return r(t)+e}t.exports=a},"990b":function(t,e,n){var r=n("9093"),i=n("2621"),a=n("cb7c"),o=n("7726").Reflect;t.exports=o&&o.ownKeys||function(t){var e=r.f(a(t)),n=i.f;return n?e.concat(n(t)):e}},9934:function(t,e,n){var r=n("6fcd"),i=n("41c3"),a=n("30c9");function o(t){return a(t)?r(t,!0):i(t)}t.exports=o},9948:function(t,e,n){var r=n("72af"),i=n("1304"),a=n("9934");function o(t,e){return null==t?t:r(t,i(e),a)}t.exports=o},"99cd":function(t,e){function n(t){return function(e,n,r){var i=-1,a=Object(e),o=r(e),s=o.length;while(s--){var l=o[t?s:++i];if(!1===n(a[l],l,a))break}return e}}t.exports=n},"99d3":function(t,e,n){(function(t){var r=n("585a"),i=e&&!e.nodeType&&e,a=i&&"object"==typeof t&&t&&!t.nodeType&&t,o=a&&a.exports===i,s=o&&r.process,l=function(){try{var t=a&&a.require&&a.require("util").types;return t||s&&s.binding&&s.binding("util")}catch(e){}}();t.exports=l}).call(this,n("62e4")(t))},"9aa9":function(t,e){e.f=Object.getOwnPropertySymbols},"9aff":function(t,e,n){var r=n("9638"),i=n("30c9"),a=n("c098"),o=n("1a8c");function s(t,e,n){if(!o(n))return!1;var s=typeof e;return!!("number"==s?i(n)&&a(e,n.length):"string"==s&&e in n)&&r(n[e],t)}t.exports=s},"9b02":function(t,e,n){var r=n("656b");function i(t,e,n){var i=null==t?void 0:r(t,e);return void 0===i?n:i}t.exports=i},"9b43":function(t,e,n){var r=n("d8e8");t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,i){return t.call(e,n,r,i)}}return function(){return t.apply(e,arguments)}}},"9c6c":function(t,e,n){var r=n("2b4c")("unscopables"),i=Array.prototype;void 0==i[r]&&n("32e9")(i,r,{}),t.exports=function(t){i[r][t]=!0}},"9c80":function(t,e){t.exports=function(t){try{return{e:!1,v:t()}}catch(e){return{e:!0,v:e}}}},"9def":function(t,e,n){var r=n("4588"),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},"9e1e":function(t,e,n){t.exports=!n("79e5")((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},"9e69":function(t,e,n){var r=n("2b3e"),i=r.Symbol;t.exports=i},"9e86":function(t,e,n){var r=n("872a"),i=n("242e"),a=n("badf");function o(t,e){var n={};return e=a(e,3),i(t,(function(t,i,a){r(n,i,e(t,i,a))})),n}t.exports=o},"9f74":function(t,e,n){var r=n("48a0");function i(t,e){var n=[];return r(t,(function(t,r,i){e(t,r,i)&&n.push(t)})),n}t.exports=i},a029:function(t,e,n){var r=n("087d"),i=n("2dcb"),a=n("32f4"),o=n("d327"),s=Object.getOwnPropertySymbols,l=s?function(t){var e=[];while(t)r(e,a(t)),t=i(t);return e}:o;t.exports=l},a159:function(t,e,n){var r=n("e4ae"),i=n("7e90"),a=n("1691"),o=n("5559")("IE_PROTO"),s=function(){},l="prototype",c=function(){var t,e=n("1ec9")("iframe"),r=a.length,i="<",o=">";e.style.display="none",n("32fc").appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(i+"script"+o+"document.F=Object"+i+"/script"+o),t.close(),c=t.F;while(r--)delete c[l][a[r]];return c()};t.exports=Object.create||function(t,e){var n;return null!==t?(s[l]=r(t),n=new s,s[l]=null,n[o]=t):n=c(),void 0===e?n:i(n,e)}},a22a:function(t,e,n){var r=n("d864"),i=n("b0dc"),a=n("3702"),o=n("e4ae"),s=n("b447"),l=n("7cd6"),c={},u={};e=t.exports=function(t,e,n,h,d){var f,p,v,g,m=d?function(){return t}:l(t),y=r(n,h,e?2:1),b=0;if("function"!=typeof m)throw TypeError(t+" is not iterable!");if(a(m)){for(f=s(t.length);f>b;b++)if(g=e?y(o(p=t[b])[0],p[1]):y(t[b]),g===c||g===u)return g}else for(v=m.call(t);!(p=v.next()).done;)if(g=i(v,y,p.value,e),g===c||g===u)return g};e.BREAK=c,e.RETURN=u},a25f:function(t,e,n){var r=n("7726"),i=r.navigator;t.exports=i&&i.userAgent||""},a2be:function(t,e,n){var r=n("d612"),i=n("4284"),a=n("c584"),o=1,s=2;function l(t,e,n,l,c,u){var h=n&o,d=t.length,f=e.length;if(d!=f&&!(h&&f>d))return!1;var p=u.get(t),v=u.get(e);if(p&&v)return p==e&&v==t;var g=-1,m=!0,y=n&s?new r:void 0;u.set(t,e),u.set(e,t);while(++g0){if(a=l.removeMin(),o=s[a],o.distance===Number.POSITIVE_INFINITY)break;r(a).forEach(c)}return s}},a481:function(t,e,n){"use strict";var r=n("cb7c"),i=n("4bf8"),a=n("9def"),o=n("4588"),s=n("0390"),l=n("5f1b"),c=Math.max,u=Math.min,h=Math.floor,d=/\$([$&`']|\d\d?|<[^>]*>)/g,f=/\$([$&`']|\d\d?)/g,p=function(t){return void 0===t?t:String(t)};n("214f")("replace",2,(function(t,e,n,v){return[function(r,i){var a=t(this),o=void 0==r?void 0:r[e];return void 0!==o?o.call(r,a,i):n.call(String(a),r,i)},function(t,e){var i=v(n,t,this,e);if(i.done)return i.value;var h=r(t),d=String(this),f="function"===typeof e;f||(e=String(e));var m=h.global;if(m){var y=h.unicode;h.lastIndex=0}var b=[];while(1){var x=l(h,d);if(null===x)break;if(b.push(x),!m)break;var w=String(x[0]);""===w&&(h.lastIndex=s(d,a(h.lastIndex),y))}for(var k="",S=0,C=0;C=S&&(k+=d.slice(S,_)+P,S=_+A.length)}return k+d.slice(S)}];function g(t,e,r,a,o,s){var l=r+t.length,c=a.length,u=f;return void 0!==o&&(o=i(o),u=d),n.call(s,u,(function(n,i){var s;switch(i.charAt(0)){case"$":return"$";case"&":return t;case"`":return e.slice(0,r);case"'":return e.slice(l);case"<":s=o[i.slice(1,-1)];break;default:var u=+i;if(0===u)return n;if(u>c){var d=h(u/10);return 0===d?n:d<=c?void 0===a[d-1]?i.charAt(1):a[d-1]+i.charAt(1):n}s=a[u-1]}return void 0===s?"":s}))}}))},a524:function(t,e,n){var r=n("4245");function i(t){return r(this,t).has(t)}t.exports=i},a5b8:function(t,e,n){"use strict";var r=n("d8e8");function i(t){var e,n;this.promise=new t((function(t,r){if(void 0!==e||void 0!==n)throw TypeError("Bad Promise constructor");e=t,n=r})),this.resolve=r(e),this.reject=r(n)}t.exports.f=function(t){return new i(t)}},a6d1:function(t,e,n){"use strict";var r=n("6f9c"),i=n("299f");function a(t){var e="greedy"===t.graph().acyclicer?i(t,n(t)):o(t);function n(t){return function(e){return t.edge(e).weight}}r.forEach(e,(function(e){var n=t.edge(e);t.removeEdge(e),n.forwardName=e.name,n.reversed=!0,t.setEdge(e.w,e.v,n,r.uniqueId("rev"))}))}function o(t){var e=[],n={},i={};function a(o){r.has(i,o)||(i[o]=!0,n[o]=!0,r.forEach(t.outEdges(o),(function(t){r.has(n,t.w)?e.push(t):a(t.w)})),delete n[o])}return r.forEach(t.nodes(),a),e}function s(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(n.reversed){t.removeEdge(e);var r=n.forwardName;delete n.reversed,delete n.forwardName,t.setEdge(e.w,e.v,n,r)}}))}t.exports={run:a,undo:s}},a864:function(t,e,n){"use strict";var r=n("6f9c");function i(t){var e=t.graph().rankdir.toLowerCase();"lr"!==e&&"rl"!==e||o(t)}function a(t){var e=t.graph().rankdir.toLowerCase();"bt"!==e&&"rl"!==e||l(t),"lr"!==e&&"rl"!==e||(u(t),o(t))}function o(t){r.forEach(t.nodes(),(function(e){s(t.node(e))})),r.forEach(t.edges(),(function(e){s(t.edge(e))}))}function s(t){var e=t.width;t.width=t.height,t.height=e}function l(t){r.forEach(t.nodes(),(function(e){c(t.node(e))})),r.forEach(t.edges(),(function(e){var n=t.edge(e);r.forEach(n.points,c),r.has(n,"y")&&c(n)}))}function c(t){t.y=-t.y}function u(t){r.forEach(t.nodes(),(function(e){h(t.node(e))})),r.forEach(t.edges(),(function(e){var n=t.edge(e);r.forEach(n.points,h),r.has(n,"x")&&h(n)}))}function h(t){var e=t.x;t.x=t.y,t.y=e}t.exports={adjust:i,undo:a}},a994:function(t,e,n){var r=n("7d1f"),i=n("32f4"),a=n("ec69");function o(t){return r(t,a,i)}t.exports=o},aa77:function(t,e,n){var r=n("5ca1"),i=n("be13"),a=n("79e5"),o=n("fdef"),s="["+o+"]",l="​…",c=RegExp("^"+s+s+"*"),u=RegExp(s+s+"*$"),h=function(t,e,n){var i={},s=a((function(){return!!o[t]()||l[t]()!=l})),c=i[t]=s?e(d):o[t];n&&(i[n]=c),r(r.P+r.F*s,"String",i)},d=h.trim=function(t,e){return t=String(i(t)),1&e&&(t=t.replace(c,"")),2&e&&(t=t.replace(u,"")),t};t.exports=h},aae3:function(t,e,n){var r=n("d3f4"),i=n("2d95"),a=n("2b4c")("match");t.exports=function(t){var e;return r(t)&&(void 0!==(e=t[a])?!!e:"RegExp"==i(t))}},aaec:function(t,e){var n="\\ud800-\\udfff",r="\\u0300-\\u036f",i="\\ufe20-\\ufe2f",a="\\u20d0-\\u20ff",o=r+i+a,s="\\ufe0e\\ufe0f",l="\\u200d",c=RegExp("["+l+n+o+s+"]");function u(t){return c.test(t)}t.exports=u},aaf9:function(t,e,n){var r=n("df2e");function i(t,e){return r(t,e,"pre")}t.exports=i},ab81:function(t,e){var n="\\ud800-\\udfff",r="\\u0300-\\u036f",i="\\ufe20-\\ufe2f",a="\\u20d0-\\u20ff",o=r+i+a,s="\\ufe0e\\ufe0f",l="["+n+"]",c="["+o+"]",u="\\ud83c[\\udffb-\\udfff]",h="(?:"+c+"|"+u+")",d="[^"+n+"]",f="(?:\\ud83c[\\udde6-\\uddff]){2}",p="[\\ud800-\\udbff][\\udc00-\\udfff]",v="\\u200d",g=h+"?",m="["+s+"]?",y="(?:"+v+"(?:"+[d,f,p].join("|")+")"+m+g+")*",b=m+g+y,x="(?:"+[d+c+"?",c,f,p,l].join("|")+")",w=RegExp(u+"(?="+u+")|"+x+b,"g");function k(t){var e=w.lastIndex=0;while(w.test(t))++e;return e}t.exports=k},aba2:function(t,e,n){var r=n("e53d"),i=n("4178").set,a=r.MutationObserver||r.WebKitMutationObserver,o=r.process,s=r.Promise,l="process"==n("6b4c")(o);t.exports=function(){var t,e,n,c=function(){var r,i;l&&(r=o.domain)&&r.exit();while(t){i=t.fn,t=t.next;try{i()}catch(a){throw t?n():e=void 0,a}}e=void 0,r&&r.enter()};if(l)n=function(){o.nextTick(c)};else if(!a||r.navigator&&r.navigator.standalone)if(s&&s.resolve){var u=s.resolve(void 0);n=function(){u.then(c)}}else n=function(){i.call(r,c)};else{var h=!0,d=document.createTextNode("");new a(c).observe(d,{characterData:!0}),n=function(){d.data=h=!h}}return function(r){var i={fn:r,next:void 0};e&&(e.next=i),t||(t=i,n()),e=i}}},abdd:function(t,e,n){var r=n("76e9"),i=n("57dc"),a=n("cd9d");function o(t){return t&&t.length?r(t,a,i):void 0}t.exports=o},ac41:function(t,e){function n(t){var e=-1,n=Array(t.size);return t.forEach((function(t){n[++e]=t})),n}t.exports=n},ac4d:function(t,e,n){n("3a72")("asyncIterator")},ac6a:function(t,e,n){for(var r=n("cadf"),i=n("0d58"),a=n("2aba"),o=n("7726"),s=n("32e9"),l=n("84f2"),c=n("2b4c"),u=c("iterator"),h=c("toStringTag"),d=l.Array,f={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},p=i(f),v=0;v1?arguments[1]:void 0,r=i(e.length),l=void 0===n?r:Math.min(i(n),r),c=String(t);return s?s.call(e,c,l):e.slice(l-c.length,l)===c}})},b047:function(t,e){function n(t){return function(e){return t(e)}}t.exports=n},b0c5:function(t,e,n){"use strict";var r=n("520a");n("5ca1")({target:"RegExp",proto:!0,forced:r!==/./.exec},{exec:r})},b0dc:function(t,e,n){var r=n("e4ae");t.exports=function(t,e,n,i){try{return i?e(r(n)[0],n[1]):e(n)}catch(o){var a=t["return"];throw void 0!==a&&r(a.call(t)),o}}},b17d:function(t,e,n){(function(e,r){t.exports=r(n("e34f"))})(0,(function(t){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"===typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){var r=n(1),i=function(t){t&&t("layout","dagre",r)};"undefined"!==typeof cytoscape&&i(cytoscape),t.exports=i},function(t,e,n){function r(t){return r="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}var i=function(t){return"function"===typeof t},a=n(2),o=n(3),s=n(4);function l(t){this.options=o({},a,t)}l.prototype.run=function(){var t=this.options,e=this,n=t.cy,a=t.eles,o=function(t,e){return i(e)?e.apply(t,[t]):e},l=t.boundingBox||{x1:0,y1:0,w:n.width(),h:n.height()};void 0===l.x2&&(l.x2=l.x1+l.w),void 0===l.w&&(l.w=l.x2-l.x1),void 0===l.y2&&(l.y2=l.y1+l.h),void 0===l.h&&(l.h=l.y2-l.y1);var c=new s.graphlib.Graph({multigraph:!0,compound:!0}),u={},h=function(t,e){null!=e&&(u[t]=e)};h("nodesep",t.nodeSep),h("edgesep",t.edgeSep),h("ranksep",t.rankSep),h("rankdir",t.rankDir),h("align",t.align),h("ranker",t.ranker),h("acyclicer",t.acyclicer),c.setGraph(u),c.setDefaultEdgeLabel((function(){return{}})),c.setDefaultNodeLabel((function(){return{}}));var d=a.nodes();i(t.sort)&&(d=d.sort(t.sort));for(var f=0;f1?e-1:0),r=1;r-1&&t%1==0&&t<=n}t.exports=r},b39a:function(t,e,n){var r=n("d3f4");t.exports=function(t,e){if(!r(t)||t._t!==e)throw TypeError("Incompatible receiver, "+e+" required!");return t}},b447:function(t,e,n){var r=n("3a38"),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},b4b0:function(t,e,n){var r=n("8d74"),i=n("1a8c"),a=n("ffd6"),o=NaN,s=/^[-+]0x[0-9a-f]+$/i,l=/^0b[01]+$/i,c=/^0o[0-7]+$/i,u=parseInt;function h(t){if("number"==typeof t)return t;if(a(t))return o;if(i(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=i(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=r(t);var n=l.test(t);return n||c.test(t)?u(t.slice(2),n?2:8):s.test(t)?o:+t}t.exports=h},b4c0:function(t,e,n){var r=n("cb5a");function i(t){var e=this.__data__,n=r(e,t);return n<0?void 0:e[n][1]}t.exports=i},b50e:function(t,e,n){"use strict";var r=n("6f9c"),i=n("17d5").Graph;function a(t,e,n,i){var a;do{a=r.uniqueId(i)}while(t.hasNode(a));return n.dummy=e,t.setNode(a,n),a}function o(t){var e=(new i).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){var r=e.edge(n.v,n.w)||{weight:0,minlen:1},i=t.edge(n);e.setEdge(n.v,n.w,{weight:r.weight+i.weight,minlen:Math.max(r.minlen,i.minlen)})})),e}function s(t){var e=new i({multigraph:t.isMultigraph()}).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){t.children(n).length||e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){e.setEdge(n,t.edge(n))})),e}function l(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.outEdges(e),(function(e){n[e.w]=(n[e.w]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)}function c(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.inEdges(e),(function(e){n[e.v]=(n[e.v]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)}function u(t,e){var n,r,i=t.x,a=t.y,o=e.x-i,s=e.y-a,l=t.width/2,c=t.height/2;if(!o&&!s)throw new Error("Not possible to find intersection inside of the rectangle");return Math.abs(s)*l>Math.abs(o)*c?(s<0&&(c=-c),n=c*o/s,r=c):(o<0&&(l=-l),n=l,r=l*s/o),{x:i+n,y:a+r}}function h(t){var e=r.map(r.range(v(t)+1),(function(){return[]}));return r.forEach(t.nodes(),(function(n){var i=t.node(n),a=i.rank;r.isUndefined(a)||(e[a][i.order]=n)})),e}function d(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank})));r.forEach(t.nodes(),(function(n){var i=t.node(n);r.has(i,"rank")&&(i.rank-=e)}))}function f(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank}))),n=[];r.forEach(t.nodes(),(function(r){var i=t.node(r).rank-e;n[i]||(n[i]=[]),n[i].push(r)}));var i=0,a=t.graph().nodeRankFactor;r.forEach(n,(function(e,n){r.isUndefined(e)&&n%a!==0?--i:i&&r.forEach(e,(function(e){t.node(e).rank+=i}))}))}function p(t,e,n,r){var i={width:0,height:0};return arguments.length>=4&&(i.rank=n,i.order=r),a(t,"border",i,e)}function v(t){return r.max(r.map(t.nodes(),(function(e){var n=t.node(e).rank;if(!r.isUndefined(n))return n})))}function g(t,e){var n={lhs:[],rhs:[]};return r.forEach(t,(function(t){e(t)?n.lhs.push(t):n.rhs.push(t)})),n}function m(t,e){var n=r.now();try{return e()}finally{console.log(t+" time: "+(r.now()-n)+"ms")}}function y(t,e){return e()}t.exports={addDummyNode:a,simplify:o,asNonCompoundGraph:s,successorWeights:l,predecessorWeights:c,intersectRect:u,buildLayerMatrix:h,normalizeRanks:d,removeEmptyRanks:f,addBorderNode:p,maxRank:v,partition:g,time:m,notime:y}},b5a7:function(t,e,n){var r=n("0b07"),i=n("2b3e"),a=r(i,"DataView");t.exports=a},b639:function(t,e,n){"use strict";(function(t){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +var r=n("1fb5"),i=n("9152"),a=n("e3db");function o(){try{var t=new Uint8Array(1);return t.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===t.foo()&&"function"===typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(e){return!1}}function s(){return c.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function l(t,e){if(s()=s())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s().toString(16)+" bytes");return 0|t}function b(t){return+t!=t&&(t=0),c.alloc(+t)}function x(t,e){if(c.isBuffer(t))return t.length;if("undefined"!==typeof ArrayBuffer&&"function"===typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!==typeof t&&(t=""+t);var n=t.length;if(0===n)return 0;for(var r=!1;;)switch(e){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return Z(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return Q(t).length;default:if(r)return Z(t).length;e=(""+e).toLowerCase(),r=!0}}function w(t,e,n){var r=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if(n>>>=0,e>>>=0,n<=e)return"";t||(t="utf8");while(1)switch(t){case"hex":return B(this,e,n);case"utf8":case"utf-8":return I(this,e,n);case"ascii":return L(this,e,n);case"latin1":case"binary":return j(this,e,n);case"base64":return P(this,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,e,n);default:if(r)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),r=!0}}function k(t,e,n){var r=t[e];t[e]=t[n],t[n]=r}function S(t,e,n,r,i){if(0===t.length)return-1;if("string"===typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:t.length-1),n<0&&(n=t.length+n),n>=t.length){if(i)return-1;n=t.length-1}else if(n<0){if(!i)return-1;n=0}if("string"===typeof e&&(e=c.from(e,r)),c.isBuffer(e))return 0===e.length?-1:C(t,e,n,r,i);if("number"===typeof e)return e&=255,c.TYPED_ARRAY_SUPPORT&&"function"===typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,n):Uint8Array.prototype.lastIndexOf.call(t,e,n):C(t,[e],n,r,i);throw new TypeError("val must be string, number or Buffer")}function C(t,e,n,r,i){var a,o=1,s=t.length,l=e.length;if(void 0!==r&&(r=String(r).toLowerCase(),"ucs2"===r||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(t.length<2||e.length<2)return-1;o=2,s/=2,l/=2,n/=2}function c(t,e){return 1===o?t[e]:t.readUInt16BE(e*o)}if(i){var u=-1;for(a=n;as&&(n=s-l),a=n;a>=0;a--){for(var h=!0,d=0;di&&(r=i)):r=i;var a=e.length;if(a%2!==0)throw new TypeError("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o239?4:c>223?3:c>191?2:1;if(i+h<=n)switch(h){case 1:c<128&&(u=c);break;case 2:a=t[i+1],128===(192&a)&&(l=(31&c)<<6|63&a,l>127&&(u=l));break;case 3:a=t[i+1],o=t[i+2],128===(192&a)&&128===(192&o)&&(l=(15&c)<<12|(63&a)<<6|63&o,l>2047&&(l<55296||l>57343)&&(u=l));break;case 4:a=t[i+1],o=t[i+2],s=t[i+3],128===(192&a)&&128===(192&o)&&128===(192&s)&&(l=(15&c)<<18|(63&a)<<12|(63&o)<<6|63&s,l>65535&&l<1114112&&(u=l))}null===u?(u=65533,h=1):u>65535&&(u-=65536,r.push(u>>>10&1023|55296),u=56320|1023&u),r.push(u),i+=h}return V(r)}e.Buffer=c,e.SlowBuffer=b,e.INSPECT_MAX_BYTES=50,c.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:o(),e.kMaxLength=s(),c.poolSize=8192,c._augment=function(t){return t.__proto__=c.prototype,t},c.from=function(t,e,n){return u(null,t,e,n)},c.TYPED_ARRAY_SUPPORT&&(c.prototype.__proto__=Uint8Array.prototype,c.__proto__=Uint8Array,"undefined"!==typeof Symbol&&Symbol.species&&c[Symbol.species]===c&&Object.defineProperty(c,Symbol.species,{value:null,configurable:!0})),c.alloc=function(t,e,n){return d(null,t,e,n)},c.allocUnsafe=function(t){return f(null,t)},c.allocUnsafeSlow=function(t){return f(null,t)},c.isBuffer=function(t){return!(null==t||!t._isBuffer)},c.compare=function(t,e){if(!c.isBuffer(t)||!c.isBuffer(e))throw new TypeError("Arguments must be Buffers");if(t===e)return 0;for(var n=t.length,r=e.length,i=0,a=Math.min(n,r);i0&&(t=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(t+=" ... ")),""},c.prototype.compare=function(t,e,n,r,i){if(!c.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===n&&(n=t?t.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),e<0||n>t.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&e>=n)return 0;if(r>=i)return-1;if(e>=n)return 1;if(e>>>=0,n>>>=0,r>>>=0,i>>>=0,this===t)return 0;for(var a=i-r,o=n-e,s=Math.min(a,o),l=this.slice(r,i),u=t.slice(e,n),h=0;hi)&&(n=i),t.length>0&&(n<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return A(this,t,e,n);case"utf8":case"utf-8":return _(this,t,e,n);case"ascii":return D(this,t,e,n);case"latin1":case"binary":return T(this,t,e,n);case"base64":return E(this,t,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,e,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var M=4096;function V(t){var e=t.length;if(e<=M)return String.fromCharCode.apply(String,t);var n="",r=0;while(rr)&&(n=r);for(var i="",a=e;an)throw new RangeError("Trying to access beyond buffer length")}function N(t,e,n,r,i,a){if(!c.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||et.length)throw new RangeError("Index out of range")}function z(t,e,n,r){e<0&&(e=65535+e+1);for(var i=0,a=Math.min(t.length-n,2);i>>8*(r?i:1-i)}function $(t,e,n,r){e<0&&(e=4294967295+e+1);for(var i=0,a=Math.min(t.length-n,4);i>>8*(r?i:3-i)&255}function Y(t,e,n,r,i,a){if(n+r>t.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function H(t,e,n,r,a){return a||Y(t,e,n,4,34028234663852886e22,-34028234663852886e22),i.write(t,e,n,r,23,4),n+4}function W(t,e,n,r,a){return a||Y(t,e,n,8,17976931348623157e292,-17976931348623157e292),i.write(t,e,n,r,52,8),n+8}c.prototype.slice=function(t,e){var n,r=this.length;if(t=~~t,e=void 0===e?r:~~e,t<0?(t+=r,t<0&&(t=0)):t>r&&(t=r),e<0?(e+=r,e<0&&(e=0)):e>r&&(e=r),e0&&(i*=256))r+=this[t+--e]*i;return r},c.prototype.readUInt8=function(t,e){return e||F(t,1,this.length),this[t]},c.prototype.readUInt16LE=function(t,e){return e||F(t,2,this.length),this[t]|this[t+1]<<8},c.prototype.readUInt16BE=function(t,e){return e||F(t,2,this.length),this[t]<<8|this[t+1]},c.prototype.readUInt32LE=function(t,e){return e||F(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},c.prototype.readUInt32BE=function(t,e){return e||F(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},c.prototype.readIntLE=function(t,e,n){t|=0,e|=0,n||F(t,e,this.length);var r=this[t],i=1,a=0;while(++a=i&&(r-=Math.pow(2,8*e)),r},c.prototype.readIntBE=function(t,e,n){t|=0,e|=0,n||F(t,e,this.length);var r=e,i=1,a=this[t+--r];while(r>0&&(i*=256))a+=this[t+--r]*i;return i*=128,a>=i&&(a-=Math.pow(2,8*e)),a},c.prototype.readInt8=function(t,e){return e||F(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},c.prototype.readInt16LE=function(t,e){e||F(t,2,this.length);var n=this[t]|this[t+1]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt16BE=function(t,e){e||F(t,2,this.length);var n=this[t+1]|this[t]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt32LE=function(t,e){return e||F(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},c.prototype.readInt32BE=function(t,e){return e||F(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},c.prototype.readFloatLE=function(t,e){return e||F(t,4,this.length),i.read(this,t,!0,23,4)},c.prototype.readFloatBE=function(t,e){return e||F(t,4,this.length),i.read(this,t,!1,23,4)},c.prototype.readDoubleLE=function(t,e){return e||F(t,8,this.length),i.read(this,t,!0,52,8)},c.prototype.readDoubleBE=function(t,e){return e||F(t,8,this.length),i.read(this,t,!1,52,8)},c.prototype.writeUIntLE=function(t,e,n,r){if(t=+t,e|=0,n|=0,!r){var i=Math.pow(2,8*n)-1;N(this,t,e,n,i,0)}var a=1,o=0;this[e]=255&t;while(++o=0&&(o*=256))this[e+a]=t/o&255;return e+n},c.prototype.writeUInt8=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,1,255,0),c.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},c.prototype.writeUInt16LE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):z(this,t,e,!0),e+2},c.prototype.writeUInt16BE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):z(this,t,e,!1),e+2},c.prototype.writeUInt32LE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):$(this,t,e,!0),e+4},c.prototype.writeUInt32BE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):$(this,t,e,!1),e+4},c.prototype.writeIntLE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);N(this,t,e,n,i-1,-i)}var a=0,o=1,s=0;this[e]=255&t;while(++a>0)-s&255;return e+n},c.prototype.writeIntBE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);N(this,t,e,n,i-1,-i)}var a=n-1,o=1,s=0;this[e+a]=255&t;while(--a>=0&&(o*=256))t<0&&0===s&&0!==this[e+a+1]&&(s=1),this[e+a]=(t/o>>0)-s&255;return e+n},c.prototype.writeInt8=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,1,127,-128),c.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},c.prototype.writeInt16LE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):z(this,t,e,!0),e+2},c.prototype.writeInt16BE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):z(this,t,e,!1),e+2},c.prototype.writeInt32LE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):$(this,t,e,!0),e+4},c.prototype.writeInt32BE=function(t,e,n){return t=+t,e|=0,n||N(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),c.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):$(this,t,e,!1),e+4},c.prototype.writeFloatLE=function(t,e,n){return H(this,t,e,!0,n)},c.prototype.writeFloatBE=function(t,e,n){return H(this,t,e,!1,n)},c.prototype.writeDoubleLE=function(t,e,n){return W(this,t,e,!0,n)},c.prototype.writeDoubleBE=function(t,e,n){return W(this,t,e,!1,n)},c.prototype.copy=function(t,e,n,r){if(n||(n=0),r||0===r||(r=this.length),e>=t.length&&(e=t.length),e||(e=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),t.length-e=0;--i)t[i+e]=this[i+n];else if(a<1e3||!c.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,n=void 0===n?this.length:n>>>0,t||(t=0),"number"===typeof t)for(a=e;a55295&&n<57344){if(!i){if(n>56319){(e-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(e-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(e-=3)>-1&&a.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(e-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((e-=1)<0)break;a.push(n)}else if(n<2048){if((e-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((e-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function K(t){for(var e=[],n=0;n>8,i=n%256,a.push(i),a.push(r)}return a}function Q(t){return r.toByteArray(G(t))}function tt(t,e,n,r){for(var i=0;i=e.length||i>=t.length)break;e[i+n]=t[i]}return i}function et(t){return t!==t}}).call(this,n("c8ba"))},b760:function(t,e,n){var r=n("872a"),i=n("9638");function a(t,e,n){(void 0!==n&&!i(t[e],n)||void 0===n&&!(e in t))&&r(t,e,n)}t.exports=a},b8ce:function(t,e,n){var r=n("3818"),i=4;function a(t){return r(t,i)}t.exports=a},b8e3:function(t,e){t.exports=!0},badf:function(t,e,n){var r=n("642a"),i=n("1838"),a=n("cd9d"),o=n("6747"),s=n("f9ce");function l(t){return"function"==typeof t?t:null==t?a:"object"==typeof t?o(t)?i(t[0],t[1]):r(t):s(t)}t.exports=l},bbc0:function(t,e,n){var r=n("6044"),i="__lodash_hash_undefined__",a=Object.prototype,o=a.hasOwnProperty;function s(t){var e=this.__data__;if(r){var n=e[t];return n===i?void 0:n}return o.call(e,t)?e[t]:void 0}t.exports=s},bc13:function(t,e,n){var r=n("e53d"),i=r.navigator;t.exports=i&&i.userAgent||""},bcaa:function(t,e,n){var r=n("cb7c"),i=n("d3f4"),a=n("a5b8");t.exports=function(t,e){if(r(t),i(e)&&e.constructor===t)return e;var n=a.f(t),o=n.resolve;return o(e),n.promise}},bcdf:function(t,e){function n(){}t.exports=n},bd86:function(t,e,n){"use strict";n.d(e,"a",(function(){return u}));var r=n("454f"),i=n.n(r),a=n("7618"),o=n("366e"),s=n.n(o);function l(t,e){if("object"!=Object(a["a"])(t)||!t)return t;var n=t[s.a];if(void 0!==n){var r=n.call(t,e||"default");if("object"!=Object(a["a"])(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}function c(t){var e=l(t,"string");return"symbol"==Object(a["a"])(e)?e:e+""}function u(t,e,n){return(e=c(e))in t?i()(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}},be13:function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},bf0b:function(t,e,n){var r=n("355d"),i=n("aebd"),a=n("36c3"),o=n("1bc3"),s=n("07e3"),l=n("794b"),c=Object.getOwnPropertyDescriptor;e.f=n("8e60")?c:function(t,e){if(t=a(t),e=o(e,!0),l)try{return c(t,e)}catch(n){}if(s(t,e))return i(!r.f.call(t,e),t[e])}},bf40:function(t,e,n){},bfc7:function(t,e,n){var r=n("5c69"),i=n("100e"),a=n("2c66"),o=n("dcbe"),s=i((function(t){return a(r(t,1,o,!0))}));t.exports=s},c05f:function(t,e,n){var r=n("7b97"),i=n("1310");function a(t,e,n,o,s){return t===e||(null==t||null==e||!i(t)&&!i(e)?t!==t&&e!==e:r(t,e,n,o,a,s))}t.exports=a},c098:function(t,e){var n=9007199254740991,r=/^(?:0|[1-9]\d*)$/;function i(t,e){var i=typeof t;return e=null==e?n:e,!!e&&("number"==i||"symbol"!=i&&r.test(t))&&t>-1&&t%1==0&&t1?n-1:0),i=1;i2&&void 0!==arguments[2]?arguments[2]:v;e&&e(t,null);let a=r.length;while(a--){let e=r[a];if("string"===typeof e){const t=i(e);t!==e&&(n(r)||(r[a]=t),e=t)}t[e]=!0}return t}function D(t){for(let e=0;e/gm),Y=o(/\$\{[\w\W]*/gm),H=o(/^data-[\-\w.\u00B7-\uFFFF]+$/),W=o(/^aria-[\-\w]+$/),X=o(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),G=o(/^(?:\w+script|data):/i),U=o(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),q=o(/^html$/i),Z=o(/^[a-z][.\w]*(-[.\w]+)+$/i);var K=Object.freeze({__proto__:null,ARIA_ATTR:W,ATTR_WHITESPACE:U,CUSTOM_ELEMENT:Z,DATA_ATTR:H,DOCTYPE_NAME:q,ERB_EXPR:$,IS_ALLOWED_URI:X,IS_SCRIPT_OR_DATA:G,MUSTACHE_EXPR:z,TMPLIT_EXPR:Y});const J={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},Q=function(){return"undefined"===typeof window?null:window},tt=function(t,e){if("object"!==typeof t||"function"!==typeof t.createPolicy)return null;let n=null;const r="data-tt-policy-suffix";e&&e.hasAttribute(r)&&(n=e.getAttribute(r));const i="dompurify"+(n?"#"+n:"");try{return t.createPolicy(i,{createHTML(t){return t},createScriptURL(t){return t}})}catch(a){return console.warn("TrustedTypes policy "+i+" could not be created."),null}},et=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}};function nt(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Q();const n=t=>nt(t);if(n.version="3.2.4",n.removed=[],!e||!e.document||e.document.nodeType!==J.document||!e.Element)return n.isSupported=!1,n;let{document:r}=e;const i=r,o=i.currentScript,{DocumentFragment:l,HTMLTemplateElement:c,Node:C,Element:A,NodeFilter:D,NamedNodeMap:z=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:$,DOMParser:Y,trustedTypes:H}=e,W=A.prototype,G=E(W,"cloneNode"),U=E(W,"remove"),Z=E(W,"nextSibling"),rt=E(W,"childNodes"),it=E(W,"parentNode");if("function"===typeof c){const t=r.createElement("template");t.content&&t.content.ownerDocument&&(r=t.content.ownerDocument)}let at,ot="";const{implementation:st,createNodeIterator:lt,createDocumentFragment:ct,getElementsByTagName:ut}=r,{importNode:ht}=i;let dt=et();n.isSupported="function"===typeof t&&"function"===typeof it&&st&&void 0!==st.createHTMLDocument;const{MUSTACHE_EXPR:ft,ERB_EXPR:pt,TMPLIT_EXPR:vt,DATA_ATTR:gt,ARIA_ATTR:mt,IS_SCRIPT_OR_DATA:yt,ATTR_WHITESPACE:bt,CUSTOM_ELEMENT:xt}=K;let{IS_ALLOWED_URI:wt}=K,kt=null;const St=_({},[...O,...P,...I,...V,...j]);let Ct=null;const At=_({},[...B,...R,...F,...N]);let _t=Object.seal(s(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Dt=null,Tt=null,Et=!0,Ot=!0,Pt=!1,It=!0,Mt=!1,Vt=!0,Lt=!1,jt=!1,Bt=!1,Rt=!1,Ft=!1,Nt=!1,zt=!0,$t=!1;const Yt="user-content-";let Ht=!0,Wt=!1,Xt={},Gt=null;const Ut=_({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let qt=null;const Zt=_({},["audio","video","img","source","image","track"]);let Kt=null;const Jt=_({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Qt="http://www.w3.org/1998/Math/MathML",te="http://www.w3.org/2000/svg",ee="http://www.w3.org/1999/xhtml";let ne=ee,re=!1,ie=null;const ae=_({},[Qt,te,ee],g);let oe=_({},["mi","mo","mn","ms","mtext"]),se=_({},["annotation-xml"]);const le=_({},["title","style","font","a","script"]);let ce=null;const ue=["application/xhtml+xml","text/html"],he="text/html";let de=null,fe=null;const pe=r.createElement("form"),ve=function(t){return t instanceof RegExp||t instanceof Function},ge=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!fe||fe!==t){if(t&&"object"===typeof t||(t={}),t=T(t),ce=-1===ue.indexOf(t.PARSER_MEDIA_TYPE)?he:t.PARSER_MEDIA_TYPE,de="application/xhtml+xml"===ce?g:v,kt=w(t,"ALLOWED_TAGS")?_({},t.ALLOWED_TAGS,de):St,Ct=w(t,"ALLOWED_ATTR")?_({},t.ALLOWED_ATTR,de):At,ie=w(t,"ALLOWED_NAMESPACES")?_({},t.ALLOWED_NAMESPACES,g):ae,Kt=w(t,"ADD_URI_SAFE_ATTR")?_(T(Jt),t.ADD_URI_SAFE_ATTR,de):Jt,qt=w(t,"ADD_DATA_URI_TAGS")?_(T(Zt),t.ADD_DATA_URI_TAGS,de):Zt,Gt=w(t,"FORBID_CONTENTS")?_({},t.FORBID_CONTENTS,de):Ut,Dt=w(t,"FORBID_TAGS")?_({},t.FORBID_TAGS,de):{},Tt=w(t,"FORBID_ATTR")?_({},t.FORBID_ATTR,de):{},Xt=!!w(t,"USE_PROFILES")&&t.USE_PROFILES,Et=!1!==t.ALLOW_ARIA_ATTR,Ot=!1!==t.ALLOW_DATA_ATTR,Pt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,It=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,Mt=t.SAFE_FOR_TEMPLATES||!1,Vt=!1!==t.SAFE_FOR_XML,Lt=t.WHOLE_DOCUMENT||!1,Rt=t.RETURN_DOM||!1,Ft=t.RETURN_DOM_FRAGMENT||!1,Nt=t.RETURN_TRUSTED_TYPE||!1,Bt=t.FORCE_BODY||!1,zt=!1!==t.SANITIZE_DOM,$t=t.SANITIZE_NAMED_PROPS||!1,Ht=!1!==t.KEEP_CONTENT,Wt=t.IN_PLACE||!1,wt=t.ALLOWED_URI_REGEXP||X,ne=t.NAMESPACE||ee,oe=t.MATHML_TEXT_INTEGRATION_POINTS||oe,se=t.HTML_INTEGRATION_POINTS||se,_t=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&ve(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(_t.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ve(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(_t.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"===typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(_t.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Mt&&(Ot=!1),Ft&&(Rt=!0),Xt&&(kt=_({},j),Ct=[],!0===Xt.html&&(_(kt,O),_(Ct,B)),!0===Xt.svg&&(_(kt,P),_(Ct,R),_(Ct,N)),!0===Xt.svgFilters&&(_(kt,I),_(Ct,R),_(Ct,N)),!0===Xt.mathMl&&(_(kt,V),_(Ct,F),_(Ct,N))),t.ADD_TAGS&&(kt===St&&(kt=T(kt)),_(kt,t.ADD_TAGS,de)),t.ADD_ATTR&&(Ct===At&&(Ct=T(Ct)),_(Ct,t.ADD_ATTR,de)),t.ADD_URI_SAFE_ATTR&&_(Kt,t.ADD_URI_SAFE_ATTR,de),t.FORBID_CONTENTS&&(Gt===Ut&&(Gt=T(Gt)),_(Gt,t.FORBID_CONTENTS,de)),Ht&&(kt["#text"]=!0),Lt&&_(kt,["html","head","body"]),kt.table&&(_(kt,["tbody"]),delete Dt.tbody),t.TRUSTED_TYPES_POLICY){if("function"!==typeof t.TRUSTED_TYPES_POLICY.createHTML)throw S('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!==typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw S('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');at=t.TRUSTED_TYPES_POLICY,ot=at.createHTML("")}else void 0===at&&(at=tt(H,o)),null!==at&&"string"===typeof ot&&(ot=at.createHTML(""));a&&a(t),fe=t}},me=_({},[...P,...I,...M]),ye=_({},[...V,...L]),be=function(t){let e=it(t);e&&e.tagName||(e={namespaceURI:ne,tagName:"template"});const n=v(t.tagName),r=v(e.tagName);return!!ie[t.namespaceURI]&&(t.namespaceURI===te?e.namespaceURI===ee?"svg"===n:e.namespaceURI===Qt?"svg"===n&&("annotation-xml"===r||oe[r]):Boolean(me[n]):t.namespaceURI===Qt?e.namespaceURI===ee?"math"===n:e.namespaceURI===te?"math"===n&&se[r]:Boolean(ye[n]):t.namespaceURI===ee?!(e.namespaceURI===te&&!se[r])&&(!(e.namespaceURI===Qt&&!oe[r])&&(!ye[n]&&(le[n]||!me[n]))):!("application/xhtml+xml"!==ce||!ie[t.namespaceURI]))},xe=function(t){f(n.removed,{element:t});try{it(t).removeChild(t)}catch(e){U(t)}},we=function(t,e){try{f(n.removed,{attribute:e.getAttributeNode(t),from:e})}catch(r){f(n.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t)if(Rt||Ft)try{xe(e)}catch(r){}else try{e.setAttribute(t,"")}catch(r){}},ke=function(t){let e=null,n=null;if(Bt)t=""+t;else{const e=m(t,/^[\r\n\t ]+/);n=e&&e[0]}"application/xhtml+xml"===ce&&ne===ee&&(t=''+t+"");const i=at?at.createHTML(t):t;if(ne===ee)try{e=(new Y).parseFromString(i,ce)}catch(o){}if(!e||!e.documentElement){e=st.createDocument(ne,"template",null);try{e.documentElement.innerHTML=re?ot:i}catch(o){}}const a=e.body||e.documentElement;return t&&n&&a.insertBefore(r.createTextNode(n),a.childNodes[0]||null),ne===ee?ut.call(e,Lt?"html":"body")[0]:Lt?e.documentElement:a},Se=function(t){return lt.call(t.ownerDocument||t,t,D.SHOW_ELEMENT|D.SHOW_COMMENT|D.SHOW_TEXT|D.SHOW_PROCESSING_INSTRUCTION|D.SHOW_CDATA_SECTION,null)},Ce=function(t){return t instanceof $&&("string"!==typeof t.nodeName||"string"!==typeof t.textContent||"function"!==typeof t.removeChild||!(t.attributes instanceof z)||"function"!==typeof t.removeAttribute||"function"!==typeof t.setAttribute||"string"!==typeof t.namespaceURI||"function"!==typeof t.insertBefore||"function"!==typeof t.hasChildNodes)},Ae=function(t){return"function"===typeof C&&t instanceof C};function _e(t,e,r){u(t,t=>{t.call(n,e,r,fe)})}const De=function(t){let e=null;if(_e(dt.beforeSanitizeElements,t,null),Ce(t))return xe(t),!0;const r=de(t.nodeName);if(_e(dt.uponSanitizeElement,t,{tagName:r,allowedTags:kt}),t.hasChildNodes()&&!Ae(t.firstElementChild)&&k(/<[/\w]/g,t.innerHTML)&&k(/<[/\w]/g,t.textContent))return xe(t),!0;if(t.nodeType===J.progressingInstruction)return xe(t),!0;if(Vt&&t.nodeType===J.comment&&k(/<[/\w]/g,t.data))return xe(t),!0;if(!kt[r]||Dt[r]){if(!Dt[r]&&Ee(r)){if(_t.tagNameCheck instanceof RegExp&&k(_t.tagNameCheck,r))return!1;if(_t.tagNameCheck instanceof Function&&_t.tagNameCheck(r))return!1}if(Ht&&!Gt[r]){const e=it(t)||t.parentNode,n=rt(t)||t.childNodes;if(n&&e){const r=n.length;for(let i=r-1;i>=0;--i){const r=G(n[i],!0);r.__removalCount=(t.__removalCount||0)+1,e.insertBefore(r,Z(t))}}}return xe(t),!0}return t instanceof A&&!be(t)?(xe(t),!0):"noscript"!==r&&"noembed"!==r&&"noframes"!==r||!k(/<\/no(script|embed|frames)/i,t.innerHTML)?(Mt&&t.nodeType===J.text&&(e=t.textContent,u([ft,pt,vt],t=>{e=y(e,t," ")}),t.textContent!==e&&(f(n.removed,{element:t.cloneNode()}),t.textContent=e)),_e(dt.afterSanitizeElements,t,null),!1):(xe(t),!0)},Te=function(t,e,n){if(zt&&("id"===e||"name"===e)&&(n in r||n in pe))return!1;if(Ot&&!Tt[e]&&k(gt,e));else if(Et&&k(mt,e));else if(!Ct[e]||Tt[e]){if(!(Ee(t)&&(_t.tagNameCheck instanceof RegExp&&k(_t.tagNameCheck,t)||_t.tagNameCheck instanceof Function&&_t.tagNameCheck(t))&&(_t.attributeNameCheck instanceof RegExp&&k(_t.attributeNameCheck,e)||_t.attributeNameCheck instanceof Function&&_t.attributeNameCheck(e))||"is"===e&&_t.allowCustomizedBuiltInElements&&(_t.tagNameCheck instanceof RegExp&&k(_t.tagNameCheck,n)||_t.tagNameCheck instanceof Function&&_t.tagNameCheck(n))))return!1}else if(Kt[e]);else if(k(wt,y(n,bt,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==b(n,"data:")||!qt[t]){if(Pt&&!k(yt,y(n,bt,"")));else if(n)return!1}else;return!0},Ee=function(t){return"annotation-xml"!==t&&m(t,xt)},Oe=function(t){_e(dt.beforeSanitizeAttributes,t,null);const{attributes:e}=t;if(!e||Ce(t))return;const r={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ct,forceKeepAttr:void 0};let i=e.length;while(i--){const o=e[i],{name:s,namespaceURI:l,value:c}=o,h=de(s);let f="value"===s?c:x(c);if(r.attrName=h,r.attrValue=f,r.keepAttr=!0,r.forceKeepAttr=void 0,_e(dt.uponSanitizeAttribute,t,r),f=r.attrValue,!$t||"id"!==h&&"name"!==h||(we(s,t),f=Yt+f),Vt&&k(/((--!?|])>)|<\/(style|title)/i,f)){we(s,t);continue}if(r.forceKeepAttr)continue;if(we(s,t),!r.keepAttr)continue;if(!It&&k(/\/>/i,f)){we(s,t);continue}Mt&&u([ft,pt,vt],t=>{f=y(f,t," ")});const p=de(t.nodeName);if(Te(p,h,f)){if(at&&"object"===typeof H&&"function"===typeof H.getAttributeType)if(l);else switch(H.getAttributeType(p,h)){case"TrustedHTML":f=at.createHTML(f);break;case"TrustedScriptURL":f=at.createScriptURL(f);break}try{l?t.setAttributeNS(l,s,f):t.setAttribute(s,f),Ce(t)?xe(t):d(n.removed)}catch(a){}}}_e(dt.afterSanitizeAttributes,t,null)},Pe=function t(e){let n=null;const r=Se(e);_e(dt.beforeSanitizeShadowDOM,e,null);while(n=r.nextNode())_e(dt.uponSanitizeShadowNode,n,null),De(n),Oe(n),n.content instanceof l&&t(n.content);_e(dt.afterSanitizeShadowDOM,e,null)};return n.sanitize=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=null,a=null,o=null,s=null;if(re=!t,re&&(t="\x3c!--\x3e"),"string"!==typeof t&&!Ae(t)){if("function"!==typeof t.toString)throw S("toString is not a function");if(t=t.toString(),"string"!==typeof t)throw S("dirty is not a string, aborting")}if(!n.isSupported)return t;if(jt||ge(e),n.removed=[],"string"===typeof t&&(Wt=!1),Wt){if(t.nodeName){const e=de(t.nodeName);if(!kt[e]||Dt[e])throw S("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof C)r=ke("\x3c!----\x3e"),a=r.ownerDocument.importNode(t,!0),a.nodeType===J.element&&"BODY"===a.nodeName||"HTML"===a.nodeName?r=a:r.appendChild(a);else{if(!Rt&&!Mt&&!Lt&&-1===t.indexOf("<"))return at&&Nt?at.createHTML(t):t;if(r=ke(t),!r)return Rt?null:Nt?ot:""}r&&Bt&&xe(r.firstChild);const c=Se(Wt?t:r);while(o=c.nextNode())De(o),Oe(o),o.content instanceof l&&Pe(o.content);if(Wt)return t;if(Rt){if(Ft){s=ct.call(r.ownerDocument);while(r.firstChild)s.appendChild(r.firstChild)}else s=r;return(Ct.shadowroot||Ct.shadowrootmode)&&(s=ht.call(i,s,!0)),s}let h=Lt?r.outerHTML:r.innerHTML;return Lt&&kt["!doctype"]&&r.ownerDocument&&r.ownerDocument.doctype&&r.ownerDocument.doctype.name&&k(q,r.ownerDocument.doctype.name)&&(h="\n"+h),Mt&&u([ft,pt,vt],t=>{h=y(h,t," ")}),at&&Nt?at.createHTML(h):h},n.setConfig=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};ge(t),jt=!0},n.clearConfig=function(){fe=null,jt=!1},n.isValidAttribute=function(t,e,n){fe||ge({});const r=de(t),i=de(e);return Te(r,i,n)},n.addHook=function(t,e){"function"===typeof e&&f(dt[t],e)},n.removeHook=function(t,e){if(void 0!==e){const n=h(dt[t],e);return-1===n?void 0:p(dt[t],n,1)[0]}return d(dt[t])},n.removeHooks=function(t){dt[t]=[]},n.removeAllHooks=function(){dt=et()},n}var rt=nt();return rt}))},c1c9:function(t,e,n){var r=n("a454"),i=n("f3c1"),a=i(r);t.exports=a},c207:function(t,e){},c26b:function(t,e,n){"use strict";var r=n("86cc").f,i=n("2aeb"),a=n("dcbc"),o=n("9b43"),s=n("f605"),l=n("4a59"),c=n("01f9"),u=n("d53b"),h=n("7a56"),d=n("9e1e"),f=n("67ab").fastKey,p=n("b39a"),v=d?"_s":"size",g=function(t,e){var n,r=f(e);if("F"!==r)return t._i[r];for(n=t._f;n;n=n.n)if(n.k==e)return n};t.exports={getConstructor:function(t,e,n,c){var u=t((function(t,r){s(t,u,e,"_i"),t._t=e,t._i=i(null),t._f=void 0,t._l=void 0,t[v]=0,void 0!=r&&l(r,n,t[c],t)}));return a(u.prototype,{clear:function(){for(var t=p(this,e),n=t._i,r=t._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete n[r.i];t._f=t._l=void 0,t[v]=0},delete:function(t){var n=p(this,e),r=g(n,t);if(r){var i=r.n,a=r.p;delete n._i[r.i],r.r=!0,a&&(a.n=i),i&&(i.p=a),n._f==r&&(n._f=i),n._l==r&&(n._l=a),n[v]--}return!!r},forEach:function(t){p(this,e);var n,r=o(t,arguments.length>1?arguments[1]:void 0,3);while(n=n?n.n:this._f){r(n.v,n.k,this);while(n&&n.r)n=n.p}},has:function(t){return!!g(p(this,e),t)}}),d&&r(u.prototype,"size",{get:function(){return p(this,e)[v]}}),u},def:function(t,e,n){var r,i,a=g(t,e);return a?a.v=n:(t._l=a={i:i=f(e,!0),k:e,v:n,p:r=t._l,n:void 0,r:!1},t._f||(t._f=a),r&&(r.n=a),t[v]++,"F"!==i&&(t._i[i]=a)),t},getEntry:g,setStrong:function(t,e,n){c(t,e,(function(t,n){this._t=p(t,e),this._k=n,this._l=void 0}),(function(){var t=this,e=t._k,n=t._l;while(n&&n.r)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?u(0,"keys"==e?n.k:"values"==e?n.v:[n.k,n.v]):(t._t=void 0,u(1))}),n?"entries":"values",!n,!0),h(e)}}},c2b6:function(t,e,n){var r=n("f8af"),i=n("5d89"),a=n("6f6c"),o=n("a2db"),s=n("c8fe"),l="[object Boolean]",c="[object Date]",u="[object Map]",h="[object Number]",d="[object RegExp]",f="[object Set]",p="[object String]",v="[object Symbol]",g="[object ArrayBuffer]",m="[object DataView]",y="[object Float32Array]",b="[object Float64Array]",x="[object Int8Array]",w="[object Int16Array]",k="[object Int32Array]",S="[object Uint8Array]",C="[object Uint8ClampedArray]",A="[object Uint16Array]",_="[object Uint32Array]";function D(t,e,n){var D=t.constructor;switch(e){case g:return r(t);case l:case c:return new D(+t);case m:return i(t,n);case y:case b:case x:case w:case k:case S:case C:case A:case _:return s(t,n);case u:return new D;case h:case p:return new D(t);case d:return a(t);case f:return new D;case v:return o(t)}}t.exports=D},c366:function(t,e,n){var r=n("6821"),i=n("9def"),a=n("77f1");t.exports=function(t){return function(e,n,o){var s,l=r(e),c=i(l.length),u=a(o,c);if(t&&n!=n){while(c>u)if(s=l[u++],s!=s)return!0}else for(;c>u;u++)if((t||u in l)&&l[u]===n)return t||u||0;return!t&&-1}}},c367:function(t,e,n){"use strict";var r=n("8436"),i=n("50ed"),a=n("481b"),o=n("36c3");t.exports=n("30f1")(Array,"Array",(function(t,e){this._t=o(t),this._i=0,this._k=e}),(function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,i(1)):i(0,"keys"==e?n:"values"==e?t[n]:[n,t[n]])}),"values"),a.Arguments=a.Array,r("keys"),r("values"),r("entries")},c3a1:function(t,e,n){var r=n("e6f3"),i=n("1691");t.exports=Object.keys||function(t){return r(t,i)}},c3cd:function(t,e){t.exports="2.1.8"},c3fc:function(t,e,n){var r=n("42a2"),i=n("1310"),a="[object Set]";function o(t){return i(t)&&r(t)==a}t.exports=o},c532:function(t,e,n){"use strict";(function(t,r){var i=n("1d2b");const{toString:a}=Object.prototype,{getPrototypeOf:o}=Object,s=(t=>e=>{const n=a.call(e);return t[n]||(t[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),l=t=>(t=t.toLowerCase(),e=>s(e)===t),c=t=>e=>typeof e===t,{isArray:u}=Array,h=c("undefined");function d(t){return null!==t&&!h(t)&&null!==t.constructor&&!h(t.constructor)&&g(t.constructor.isBuffer)&&t.constructor.isBuffer(t)}const f=l("ArrayBuffer");function p(t){let e;return e="undefined"!==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(t):t&&t.buffer&&f(t.buffer),e}const v=c("string"),g=c("function"),m=c("number"),y=t=>null!==t&&"object"===typeof t,b=t=>!0===t||!1===t,x=t=>{if("object"!==s(t))return!1;const e=o(t);return(null===e||e===Object.prototype||null===Object.getPrototypeOf(e))&&!(Symbol.toStringTag in t)&&!(Symbol.iterator in t)},w=l("Date"),k=l("File"),S=l("Blob"),C=l("FileList"),A=t=>y(t)&&g(t.pipe),_=t=>{let e;return t&&("function"===typeof FormData&&t instanceof FormData||g(t.append)&&("formdata"===(e=s(t))||"object"===e&&g(t.toString)&&"[object FormData]"===t.toString()))},D=l("URLSearchParams"),[T,E,O,P]=["ReadableStream","Request","Response","Headers"].map(l),I=t=>t.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function M(t,e,{allOwnKeys:n=!1}={}){if(null===t||"undefined"===typeof t)return;let r,i;if("object"!==typeof t&&(t=[t]),u(t))for(r=0,i=t.length;r0)if(r=n[i],e===r.toLowerCase())return r;return null}const L=(()=>"undefined"!==typeof globalThis?globalThis:"undefined"!==typeof self?self:"undefined"!==typeof window?window:t)(),j=t=>!h(t)&&t!==L;function B(){const{caseless:t}=j(this)&&this||{},e={},n=(n,r)=>{const i=t&&V(e,r)||r;x(e[i])&&x(n)?e[i]=B(e[i],n):x(n)?e[i]=B({},n):u(n)?e[i]=n.slice():e[i]=n};for(let r=0,i=arguments.length;r(M(e,(e,r)=>{n&&g(e)?t[r]=Object(i["a"])(e,n):t[r]=e},{allOwnKeys:r}),t),F=t=>(65279===t.charCodeAt(0)&&(t=t.slice(1)),t),N=(t,e,n,r)=>{t.prototype=Object.create(e.prototype,r),t.prototype.constructor=t,Object.defineProperty(t,"super",{value:e.prototype}),n&&Object.assign(t.prototype,n)},z=(t,e,n,r)=>{let i,a,s;const l={};if(e=e||{},null==t)return e;do{i=Object.getOwnPropertyNames(t),a=i.length;while(a-- >0)s=i[a],r&&!r(s,t,e)||l[s]||(e[s]=t[s],l[s]=!0);t=!1!==n&&o(t)}while(t&&(!n||n(t,e))&&t!==Object.prototype);return e},$=(t,e,n)=>{t=String(t),(void 0===n||n>t.length)&&(n=t.length),n-=e.length;const r=t.indexOf(e,n);return-1!==r&&r===n},Y=t=>{if(!t)return null;if(u(t))return t;let e=t.length;if(!m(e))return null;const n=new Array(e);while(e-- >0)n[e]=t[e];return n},H=(t=>e=>t&&e instanceof t)("undefined"!==typeof Uint8Array&&o(Uint8Array)),W=(t,e)=>{const n=t&&t[Symbol.iterator],r=n.call(t);let i;while((i=r.next())&&!i.done){const n=i.value;e.call(t,n[0],n[1])}},X=(t,e)=>{let n;const r=[];while(null!==(n=t.exec(e)))r.push(n);return r},G=l("HTMLFormElement"),U=t=>t.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(t,e,n){return e.toUpperCase()+n})),q=(({hasOwnProperty:t})=>(e,n)=>t.call(e,n))(Object.prototype),Z=l("RegExp"),K=(t,e)=>{const n=Object.getOwnPropertyDescriptors(t),r={};M(n,(n,i)=>{let a;!1!==(a=e(n,i,t))&&(r[i]=a||n)}),Object.defineProperties(t,r)},J=t=>{K(t,(e,n)=>{if(g(t)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const r=t[n];g(r)&&(e.enumerable=!1,"writable"in e?e.writable=!1:e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))})},Q=(t,e)=>{const n={},r=t=>{t.forEach(t=>{n[t]=!0})};return u(t)?r(t):r(String(t).split(e)),n},tt=()=>{},et=(t,e)=>null!=t&&Number.isFinite(t=+t)?t:e;function nt(t){return!!(t&&g(t.append)&&"FormData"===t[Symbol.toStringTag]&&t[Symbol.iterator])}const rt=t=>{const e=new Array(10),n=(t,r)=>{if(y(t)){if(e.indexOf(t)>=0)return;if(!("toJSON"in t)){e[r]=t;const i=u(t)?[]:{};return M(t,(t,e)=>{const a=n(t,r+1);!h(a)&&(i[e]=a)}),e[r]=void 0,i}}return t};return n(t,0)},it=l("AsyncFunction"),at=t=>t&&(y(t)||g(t))&&g(t.then)&&g(t.catch),ot=((t,e)=>t?setImmediate:e?((t,e)=>(L.addEventListener("message",({source:n,data:r})=>{n===L&&r===t&&e.length&&e.shift()()},!1),n=>{e.push(n),L.postMessage(t,"*")}))("axios@"+Math.random(),[]):t=>setTimeout(t))("function"===typeof setImmediate,g(L.postMessage)),st="undefined"!==typeof queueMicrotask?queueMicrotask.bind(L):"undefined"!==typeof r&&r.nextTick||ot;e["a"]={isArray:u,isArrayBuffer:f,isBuffer:d,isFormData:_,isArrayBufferView:p,isString:v,isNumber:m,isBoolean:b,isObject:y,isPlainObject:x,isReadableStream:T,isRequest:E,isResponse:O,isHeaders:P,isUndefined:h,isDate:w,isFile:k,isBlob:S,isRegExp:Z,isFunction:g,isStream:A,isURLSearchParams:D,isTypedArray:H,isFileList:C,forEach:M,merge:B,extend:R,trim:I,stripBOM:F,inherits:N,toFlatObject:z,kindOf:s,kindOfTest:l,endsWith:$,toArray:Y,forEachEntry:W,matchAll:X,isHTMLForm:G,hasOwnProperty:q,hasOwnProp:q,reduceDescriptors:K,freezeMethods:J,toObjectSet:Q,toCamelCase:U,noop:tt,toFiniteNumber:et,findKey:V,global:L,isContextDefined:j,isSpecCompliantForm:nt,toJSONObject:rt,isAsyncFn:it,isThenable:at,setImmediate:ot,asap:st}}).call(this,n("c8ba"),n("f28c"))},c584:function(t,e){function n(t,e){return t.has(e)}t.exports=n},c5a2:function(t,e,n){var r=n("6ac0"),i=n("48a0"),a=n("badf"),o=n("58f7"),s=n("6747");function l(t,e,n){var l=s(t)?r:o,c=arguments.length<3;return l(t,a(e,4),n,c,i)}t.exports=l},c5f6:function(t,e,n){"use strict";var r=n("7726"),i=n("69a8"),a=n("2d95"),o=n("5dbc"),s=n("6a99"),l=n("79e5"),c=n("9093").f,u=n("11e9").f,h=n("86cc").f,d=n("aa77").trim,f="Number",p=r[f],v=p,g=p.prototype,m=a(n("2aeb")(g))==f,y="trim"in String.prototype,b=function(t){var e=s(t,!1);if("string"==typeof e&&e.length>2){e=y?e.trim():d(e,3);var n,r,i,a=e.charCodeAt(0);if(43===a||45===a){if(n=e.charCodeAt(2),88===n||120===n)return NaN}else if(48===a){switch(e.charCodeAt(1)){case 66:case 98:r=2,i=49;break;case 79:case 111:r=8,i=55;break;default:return+e}for(var o,l=e.slice(2),c=0,u=l.length;ci)return NaN;return parseInt(l,r)}}return+e};if(!p(" 0o1")||!p("0b1")||p("+0x1")){p=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof p&&(m?l((function(){g.valueOf.call(n)})):a(n)!=f)?o(new v(b(e)),n,p):b(e)};for(var x,w=n("9e1e")?c(v):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),k=0;w.length>k;k++)i(v,x=w[k])&&!i(p,x)&&h(p,x,u(v,x));p.prototype=g,g.constructor=p,n("2aba")(r,f,p)}},c641:function(t,e,n){t.exports=n("6cd4")},c69a:function(t,e,n){t.exports=!n("9e1e")&&!n("79e5")((function(){return 7!=Object.defineProperty(n("230e")("div"),"a",{get:function(){return 7}}).a}))},c6cf:function(t,e,n){var r=n("4d8c"),i=n("2286"),a=n("c1c9");function o(t){return a(i(t,void 0,r),t+"")}t.exports=o},c707:function(t,e,n){var r=n("5c69"),i=n("6a5c"),a=n("100e"),o=n("9aff"),s=a((function(t,e){if(null==t)return[];var n=e.length;return n>1&&o(t,e[0],e[1])?e=[]:n>2&&o(e[0],e[1],e[2])&&(e=[e[0]]),i(t,r(e,1),[])}));t.exports=s},c869:function(t,e,n){var r=n("0b07"),i=n("2b3e"),a=r(i,"Set");t.exports=a},c87c:function(t,e){var n=Object.prototype,r=n.hasOwnProperty;function i(t){var e=t.length,n=new t.constructor(e);return e&&"string"==typeof t[0]&&r.call(t,"index")&&(n.index=t.index,n.input=t.input),n}t.exports=i},c8ba:function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(r){"object"===typeof window&&(n=window)}t.exports=n},c8fe:function(t,e,n){var r=n("f8af");function i(t,e){var n=e?r(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.length)}t.exports=i},c9ca:function(t,e,n){var r=n("ef5d"),i=r("length");t.exports=i},ca5a:function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},cadf:function(t,e,n){"use strict";var r=n("9c6c"),i=n("d53b"),a=n("84f2"),o=n("6821");t.exports=n("01f9")(Array,"Array",(function(t,e){this._t=o(t),this._i=0,this._k=e}),(function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,i(1)):i(0,"keys"==e?n:"values"==e?t[n]:[n,t[n]])}),"values"),a.Arguments=a.Array,r("keys"),r("values"),r("entries")},cae7:function(t,e,n){var r=n("ffd6");function i(t,e){if(t!==e){var n=void 0!==t,i=null===t,a=t===t,o=r(t),s=void 0!==e,l=null===e,c=e===e,u=r(e);if(!l&&!u&&!o&&t>e||o&&s&&c&&!l&&!u||i&&s&&c||!n&&c||!a)return 1;if(!i&&!o&&!u&&tl)r(s,n=e[l++])&&(~a(c,n)||c.push(n));return c}},ce5b:function(t,e,n){(function(e,r){t.exports=r(n("2b0e"))})("undefined"!==typeof self&&self,(function(t){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"===typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/dist/",n(n.s="./src/index.ts")}({"./src/components/VAlert/VAlert.sass": +/*!*******************************************!*\ + !*** ./src/components/VAlert/VAlert.sass ***! + \*******************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VAlert/VAlert.ts": +/*!*****************************************!*\ + !*** ./src/components/VAlert/VAlert.ts ***! + \*****************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VAlert.sass */"./src/components/VAlert/VAlert.sass");var r=n(/*! ../VSheet */"./src/components/VSheet/index.ts"),i=n(/*! ../VBtn */"./src/components/VBtn/index.ts"),a=n(/*! ../VIcon */"./src/components/VIcon/index.ts"),o=n(/*! ../../mixins/toggleable */"./src/mixins/toggleable/index.ts"),s=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),l=n(/*! ../../mixins/transitionable */"./src/mixins/transitionable/index.ts"),c=n(/*! ../../util/mixins */"./src/util/mixins.ts"),u=n(/*! ../../util/console */"./src/util/console.ts"),h=n(/*! ../../util/helpers */"./src/util/helpers.ts"),d=function(){return d=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0,"v-app-bar--shrink-on-scroll":this.shrinkOnScroll})},scrollRatio:function(){var t=this.computedScrollThreshold;return Math.max((t-this.currentScroll)/t,0)},computedContentHeight:function(){if(!this.shrinkOnScroll)return r["default"].options.computed.computedContentHeight.call(this);var t=this.dense?48:56,e=this.computedOriginalHeight;return t+(e-t)*this.scrollRatio},computedFontSize:function(){if(this.isProminent){var t=1.25,e=1.5;return t+(e-t)*this.scrollRatio}},computedLeft:function(){return!this.app||this.clippedLeft?0:this.$vuetify.application.left},computedMarginTop:function(){return this.app?this.$vuetify.application.bar:0},computedOpacity:function(){if(this.fadeImgOnScroll)return this.scrollRatio},computedOriginalHeight:function(){var t=r["default"].options.computed.computedContentHeight.call(this);return this.isExtended&&(t+=parseInt(this.extensionHeight)),t},computedRight:function(){return!this.app||this.clippedRight?0:this.$vuetify.application.right},computedScrollThreshold:function(){return this.scrollThreshold?Number(this.scrollThreshold):this.computedOriginalHeight-(this.dense?48:56)},computedTransform:function(){if(!this.canScroll||this.elevateOnScroll&&0===this.currentScroll&&this.isActive)return 0;if(this.isActive)return 0;var t=this.scrollOffScreen?this.computedHeight:this.computedContentHeight;return this.bottom?t:-t},hideShadow:function(){return this.elevateOnScroll&&this.isExtended?this.currentScroll0:r["default"].options.computed.isCollapsed.call(this)},isProminent:function(){return r["default"].options.computed.isProminent.call(this)||this.shrinkOnScroll},styles:function(){return h(h({},r["default"].options.computed.styles.call(this)),{fontSize:Object(c["convertToUnit"])(this.computedFontSize,"rem"),marginTop:Object(c["convertToUnit"])(this.computedMarginTop),transform:"translateY("+Object(c["convertToUnit"])(this.computedTransform)+")",left:Object(c["convertToUnit"])(this.computedLeft),right:Object(c["convertToUnit"])(this.computedRight)})}},watch:{canScroll:"onScroll",computedTransform:function(){this.canScroll&&(this.clippedLeft||this.clippedRight)&&this.callUpdate()},invertedScroll:function(t){this.isActive=!t||0!==this.currentScroll},hideOnScroll:function(t){this.isActive=!t||this.currentScrollthis.computedScrollThreshold:(this.hideOnScroll&&(this.isActive=this.isScrollingUp||this.currentScroll-1}},hideNoData:Boolean,menuProps:{type:r["default"].options.props.menuProps.type,default:function(){return l}},noFilter:Boolean,searchInput:{type:String}},data:function(){return{lazySearch:this.searchInput}},computed:{classes:function(){return s(s({},r["default"].options.computed.classes.call(this)),{"v-autocomplete":!0,"v-autocomplete--is-selecting-index":this.selectedIndex>-1})},computedItems:function(){return this.filteredItems},selectedValues:function(){var t=this;return this.selectedItems.map((function(e){return t.getValue(e)}))},hasDisplayedItems:function(){var t=this;return this.hideSelected?this.filteredItems.some((function(e){return!t.hasItem(e)})):this.filteredItems.length>0},currentRange:function(){return null==this.selectedItem?0:String(this.getText(this.selectedItem)).length},filteredItems:function(){var t=this;return!this.isSearching||this.noFilter||null==this.internalSearch?this.allItems:this.allItems.filter((function(e){var n=Object(o["getPropertyFromItem"])(e,t.itemText),r=null!=n?String(n):"";return t.filter(e,String(t.internalSearch),r)}))},internalSearch:{get:function(){return this.lazySearch},set:function(t){this.lazySearch!==t&&(this.lazySearch=t,this.$emit("update:search-input",t))}},isAnyValueAllowed:function(){return!1},isDirty:function(){return this.searchIsDirty||this.selectedItems.length>0},isSearching:function(){return this.multiple&&this.searchIsDirty||this.searchIsDirty&&this.internalSearch!==this.getText(this.selectedItem)},menuCanShow:function(){return!!this.isFocused&&(this.hasDisplayedItems||!this.hideNoData)},$_menuProps:function(){var t=r["default"].options.computed.$_menuProps.call(this);return t.contentClass=("v-autocomplete__content "+(t.contentClass||"")).trim(),s(s({},l),t)},searchIsDirty:function(){return null!=this.internalSearch&&""!==this.internalSearch},selectedItem:function(){var t=this;return this.multiple?null:this.selectedItems.find((function(e){return t.valueComparator(t.getValue(e),t.getValue(t.internalValue))}))},listData:function(){var t=r["default"].options.computed.listData.call(this);return t.props=s(s({},t.props),{items:this.virtualizedItems,noFilter:this.noFilter||!this.isSearching||!this.filteredItems.length,searchInput:this.internalSearch}),t}},watch:{filteredItems:"onFilteredItemsChanged",internalValue:"setSearch",isFocused:function(t){t?(document.addEventListener("copy",this.onCopy),this.$refs.input&&this.$refs.input.select()):(document.removeEventListener("copy",this.onCopy),this.blur(),this.updateSelf())},isMenuActive:function(t){!t&&this.hasSlot&&(this.lazySearch=null)},items:function(t,e){e&&e.length||!this.hideNoData||!this.isFocused||this.isMenuActive||!t.length||this.activateMenu()},searchInput:function(t){this.lazySearch=t},internalSearch:"onInternalSearchChanged",itemText:"updateSelf"},created:function(){this.setSearch()},destroyed:function(){document.removeEventListener("copy",this.onCopy)},methods:{onFilteredItemsChanged:function(t,e){var n=this;if(t!==e){if(!this.autoSelectFirst){var r=e[this.$refs.menu.listIndex];r?this.setMenuIndex(t.findIndex((function(t){return t===r}))):this.setMenuIndex(-1),this.$emit("update:list-index",this.$refs.menu.listIndex)}this.$nextTick((function(){n.internalSearch&&(1===t.length||n.autoSelectFirst)&&(n.$refs.menu.getTiles(),n.autoSelectFirst&&t.length&&(n.setMenuIndex(0),n.$emit("update:list-index",n.$refs.menu.listIndex)))}))}},onInternalSearchChanged:function(){this.updateMenuDimensions()},updateMenuDimensions:function(){this.isMenuActive&&this.$refs.menu&&this.$refs.menu.updateDimensions()},changeSelectedIndex:function(t){this.searchIsDirty||(this.multiple&&t===o["keyCodes"].left?-1===this.selectedIndex?this.selectedIndex=this.selectedItems.length-1:this.selectedIndex--:this.multiple&&t===o["keyCodes"].right?this.selectedIndex>=this.selectedItems.length-1?this.selectedIndex=-1:this.selectedIndex++:t!==o["keyCodes"].backspace&&t!==o["keyCodes"].delete||this.deleteCurrentItem())},deleteCurrentItem:function(){var t=this.selectedIndex,e=this.selectedItems[t];if(this.isInteractive&&!this.getDisabled(e)){var n=this.selectedItems.length-1;if(-1!==this.selectedIndex||0===n){var r=this.selectedItems.length,i=t!==r-1?t:t-1,a=this.selectedItems[i];a?this.selectItem(e):this.setValue(this.multiple?[]:null),this.selectedIndex=i}else this.selectedIndex=n}},clearableCallback:function(){this.internalSearch=null,r["default"].options.methods.clearableCallback.call(this)},genInput:function(){var t=i["default"].options.methods.genInput.call(this);return t.data=Object(a["default"])(t.data,{attrs:{"aria-activedescendant":Object(o["getObjectValueByPath"])(this.$refs.menu,"activeTile.id"),autocomplete:Object(o["getObjectValueByPath"])(t.data,"attrs.autocomplete","off")},domProps:{value:this.internalSearch}}),t},genInputSlot:function(){var t=r["default"].options.methods.genInputSlot.call(this);return t.data.attrs.role="combobox",t},genSelections:function(){return this.hasSlot||this.multiple?r["default"].options.methods.genSelections.call(this):[]},onClick:function(t){this.isInteractive&&(this.selectedIndex>-1?this.selectedIndex=-1:this.onFocus(),this.isAppendInner(t.target)||this.activateMenu())},onInput:function(t){if(!(this.selectedIndex>-1)&&t.target){var e=t.target,n=e.value;e.value&&this.activateMenu(),this.multiple||""!==n||this.deleteCurrentItem(),this.internalSearch=n,this.badInput=e.validity&&e.validity.badInput}},onKeyDown:function(t){var e=t.keyCode;!t.ctrlKey&&[o["keyCodes"].home,o["keyCodes"].end].includes(e)||r["default"].options.methods.onKeyDown.call(this,t),this.changeSelectedIndex(e)},onSpaceDown:function(t){},onTabDown:function(t){r["default"].options.methods.onTabDown.call(this,t),this.updateSelf()},onUpDown:function(t){t.preventDefault(),this.activateMenu()},selectItem:function(t){r["default"].options.methods.selectItem.call(this,t),this.setSearch()},setSelectedItems:function(){r["default"].options.methods.setSelectedItems.call(this),this.isFocused||this.setSearch()},setSearch:function(){var t=this;this.$nextTick((function(){t.multiple&&t.internalSearch&&t.isMenuActive||(t.internalSearch=!t.selectedItems.length||t.multiple||t.hasSlot?null:t.getText(t.selectedItem))}))},updateSelf:function(){(this.searchIsDirty||this.internalValue)&&(this.multiple||this.valueComparator(this.internalSearch,this.getValue(this.internalValue))||this.setSearch())},hasItem:function(t){return this.selectedValues.indexOf(this.getValue(t))>-1},onCopy:function(t){var e,n;if(-1!==this.selectedIndex){var r=this.selectedItems[this.selectedIndex],i=this.getText(r);null===(e=t.clipboardData)||void 0===e||e.setData("text/plain",i),null===(n=t.clipboardData)||void 0===n||n.setData("text/vnd.vuetify.autocomplete.item+plain",i),t.preventDefault()}}}})},"./src/components/VAutocomplete/index.ts": +/*!***********************************************!*\ + !*** ./src/components/VAutocomplete/index.ts ***! + \***********************************************/ +/*! exports provided: VAutocomplete, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VAutocomplete */"./src/components/VAutocomplete/VAutocomplete.ts");n.d(e,"VAutocomplete",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VAvatar/VAvatar.sass": +/*!*********************************************!*\ + !*** ./src/components/VAvatar/VAvatar.sass ***! + \*********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VAvatar/VAvatar.ts": +/*!*******************************************!*\ + !*** ./src/components/VAvatar/VAvatar.ts ***! + \*******************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VAvatar.sass */"./src/components/VAvatar/VAvatar.sass");var r=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),i=n(/*! ../../mixins/measurable */"./src/mixins/measurable/index.ts"),a=n(/*! ../../mixins/roundable */"./src/mixins/roundable/index.ts"),o=n(/*! ../../util/helpers */"./src/util/helpers.ts"),s=n(/*! ../../util/mixins */"./src/util/mixins.ts"),l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;nthis.computedScrollThreshold,this.$emit("update:input-value",this.isActive)),this.currentThreshold0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},m=Object(h["default"])(r["default"],c["default"],l["default"],u["default"],Object(a["factory"])("btnToggle"),Object(o["factory"])("inputValue"));e["default"]=m.extend().extend({name:"v-btn",props:{activeClass:{type:String,default:function(){return this.btnToggle?this.btnToggle.activeClass:""}},block:Boolean,depressed:Boolean,fab:Boolean,icon:Boolean,loading:Boolean,outlined:Boolean,plain:Boolean,retainFocusOnClick:Boolean,rounded:Boolean,tag:{type:String,default:"button"},text:Boolean,tile:Boolean,type:{type:String,default:"button"},value:null},data:function(){return{proxyClass:"v-btn--active"}},computed:{classes:function(){return v(v(v(v(v(v({"v-btn":!0},c["default"].options.computed.classes.call(this)),{"v-btn--absolute":this.absolute,"v-btn--block":this.block,"v-btn--bottom":this.bottom,"v-btn--disabled":this.disabled,"v-btn--is-elevated":this.isElevated,"v-btn--fab":this.fab,"v-btn--fixed":this.fixed,"v-btn--has-bg":this.hasBg,"v-btn--icon":this.icon,"v-btn--left":this.left,"v-btn--loading":this.loading,"v-btn--outlined":this.outlined,"v-btn--plain":this.plain,"v-btn--right":this.right,"v-btn--round":this.isRound,"v-btn--rounded":this.rounded,"v-btn--router":this.to,"v-btn--text":this.text,"v-btn--tile":this.tile,"v-btn--top":this.top}),this.themeClasses),this.groupClasses),this.elevationClasses),this.sizeableClasses)},computedElevation:function(){if(!this.disabled)return s["default"].options.computed.computedElevation.call(this)},computedRipple:function(){var t,e=!this.icon&&!this.fab||{circle:!0};return!this.disabled&&(null!==(t=this.ripple)&&void 0!==t?t:e)},hasBg:function(){return!this.text&&!this.plain&&!this.outlined&&!this.icon},isElevated:function(){return Boolean(!this.icon&&!this.text&&!this.outlined&&!this.depressed&&!this.disabled&&!this.plain&&(null==this.elevation||Number(this.elevation)>0))},isRound:function(){return Boolean(this.icon||this.fab)},styles:function(){return v({},this.measurableStyles)}},created:function(){var t=this,e=[["flat","text"],["outline","outlined"],["round","rounded"]];e.forEach((function(e){var n=g(e,2),r=n[0],i=n[1];t.$attrs.hasOwnProperty(r)&&Object(d["breaking"])(r,i,t)}))},methods:{click:function(t){!this.retainFocusOnClick&&!this.fab&&t.detail&&this.$el.blur(),this.$emit("click",t),this.btnToggle&&this.toggle()},genContent:function(){return this.$createElement("span",{staticClass:"v-btn__content"},Object(f["getSlot"])(this))},genLoader:function(){return this.$createElement("span",{class:"v-btn__loader"},Object(f["getSlot"])(this,"loader")||[this.$createElement(i["default"],{props:{indeterminate:!0,size:23,width:2}})])}},render:function(t){var e=[this.genContent(),this.loading&&this.genLoader()],n=this.generateRouteLink(),r=n.tag,i=n.data,a=this.hasBg?this.setBackgroundColor:this.setTextColor;return"button"===r&&(i.attrs.type=this.type,i.attrs.disabled=this.disabled),i.attrs.value=["string","number"].includes(p(this.value))?this.value:JSON.stringify(this.value),t(r,this.disabled?i:a(this.color,i),e)}})},"./src/components/VBtn/index.ts": +/*!**************************************!*\ + !*** ./src/components/VBtn/index.ts ***! + \**************************************/ +/*! exports provided: VBtn, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VBtn */"./src/components/VBtn/VBtn.ts");n.d(e,"VBtn",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VBtnToggle/VBtnToggle.sass": +/*!***************************************************!*\ + !*** ./src/components/VBtnToggle/VBtnToggle.sass ***! + \***************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VBtnToggle/VBtnToggle.ts": +/*!*************************************************!*\ + !*** ./src/components/VBtnToggle/VBtnToggle.ts ***! + \*************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VBtnToggle.sass */"./src/components/VBtnToggle/VBtnToggle.sass");var r=n(/*! ../../mixins/button-group */"./src/mixins/button-group/index.ts"),i=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),a=n(/*! ../../util/mixins */"./src/util/mixins.ts"),o=function(){return o=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0,r=n?a["nextDay"]:a["prevDay"],i=n?a["DAYS_IN_MONTH_MAX"]:a["DAY_MIN"],o=n?t:-t;while(--o>=0)switch(this.type){case"month":e.day=i,r(e);break;case"week":Object(a["relativeDays"])(e,r,a["DAYS_IN_WEEK"]);break;case"day":Object(a["relativeDays"])(e,r,1);break;case"4day":Object(a["relativeDays"])(e,r,4);break;case"category":Object(a["relativeDays"])(e,r,this.parsedCategoryDays);break}Object(a["updateWeekday"])(e),Object(a["updateFormatted"])(e),Object(a["updateRelative"])(e,this.times.now),this.value instanceof Date?this.$emit("input",Object(a["timestampToDate"])(e)):"number"===typeof this.value?this.$emit("input",Object(a["timestampToDate"])(e).getTime()):this.$emit("input",e.date),this.$emit("moved",e)},next:function(t){void 0===t&&(t=1),this.move(t)},prev:function(t){void 0===t&&(t=1),this.move(-t)},timeToY:function(t,e){void 0===e&&(e=!0);var n=this.$children[0];return!(!n||!n.timeToY)&&n.timeToY(t,e)},timeDelta:function(t){var e=this.$children[0];return!(!e||!e.timeDelta)&&e.timeDelta(t)},minutesToPixels:function(t){var e=this.$children[0];return e&&e.minutesToPixels?e.minutesToPixels(t):-1},scrollToTime:function(t){var e=this.$children[0];return!(!e||!e.scrollToTime)&&e.scrollToTime(t)},parseTimestamp:function(t,e){return Object(a["parseTimestamp"])(t,e,this.times.now)},timestampToDate:function(t){return Object(a["timestampToDate"])(t)},getCategoryList:function(t){var e=this;if(!this.noEvents){var n=t.reduce((function(t,e,n){return"object"===h(e)&&e.categoryName?t[e.categoryName]={index:n,count:0}:"string"===typeof e&&(t[e]={index:n,count:0}),t}),{});if(!this.categoryHideDynamic||!this.categoryShowAll){var r=t.length;this.parsedEvents.forEach((function(t){var i=t.category;"string"!==typeof i&&(i=e.categoryForInvalid),i&&(i in n?n[i].count++:e.categoryHideDynamic||(n[i]={index:r++,count:1}))}))}if(!this.categoryShowAll)for(var i in n)0===n[i].count&&delete n[i];t=t.filter((function(t){return"object"===h(t)&&t.categoryName?n.hasOwnProperty(t.categoryName):"string"===typeof t&&n.hasOwnProperty(t)}))}return t}},render:function(t){var e=this,n=this.renderProps,r=n.start,i=n.end,a=n.maxDays,o=n.component,s=n.weekdays,l=n.categories;return t(o,{staticClass:"v-calendar",class:{"v-calendar-events":!this.noEvents},props:d(d({},this.$props),{start:r.date,end:i.date,maxDays:a,weekdays:s,categories:l}),attrs:{role:"grid"},directives:[{modifiers:{quiet:!0},name:"resize",value:this.updateEventVisibility}],on:d(d({},this.$listeners),{"click:date":function(t,n){e.$listeners.input&&e.$emit("input",t.date),e.$listeners["click:date"]&&e.$emit("click:date",t,n)}}),scopedSlots:this.getScopedSlots()})}})},"./src/components/VCalendar/VCalendarCategory.sass": +/*!*********************************************************!*\ + !*** ./src/components/VCalendar/VCalendarCategory.sass ***! + \*********************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VCalendar/VCalendarCategory.ts": +/*!*******************************************************!*\ + !*** ./src/components/VCalendar/VCalendarCategory.ts ***! + \*******************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VCalendarCategory.sass */"./src/components/VCalendar/VCalendarCategory.sass");var r=n(/*! ./VCalendarDaily */"./src/components/VCalendar/VCalendarDaily.ts"),i=n(/*! ../../util/helpers */"./src/util/helpers.ts"),a=n(/*! ./util/props */"./src/components/VCalendar/util/props.ts"),o=n(/*! ./util/parser */"./src/components/VCalendar/util/parser.ts");function s(t){return s="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},s(t)}var l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},u=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},c=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},h=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;iObject(l["getDayIdentifier"])(this.parsedEnd)},genHead:function(){return this.$createElement("div",{staticClass:"v-calendar-weekly__head",attrs:{role:"row"}},this.genHeadDays())},genHeadDays:function(){var t=this.todayWeek.map(this.genHeadDay);return this.showWeek&&t.unshift(this.$createElement("div",{staticClass:"v-calendar-weekly__head-weeknumber"})),t},genHeadDay:function(t,e){var n=this.isOutside(this.days[e]),r=t.present?this.color:void 0;return this.$createElement("div",this.setTextColor(r,{key:t.date,staticClass:"v-calendar-weekly__head-weekday",class:this.getRelativeClasses(t,n),attrs:{role:"columnheader"}}),this.weekdayFormatter(t,this.shortWeekdays))},genWeeks:function(){for(var t=this.days,e=this.parsedWeekdays.length,n=[],r=0;r0?"numeric":void 0});return n(t,!0)},updateEventVisibility:function(){if(!this.noEvents&&this.eventMore){var t=this.eventHeight,e=this.getEventsMap();for(var n in e){var r=e[n],i=r.parent,a=r.events,o=r.more;if(!o)break;for(var s=i.getBoundingClientRect(),l=a.length-1,c=a.map((function(t){return{event:t,bottom:t.getBoundingClientRect().bottom}})).sort((function(t,e){return t.bottom-e.bottom})),u=0,h=0;h<=l;h++){var d=c[h].bottom,f=h===l?d>s.bottom:d+t>s.bottom;f&&(c[h].event.style.display="none",u++)}u?(o.style.display="",o.innerHTML=this.$vuetify.lang.t(this.eventMoreText,u)):o.style.display="none"}}},getEventsMap:function(){var t={},e=this.$refs.events;return e&&e.forEach?(e.forEach((function(e){var n=e.getAttribute("data-date");e.parentElement&&n&&(n in t||(t[n]={parent:e.parentElement,more:null,events:[]}),e.getAttribute("data-more")?t[n].more=e:(t[n].events.push(e),e.style.display=""))})),t):t},genDayEvent:function(t,e){var n=t.event,r=this.eventHeight,i=this.eventMarginBottom,a=Object(s["getDayIdentifier"])(e),o=e.week,l=a===n.startIdentifier,c=a===n.endIdentifier,u=d;if(!this.categoryMode)for(var f=e.index+1;f=p)){c=!0;break}u+=h,c=c||p===n.endIdentifier}var v={eventParsed:n,day:e,start:l,end:c,timed:!1};return this.genEvent(n,v,!1,{staticClass:"v-event",class:{"v-event-start":l,"v-event-end":c},style:{height:r+"px",width:u+"%","margin-bottom":i+"px"},attrs:{"data-date":e.date},key:n.index,ref:"events",refInFor:!0})},genTimedEvent:function(t,e){var n=t.event,r=t.left,i=t.width;if(e.timeDelta(n.end)<0||e.timeDelta(n.start)>=1||Object(l["isEventHiddenOn"])(n,e))return!1;var a=Object(s["getDayIdentifier"])(e),o=n.startIdentifier>=a,c=n.endIdentifier>a,u=o?e.timeToY(n.start):0,h=c?e.timeToY(f):e.timeToY(n.end),d=Math.max(this.eventHeight,h-u),p={eventParsed:n,day:e,start:o,end:c,timed:!0};return this.genEvent(n,p,!0,{staticClass:"v-event-timed",style:{top:u+"px",height:d+"px",left:r+"%",width:i+"%"}})},genEvent:function(t,e,n,r){var i,a=this,o=this.$scopedSlots.event,l=this.eventTextColorFunction(t.input),c=this.eventColorFunction(t.input),h=t.start.hour<12&&t.end.hour>=12,d=Object(s["diffMinutes"])(t.start,t.end)<=this.parsedEventOverlapThreshold,f=this.formatTime,p=function(){return f(t.start,h)+" - "+f(t.end,!0)},v=function(){var e=a.eventNameFunction(t,n);if(t.start.hasTime){if(n){var r=p(),i=d?", ":a.$createElement("br");return a.$createElement("span",{staticClass:"v-event-summary"},[a.$createElement("strong",[e]),i,r])}r=f(t.start,!0);return a.$createElement("span",{staticClass:"v-event-summary"},[a.$createElement("strong",[r])," ",e])}return a.$createElement("span",{staticClass:"v-event-summary"},[e])},g=u(u({},e),{event:t.input,outside:e.day.outside,singline:d,overlapsNoon:h,formatTime:f,timeSummary:p,eventSummary:v});return this.$createElement("div",this.setTextColor(l,this.setBackgroundColor(c,u({on:this.getDefaultMouseEventHandlers(":event",(function(t){return u(u({},g),{nativeEvent:t})})),directives:[{name:"ripple",value:null===(i=this.eventRipple)||void 0===i||i}]},r))),o?o(g):[this.genName(v)])},genName:function(t){return this.$createElement("div",{staticClass:"pl-1"},[t()])},genPlaceholder:function(t){var e=this.eventHeight+this.eventMarginBottom;return this.$createElement("div",{style:{height:e+"px"},attrs:{"data-date":t.date},ref:"events",refInFor:!0})},genMore:function(t){var e,n=this.eventHeight,r=this.eventMarginBottom;return this.$createElement("div",{staticClass:"v-event-more pl-1",class:{"v-outside":t.outside},attrs:{"data-date":t.date,"data-more":1},directives:[{name:"ripple",value:null===(e=this.eventRipple)||void 0===e||e}],on:this.getDefaultMouseEventHandlers(":more",(function(e){return u({nativeEvent:e},t)})),style:{display:"none",height:n+"px","margin-bottom":r+"px"},ref:"events",refInFor:!0})},getVisibleEvents:function(){var t=Object(s["getDayIdentifier"])(this.days[0]),e=Object(s["getDayIdentifier"])(this.days[this.days.length-1]);return this.parsedEvents.filter((function(n){return Object(l["isEventOverlapping"])(n,t,e)}))},isEventForCategory:function(t,e){return!this.categoryMode||"object"===c(e)&&e.categoryName&&e.categoryName===t.category||"string"===typeof t.category&&e===t.category||"string"!==typeof t.category&&null===e},getEventsForDay:function(t){var e=Object(s["getDayIdentifier"])(t),n=this.eventWeekdays[0];return this.parsedEvents.filter((function(r){return Object(l["isEventStart"])(r,t,e,n)}))},getEventsForDayAll:function(t){var e=this,n=Object(s["getDayIdentifier"])(t),r=this.eventWeekdays[0];return this.parsedEvents.filter((function(i){return i.allDay&&(e.categoryMode?Object(l["isEventOn"])(i,n):Object(l["isEventStart"])(i,t,n,r))&&e.isEventForCategory(i,t.category)}))},getEventsForDayTimed:function(t){var e=this,n=Object(s["getDayIdentifier"])(t);return this.parsedEvents.filter((function(r){return!r.allDay&&Object(l["isEventOn"])(r,n)&&e.isEventForCategory(r,t.category)}))},getScopedSlots:function(){var t=this;if(this.noEvents)return u({},this.$scopedSlots);var e=this.eventModeFunction(this.parsedEvents,this.eventWeekdays[0],this.parsedEventOverlapThreshold),n=function(t){return!!t},r=function(r,i,a,o){var s=i(r),l=e(r,s,o,t.categoryMode);if(o)return l.map((function(t){return a(t,r)})).filter(n);var c=[];return l.forEach((function(e,n){while(c.length0&&t.eventMore&&n.push(t.genMore(e)),a){var i=a(e);i&&(n=n?n.concat(i):i)}return n},"day-header":function(e){var n=r(e,t.getEventsForDayAll,t.genDayEvent,!1);if(o){var i=o(e);i&&(n=n?n.concat(i):i)}return n},"day-body":function(e){var n=r(e,t.getEventsForDayTimed,t.genTimedEvent,!0),i=[t.$createElement("div",{staticClass:"v-event-timed-container"},n)];if(s){var a=s(e);a&&(i=i.concat(a))}return i}})}}})},"./src/components/VCalendar/mixins/calendar-with-intervals.ts": +/*!********************************************************************!*\ + !*** ./src/components/VCalendar/mixins/calendar-with-intervals.ts ***! + \********************************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./calendar-base */"./src/components/VCalendar/mixins/calendar-base.ts"),i=n(/*! ../util/props */"./src/components/VCalendar/util/props.ts"),a=n(/*! ../util/timestamp */"./src/components/VCalendar/util/timestamp.ts");e["default"]=r["default"].extend({name:"calendar-with-intervals",props:i["default"].intervals,computed:{parsedFirstInterval:function(){return parseInt(this.firstInterval)},parsedIntervalMinutes:function(){return parseInt(this.intervalMinutes)},parsedIntervalCount:function(){return parseInt(this.intervalCount)},parsedIntervalHeight:function(){return parseFloat(this.intervalHeight)},parsedFirstTime:function(){return Object(a["parseTime"])(this.firstTime)},firstMinute:function(){var t=this.parsedFirstTime;return!1!==t&&t>=0&&t<=a["MINUTES_IN_DAY"]?t:this.parsedFirstInterval*this.parsedIntervalMinutes},bodyHeight:function(){return this.parsedIntervalCount*this.parsedIntervalHeight},days:function(){return Object(a["createDayList"])(this.parsedStart,this.parsedEnd,this.times.today,this.weekdaySkips,this.maxDays)},intervals:function(){var t=this.days,e=this.firstMinute,n=this.parsedIntervalMinutes,r=this.parsedIntervalCount,i=this.times.now;return t.map((function(t){return Object(a["createIntervalList"])(t,e,n,r,i)}))},intervalFormatter:function(){if(this.intervalFormat)return this.intervalFormat;var t={timeZone:"UTC",hour:"2-digit",minute:"2-digit"},e={timeZone:"UTC",hour:"numeric",minute:"2-digit"},n={timeZone:"UTC",hour:"numeric"};return Object(a["createNativeLocaleFormatter"])(this.currentLocale,(function(r,i){return i?0===r.minute?n:e:t}))}},methods:{showIntervalLabelDefault:function(t){var e=this.intervals[0][0],n=e.hour===t.hour&&e.minute===t.minute;return!n},intervalStyleDefault:function(t){},getTimestampAtEvent:function(t,e){var n=Object(a["copyTimestamp"])(e),r=t.currentTarget.getBoundingClientRect(),i=this.firstMinute,o=t,s=t,l=o.changedTouches||o.touches,c=l&&l[0]?l[0].clientY:s.clientY,u=(c-r.top)/this.parsedIntervalHeight,h=Math.floor(u*this.parsedIntervalMinutes),d=i+h;return Object(a["updateMinutes"])(n,d,this.times.now)},getSlotScope:function(t){var e=Object(a["copyTimestamp"])(t);return e.timeToY=this.timeToY,e.timeDelta=this.timeDelta,e.minutesToPixels=this.minutesToPixels,e.week=this.days,e},scrollToTime:function(t){var e=this.timeToY(t),n=this.$refs.scrollArea;return!(!1===e||!n)&&(n.scrollTop=e,!0)},minutesToPixels:function(t){return t/this.parsedIntervalMinutes*this.parsedIntervalHeight},timeToY:function(t,e){void 0===e&&(e=!0);var n=this.timeDelta(t);return!1!==n&&(n*=this.bodyHeight,e&&(n<0&&(n=0),n>this.bodyHeight&&(n=this.bodyHeight))),n},timeDelta:function(t){var e=Object(a["parseTime"])(t);if(!1===e)return!1;var n=this.firstMinute,r=this.parsedIntervalCount*this.parsedIntervalMinutes;return(e-n)/r}}})},"./src/components/VCalendar/mixins/times.ts": +/*!**************************************************!*\ + !*** ./src/components/VCalendar/mixins/times.ts ***! + \**************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! vue */"vue"),i=n.n(r),a=n(/*! ../util/timestamp */"./src/components/VCalendar/util/timestamp.ts");e["default"]=i.a.extend({name:"times",props:{now:{type:String,validator:a["validateTimestamp"]}},data:function(){return{times:{now:Object(a["parseTimestamp"])("0000-00-00 00:00",!0),today:Object(a["parseTimestamp"])("0000-00-00",!0)}}},computed:{parsedNow:function(){return this.now?Object(a["parseTimestamp"])(this.now,!0):null}},watch:{parsedNow:"updateTimes"},created:function(){this.updateTimes(),this.setPresent()},methods:{setPresent:function(){this.times.now.present=this.times.today.present=!0,this.times.now.past=this.times.today.past=!1,this.times.now.future=this.times.today.future=!1},updateTimes:function(){var t=this.parsedNow||this.getNow();this.updateDay(t,this.times.now),this.updateTime(t,this.times.now),this.updateDay(t,this.times.today)},getNow:function(){return Object(a["parseDate"])(new Date)},updateDay:function(t,e){t.date!==e.date&&(e.year=t.year,e.month=t.month,e.day=t.day,e.weekday=t.weekday,e.date=t.date)},updateTime:function(t,e){t.time!==e.time&&(e.hour=t.hour,e.minute=t.minute,e.time=t.time)}}})},"./src/components/VCalendar/modes/column.ts": +/*!**************************************************!*\ + !*** ./src/components/VCalendar/modes/column.ts ***! + \**************************************************/ +/*! exports provided: column */function(t,e,n){"use strict";n.r(e),n.d(e,"column",(function(){return a}));var r=n(/*! ./common */"./src/components/VCalendar/modes/common.ts"),i=100,a=function(t,e,n){var a=Object(r["getOverlapGroupHandler"])(e);return function(t,e,n,r){var o=a.getVisuals(t,e,n,r);return n&&o.forEach((function(t){t.left=t.column*i/t.columnCount,t.width=i/t.columnCount})),o}}},"./src/components/VCalendar/modes/common.ts": +/*!**************************************************!*\ + !*** ./src/components/VCalendar/modes/common.ts ***! + \**************************************************/ +/*! exports provided: getVisuals, hasOverlap, setColumnCount, getRange, getDayRange, getNormalizedRange, getOpenGroup, getOverlapGroupHandler */function(t,e,n){"use strict";n.r(e),n.d(e,"getVisuals",(function(){return o})),n.d(e,"hasOverlap",(function(){return s})),n.d(e,"setColumnCount",(function(){return l})),n.d(e,"getRange",(function(){return c})),n.d(e,"getDayRange",(function(){return u})),n.d(e,"getNormalizedRange",(function(){return h})),n.d(e,"getOpenGroup",(function(){return d})),n.d(e,"getOverlapGroupHandler",(function(){return f}));var r=n(/*! ../util/timestamp */"./src/components/VCalendar/util/timestamp.ts"),i=function(t,e){var n="function"===typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,a=n.call(t),o=[];try{while((void 0===e||e-- >0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},a=864e5;function o(t,e){void 0===e&&(e=0);var n=t.map((function(t){return{event:t,columnCount:0,column:0,left:0,width:100}}));return n.sort((function(t,n){return Math.max(e,t.event.startTimestampIdentifier)-Math.max(e,n.event.startTimestampIdentifier)||n.event.endTimestampIdentifier-t.event.endTimestampIdentifier})),n}function s(t,e,n,r,i){return void 0===i&&(i=!0),i?!(t>=r||e<=n):!(t>r||e0&&!s(r,a,e.min,e.max,h)&&(l(e.groups),e.reset());var o=d(e.groups,r,a,h);-1===o&&(o=e.groups.length,e.groups.push({start:r,end:a,visuals:[]}));var f=e.groups[o];f.visuals.push(t),f.start=Math.min(f.start,r),f.end=Math.max(f.end,a),t.column=o,-1===e.min?(e.min=r,e.max=a):(e.min=Math.min(e.min,r),e.max=Math.max(e.max,a))})),l(e.groups),h&&e.reset(),v}};return e}},"./src/components/VCalendar/modes/index.ts": +/*!*************************************************!*\ + !*** ./src/components/VCalendar/modes/index.ts ***! + \*************************************************/ +/*! exports provided: CalendarEventOverlapModes */function(t,e,n){"use strict";n.r(e),n.d(e,"CalendarEventOverlapModes",(function(){return a}));var r=n(/*! ./stack */"./src/components/VCalendar/modes/stack.ts"),i=n(/*! ./column */"./src/components/VCalendar/modes/column.ts"),a={stack:r["stack"],column:i["column"]}},"./src/components/VCalendar/modes/stack.ts": +/*!*************************************************!*\ + !*** ./src/components/VCalendar/modes/stack.ts ***! + \*************************************************/ +/*! exports provided: stack */function(t,e,n){"use strict";n.r(e),n.d(e,"stack",(function(){return u}));var r=n(/*! ./common */"./src/components/VCalendar/modes/common.ts"),i=n(/*! ../util/timestamp */"./src/components/VCalendar/util/timestamp.ts"),a=function(t){var e="function"===typeof Symbol&&Symbol.iterator,n=e&&t[e],r=0;if(n)return n.call(t);if(t&&"number"===typeof t.length)return{next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},o=function(t,e){var n="function"===typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,a=n.call(t),o=[];try{while((void 0===e||e-- >0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},s=100,l=5,c=1.7,u=function(t,e,n){var s=Object(r["getOverlapGroupHandler"])(e);return function(t,e,l,c){var u,d,f,m,x,k;if(!l)return s.getVisuals(t,e,l,c);var S=Object(i["getTimestampIdentifier"])(t),C=Object(r["getVisuals"])(e,S),A=y(C,S);try{for(var _=a(A),D=_.next();!D.done;D=_.next()){var T=D.value,E=[];try{for(var O=(f=void 0,a(T.visuals)),P=O.next();!P.done;P=O.next()){var I=P.value,M=b(I,S),V=p(M,E);if(!1===V){var L=g(M,E);L&&(M.parent=L,M.sibling=Object(r["hasOverlap"])(M.start,M.end,L.start,w(L.start,n)),M.index=L.index+1,L.children.push(M))}else{var j=o(v(M,E,V-1,V-1),1),B=(L=j[0],v(M,E,V+1,V+E.length,!0));M.children=B,M.index=V,L&&(M.parent=L,M.sibling=Object(r["hasOverlap"])(M.start,M.end,L.start,w(L.start,n)),L.children.push(M));try{for(var R=(x=void 0,a(B)),F=R.next();!F.done;F=R.next()){var N=F.value;N.parent===L&&(N.parent=M);var z=N.index-M.index<=1;z&&M.sibling&&Object(r["hasOverlap"])(M.start,w(M.start,n),N.start,N.end)&&(N.sibling=!0)}}catch($){x={error:$}}finally{try{F&&!F.done&&(k=R.return)&&k.call(R)}finally{if(x)throw x.error}}}E.push(M)}}catch(Y){f={error:Y}}finally{try{P&&!P.done&&(m=O.return)&&m.call(O)}finally{if(f)throw f.error}}h(E,n)}}catch(H){u={error:H}}finally{try{D&&!D.done&&(d=_.return)&&d.call(_)}finally{if(u)throw u.error}}return C.sort((function(t,e){return t.left-e.left||t.event.startTimestampIdentifier-e.event.startTimestampIdentifier})),C}};function h(t,e){var n,r;try{for(var i=a(t),o=i.next();!o.done;o=i.next()){var u=o.value,h=u.visual,f=u.parent,p=x(u)+1,v=f?f.visual.left:0,g=s-v,y=Math.min(l,s/p),b=d(u,t),w=g/(p-u.index+1),k=g/(p-u.index+(u.sibling?1:0))*b;f&&(h.left=u.sibling?v+w:v+y),h.width=m(u,t,e)?s-h.left:Math.min(s-h.left,k*c)}}catch(S){n={error:S}}finally{try{o&&!o.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}}function d(t,e){if(!t.children.length)return 1;var n=t.index+e.length,r=t.children.reduce((function(t,e){return Math.min(t,e.index)}),n);return r-t.index}function f(t,e){var n,i,o=[];try{for(var s=a(e),l=s.next();!l.done;l=s.next()){var c=l.value;Object(r["hasOverlap"])(t.start,t.end,c.start,c.end)&&o.push(c.index)}}catch(u){n={error:u}}finally{try{l&&!l.done&&(i=s.return)&&i.call(s)}finally{if(n)throw n.error}}return o}function p(t,e){var n=f(t,e);n.sort();for(var r=0;r=n&&d.index<=i&&Object(r["hasOverlap"])(t.start,t.end,d.start,d.end)&&c.push(d)}}catch(p){s={error:p}}finally{try{h&&!h.done&&(l=u.return)&&l.call(u)}finally{if(s)throw s.error}}if(o&&c.length>0){var f=c.reduce((function(t,e){return Math.min(t,e.index)}),c[0].index);return c.filter((function(t){return t.index===f}))}return c}function g(t,e){var n,i,o=null;try{for(var s=a(e),l=s.next();!l.done;l=s.next()){var c=l.value;Object(r["hasOverlap"])(t.start,t.end,c.start,c.end)&&(null===o||c.index>o.index)&&(o=c)}}catch(u){n={error:u}}finally{try{l&&!l.done&&(i=s.return)&&i.call(s)}finally{if(n)throw n.error}}return o}function m(t,e,n){var i,o;try{for(var s=a(e),l=s.next();!l.done;l=s.next()){var c=l.value;if(c!==t&&c.index>t.index&&Object(r["hasOverlap"])(t.start,w(t.start,n),c.start,c.end))return!1}}catch(u){i={error:u}}finally{try{l&&!l.done&&(o=s.return)&&o.call(s)}finally{if(i)throw i.error}}return!0}function y(t,e){var n,i,s,l,c=[];try{for(var u=a(t),h=u.next();!h.done;h=u.next()){var d=h.value,f=o(Object(r["getNormalizedRange"])(d.event,e),2),p=f[0],v=f[1],g=!1;try{for(var m=(s=void 0,a(c)),y=m.next();!y.done;y=m.next()){var b=y.value;if(Object(r["hasOverlap"])(p,v,b.start,b.end)){b.visuals.push(d),b.end=Math.max(b.end,v),g=!0;break}}}catch(x){s={error:x}}finally{try{y&&!y.done&&(l=m.return)&&l.call(m)}finally{if(s)throw s.error}}g||c.push({start:p,end:v,visuals:[d]})}}catch(w){n={error:w}}finally{try{h&&!h.done&&(i=u.return)&&i.call(u)}finally{if(n)throw n.error}}return c}function b(t,e){var n=o(Object(r["getNormalizedRange"])(t.event,e),2),i=n[0],a=n[1];return{parent:null,sibling:!0,index:0,visual:t,start:i,end:a,children:[]}}function x(t){var e,n,r=t.index;try{for(var i=a(t.children),o=i.next();!o.done;o=i.next()){var s=o.value,l=x(s);l>r&&(r=l)}}catch(c){e={error:c}}finally{try{o&&!o.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}return r}function w(t,e){var n=t%100,r=n+e,i=Math.floor(r/60),a=r%60;return t-n+100*i+a}},"./src/components/VCalendar/util/events.ts": +/*!*************************************************!*\ + !*** ./src/components/VCalendar/util/events.ts ***! + \*************************************************/ +/*! exports provided: parseEvent, isEventOn, isEventHiddenOn, isEventStart, isEventOverlapping */function(t,e,n){"use strict";n.r(e),n.d(e,"parseEvent",(function(){return i})),n.d(e,"isEventOn",(function(){return a})),n.d(e,"isEventHiddenOn",(function(){return o})),n.d(e,"isEventStart",(function(){return s})),n.d(e,"isEventOverlapping",(function(){return l}));var r=n(/*! ./timestamp */"./src/components/VCalendar/util/timestamp.ts");function i(t,e,n,i,a,o){void 0===a&&(a=!1),void 0===o&&(o=!1);var s=t[n],l=t[i],c=Object(r["parseTimestamp"])(s,!0),u=l?Object(r["parseTimestamp"])(l,!0):c,h=Object(r["isTimedless"])(s)?Object(r["updateHasTime"])(c,a):c,d=Object(r["isTimedless"])(l)?Object(r["updateHasTime"])(u,a):u,f=Object(r["getDayIdentifier"])(h),p=Object(r["getTimestampIdentifier"])(h),v=Object(r["getDayIdentifier"])(d),g=h.hasTime?0:2359,m=Object(r["getTimestampIdentifier"])(d)+g,y=!h.hasTime;return{input:t,start:h,startIdentifier:f,startTimestampIdentifier:p,end:d,endIdentifier:v,endTimestampIdentifier:m,allDay:y,index:e,category:o}}function a(t,e){return e>=t.startIdentifier&&e<=t.endIdentifier}function o(t,e){return"00:00"===t.end.time&&t.end.date===e.date&&t.start.date!==e.date}function s(t,e,n,r){return n===t.startIdentifier||r===e.weekday&&a(t,n)}function l(t,e,n){return e<=t.endIdentifier&&n>=t.startIdentifier}},"./src/components/VCalendar/util/parser.ts": +/*!*************************************************!*\ + !*** ./src/components/VCalendar/util/parser.ts ***! + \*************************************************/ +/*! exports provided: parsedCategoryText, getParsedCategories */function(t,e,n){"use strict";function r(t){return r="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}n.r(e),n.d(e,"parsedCategoryText",(function(){return a})),n.d(e,"getParsedCategories",(function(){return o}));var i=function(){return i=Object.assign||function(t){for(var e,n=1,r=arguments.length;nr["DAYS_IN_WEEK"]||0===e.length)return!1;for(var n={},i=!1,a=0;a=r["DAYS_IN_WEEK"])return!1;if(a>0){var s=o-e[a-1];if(s<0){if(i)return!1;i=!0}else if(0===s)return!1}if(n[o])return!1;n[o]=!0}return!0}return!1}e["default"]={base:{start:{type:[String,Number,Date],validate:r["validateTimestamp"],default:function(){return Object(r["parseDate"])(new Date).date}},end:{type:[String,Number,Date],validate:r["validateTimestamp"]},weekdays:{type:[Array,String],default:function(){return[0,1,2,3,4,5,6]},validate:o},hideHeader:{type:Boolean},shortWeekdays:{type:Boolean,default:!0},weekdayFormat:{type:Function,default:null},dayFormat:{type:Function,default:null}},intervals:{maxDays:{type:Number,default:7},shortIntervals:{type:Boolean,default:!0},intervalHeight:{type:[Number,String],default:48,validate:a},intervalWidth:{type:[Number,String],default:60,validate:a},intervalMinutes:{type:[Number,String],default:60,validate:a},firstInterval:{type:[Number,String],default:0,validate:a},firstTime:{type:[Number,String,Object],validate:r["validateTime"]},intervalCount:{type:[Number,String],default:24,validate:a},intervalFormat:{type:Function,default:null},intervalStyle:{type:Function,default:null},showIntervalLabel:{type:Function,default:null}},weeks:{localeFirstDayOfYear:{type:[String,Number],default:0},minWeeks:{validate:a,default:1},shortMonths:{type:Boolean,default:!0},showMonthOnFirst:{type:Boolean,default:!0},showWeek:Boolean,monthFormat:{type:Function,default:null}},calendar:{type:{type:String,default:"month"},value:{type:[String,Number,Date],validate:r["validateTimestamp"]}},category:{categories:{type:[Array,String],default:""},categoryText:{type:[String,Function]},categoryHideDynamic:{type:Boolean},categoryShowAll:{type:Boolean},categoryForInvalid:{type:String,default:""},categoryDays:{type:[Number,String],default:1,validate:function(t){return isFinite(parseInt(t))&&parseInt(t)>0}}},events:{events:{type:Array,default:function(){return[]}},eventStart:{type:String,default:"start"},eventEnd:{type:String,default:"end"},eventTimed:{type:[String,Function],default:"timed"},eventCategory:{type:[String,Function],default:"category"},eventHeight:{type:Number,default:20},eventColor:{type:[String,Function],default:"primary"},eventTextColor:{type:[String,Function],default:"white"},eventName:{type:[String,Function],default:"name"},eventOverlapThreshold:{type:[String,Number],default:60},eventOverlapMode:{type:[String,Function],default:"stack",validate:function(t){return t in i["CalendarEventOverlapModes"]||"function"===typeof t}},eventMore:{type:Boolean,default:!0},eventMoreText:{type:String,default:"$vuetify.calendar.moreEvents"},eventRipple:{type:[Boolean,Object],default:null},eventMarginBottom:{type:Number,default:1}}}},"./src/components/VCalendar/util/timestamp.ts": +/*!****************************************************!*\ + !*** ./src/components/VCalendar/util/timestamp.ts ***! + \****************************************************/ +/*! exports provided: PARSE_REGEX, PARSE_TIME, DAYS_IN_MONTH, DAYS_IN_MONTH_LEAP, DAYS_IN_MONTH_MIN, DAYS_IN_MONTH_MAX, MONTH_MAX, MONTH_MIN, DAY_MIN, DAYS_IN_WEEK, MINUTES_IN_HOUR, MINUTE_MAX, MINUTES_IN_DAY, HOURS_IN_DAY, HOUR_MAX, FIRST_HOUR, OFFSET_YEAR, OFFSET_MONTH, OFFSET_HOUR, OFFSET_TIME, getStartOfWeek, getEndOfWeek, getStartOfMonth, getEndOfMonth, validateTime, parseTime, validateTimestamp, parseTimestamp, parseDate, getDayIdentifier, getTimeIdentifier, getTimestampIdentifier, updateRelative, isTimedless, updateHasTime, updateMinutes, updateWeekday, updateFormatted, getWeekday, daysInMonth, copyTimestamp, padNumber, getDate, getTime, nextMinutes, nextDay, prevDay, relativeDays, diffMinutes, findWeekday, getWeekdaySkips, timestampToDate, createDayList, createIntervalList, createNativeLocaleFormatter */function(t,e,n){"use strict";n.r(e),n.d(e,"PARSE_REGEX",(function(){return a})),n.d(e,"PARSE_TIME",(function(){return o})),n.d(e,"DAYS_IN_MONTH",(function(){return s})),n.d(e,"DAYS_IN_MONTH_LEAP",(function(){return l})),n.d(e,"DAYS_IN_MONTH_MIN",(function(){return c})),n.d(e,"DAYS_IN_MONTH_MAX",(function(){return u})),n.d(e,"MONTH_MAX",(function(){return h})),n.d(e,"MONTH_MIN",(function(){return d})),n.d(e,"DAY_MIN",(function(){return f})),n.d(e,"DAYS_IN_WEEK",(function(){return p})),n.d(e,"MINUTES_IN_HOUR",(function(){return v})),n.d(e,"MINUTE_MAX",(function(){return g})),n.d(e,"MINUTES_IN_DAY",(function(){return m})),n.d(e,"HOURS_IN_DAY",(function(){return y})),n.d(e,"HOUR_MAX",(function(){return b})),n.d(e,"FIRST_HOUR",(function(){return x})),n.d(e,"OFFSET_YEAR",(function(){return w})),n.d(e,"OFFSET_MONTH",(function(){return k})),n.d(e,"OFFSET_HOUR",(function(){return S})),n.d(e,"OFFSET_TIME",(function(){return C})),n.d(e,"getStartOfWeek",(function(){return A})),n.d(e,"getEndOfWeek",(function(){return _})),n.d(e,"getStartOfMonth",(function(){return D})),n.d(e,"getEndOfMonth",(function(){return T})),n.d(e,"validateTime",(function(){return E})),n.d(e,"parseTime",(function(){return O})),n.d(e,"validateTimestamp",(function(){return P})),n.d(e,"parseTimestamp",(function(){return I})),n.d(e,"parseDate",(function(){return M})),n.d(e,"getDayIdentifier",(function(){return V})),n.d(e,"getTimeIdentifier",(function(){return L})),n.d(e,"getTimestampIdentifier",(function(){return j})),n.d(e,"updateRelative",(function(){return B})),n.d(e,"isTimedless",(function(){return R})),n.d(e,"updateHasTime",(function(){return F})),n.d(e,"updateMinutes",(function(){return N})),n.d(e,"updateWeekday",(function(){return z})),n.d(e,"updateFormatted",(function(){return $})),n.d(e,"getWeekday",(function(){return Y})),n.d(e,"daysInMonth",(function(){return H})),n.d(e,"copyTimestamp",(function(){return W})),n.d(e,"padNumber",(function(){return X})),n.d(e,"getDate",(function(){return G})),n.d(e,"getTime",(function(){return U})),n.d(e,"nextMinutes",(function(){return q})),n.d(e,"nextDay",(function(){return Z})),n.d(e,"prevDay",(function(){return K})),n.d(e,"relativeDays",(function(){return J})),n.d(e,"diffMinutes",(function(){return Q})),n.d(e,"findWeekday",(function(){return tt})),n.d(e,"getWeekdaySkips",(function(){return et})),n.d(e,"timestampToDate",(function(){return nt})),n.d(e,"createDayList",(function(){return rt})),n.d(e,"createIntervalList",(function(){return it})),n.d(e,"createNativeLocaleFormatter",(function(){return at}));var r=n(/*! ../../../util/dateTimeUtils */"./src/util/dateTimeUtils.ts");function i(t){return i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i(t)}var a=/^(\d{4})-(\d{1,2})(-(\d{1,2}))?([^\d]+(\d{1,2}))?(:(\d{1,2}))?(:(\d{1,2}))?$/,o=/(\d\d?)(:(\d\d?)|)(:(\d\d?)|)/,s=[0,31,28,31,30,31,30,31,31,30,31,30,31],l=[0,31,29,31,30,31,30,31,31,30,31,30,31],c=28,u=31,h=12,d=1,f=1,p=7,v=60,g=59,m=1440,y=24,b=23,x=0,w=1e4,k=100,S=100,C=1e4;function A(t,e,n){var r=W(t);return tt(r,e[0],K),$(r),n&&B(r,n,r.hasTime),r}function _(t,e,n){var r=W(t);return tt(r,e[e.length-1]),$(r),n&&B(r,n,r.hasTime),r}function D(t){var e=W(t);return e.day=f,z(e),$(e),e}function T(t){var e=W(t);return e.day=H(e.year,e.month),z(e),$(e),e}function E(t){return"number"===typeof t&&isFinite(t)||!!o.exec(t)||"object"===i(t)&&isFinite(t.hour)&&isFinite(t.minute)}function O(t){if("number"===typeof t)return t;if("string"===typeof t){var e=o.exec(t);return!!e&&60*parseInt(e[1])+parseInt(e[3]||0)}return"object"===i(t)&&("number"===typeof t.hour&&"number"===typeof t.minute&&60*t.hour+t.minute)}function P(t){return"number"===typeof t&&isFinite(t)||"string"===typeof t&&!!a.exec(t)||t instanceof Date}function I(t,e,n){if(void 0===e&&(e=!1),"number"===typeof t&&isFinite(t)&&(t=new Date(t)),t instanceof Date){var r=M(t);return n&&B(r,n,r.hasTime),r}if("string"!==typeof t){if(e)throw new Error(t+" is not a valid timestamp. It must be a Date, number of milliseconds since Epoch, or a string in the format of YYYY-MM-DD or YYYY-MM-DD hh:mm. Zero-padding is optional and seconds are ignored.");return null}var i=a.exec(t);if(!i){if(e)throw new Error(t+" is not a valid timestamp. It must be a Date, number of milliseconds since Epoch, or a string in the format of YYYY-MM-DD or YYYY-MM-DD hh:mm. Zero-padding is optional and seconds are ignored.");return null}var o={date:t,time:"",year:parseInt(i[1]),month:parseInt(i[2]),day:parseInt(i[4])||1,hour:parseInt(i[6])||0,minute:parseInt(i[8])||0,weekday:0,hasDay:!!i[4],hasTime:!(!i[6]||!i[8]),past:!1,present:!1,future:!1};return z(o),$(o),n&&B(o,n,o.hasTime),o}function M(t){return $({date:"",time:"",year:t.getFullYear(),month:t.getMonth()+1,day:t.getDate(),weekday:t.getDay(),hour:t.getHours(),minute:t.getMinutes(),hasDay:!0,hasTime:!0,past:!1,present:!0,future:!1})}function V(t){return t.year*w+t.month*k+t.day}function L(t){return t.hour*S+t.minute}function j(t){return V(t)*C+L(t)}function B(t,e,n){void 0===n&&(n=!1);var r=V(e),i=V(t),a=r===i;return t.hasTime&&n&&a&&(r=L(e),i=L(t),a=r===i),t.past=ir,t}function R(t){return t instanceof Date||"number"===typeof t&&isFinite(t)}function F(t,e,n){return t.hasTime!==e&&(t.hasTime=e,e||(t.hour=b,t.minute=g,t.time=U(t)),n&&B(t,n,t.hasTime)),t}function N(t,e,n){return t.hasTime=!0,t.hour=Math.floor(e/v),t.minute=e%v,t.time=U(t),n&&B(t,n,!0),t}function z(t){return t.weekday=Y(t),t}function $(t){return t.time=U(t),t.date=G(t),t}function Y(t){if(t.hasDay){var e=Math.floor,n=t.day,r=(t.month+9)%h+1,i=e(t.year/100),a=t.year%100-(t.month<=2?1:0);return((n+e(2.6*r-.2)-2*i+a+e(a/4)+e(i/4))%7+7)%7}return t.weekday}function H(t,e){return Object(r["isLeapYear"])(t)?l[e]:s[e]}function W(t){var e=t.date,n=t.time,r=t.year,i=t.month,a=t.day,o=t.weekday,s=t.hour,l=t.minute,c=t.hasDay,u=t.hasTime,h=t.past,d=t.present,f=t.future;return{date:e,time:n,year:r,month:i,day:a,weekday:o,hour:s,minute:l,hasDay:c,hasTime:u,past:h,present:d,future:f}}function X(t,e){var n=String(t);while(n.lengthv)t.minute-=v,t.hour++,t.hour>=y&&(Z(t),t.hour=x);return t}function Z(t){return t.day++,t.weekday=(t.weekday+1)%p,t.day>c&&t.day>H(t.year,t.month)&&(t.day=f,t.month++,t.month>h&&(t.month=d,t.year++)),t}function K(t){return t.day--,t.weekday=(t.weekday+6)%p,t.day=0)e(t);return t}function Q(t,e){var n=525600*(e.year-t.year),r=43800*(e.month-t.month),i=1440*(e.day-t.day),a=60*(e.hour-t.hour),o=e.minute-t.minute;return n+r+i+a+o}function tt(t,e,n,r){void 0===n&&(n=Z),void 0===r&&(r=6);while(t.weekday!==e&&--r>=0)n(t);return t}function et(t){for(var e=[1,1,1,1,1,1,1],n=[0,0,0,0,0,0,0],r=0;r0}},mandatory:{type:Boolean,default:!0},progress:Boolean,progressColor:String,showArrows:{type:Boolean,default:!0},verticalDelimiters:{type:String,default:void 0}},provide:function(){return{parentTheme:this.theme}},data:function(){return{internalHeight:this.height,slideTimeout:void 0}},computed:{classes:function(){return u(u({},r["default"].options.computed.classes.call(this)),{"v-carousel":!0,"v-carousel--hide-delimiter-background":this.hideDelimiterBackground,"v-carousel--vertical-delimiters":this.isVertical})},isDark:function(){return this.dark||!this.light},isVertical:function(){return null!=this.verticalDelimiters}},watch:{internalValue:"restartTimeout",interval:"restartTimeout",height:function(t,e){t!==e&&t&&(this.internalHeight=t)},cycle:function(t){t?this.restartTimeout():(clearTimeout(this.slideTimeout),this.slideTimeout=void 0)}},created:function(){this.$attrs.hasOwnProperty("hide-controls")&&Object(c["breaking"])("hide-controls",':show-arrows="false"',this)},mounted:function(){this.startTimeout()},methods:{genControlIcons:function(){return this.isVertical?null:r["default"].options.methods.genControlIcons.call(this)},genDelimiters:function(){return this.$createElement("div",{staticClass:"v-carousel__controls",style:{left:"left"===this.verticalDelimiters&&this.isVertical?0:"auto",right:"right"===this.verticalDelimiters?0:"auto"}},[this.genItems()])},genItems:function(){for(var t=this,e=this.items.length,n=[],r=0;r0?+this.interval:6e3))}},render:function(t){var e=r["default"].options.render.call(this,t);return e.data.style="height: "+Object(l["convertToUnit"])(this.height)+";",this.hideDelimiters||e.children.push(this.genDelimiters()),(this.progress||this.progressColor)&&e.children.push(this.genProgress()),e}})},"./src/components/VCarousel/VCarouselItem.ts": +/*!***************************************************!*\ + !*** ./src/components/VCarousel/VCarouselItem.ts ***! + \***************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VWindow/VWindowItem */"./src/components/VWindow/VWindowItem.ts"),i=n(/*! ../VImg */"./src/components/VImg/index.ts"),a=n(/*! ../../util/mixins */"./src/util/mixins.ts"),o=n(/*! ../../util/helpers */"./src/util/helpers.ts"),s=n(/*! ../../mixins/routable */"./src/mixins/routable/index.ts"),l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=Object(r["default"])(o["default"],h["default"],u["default"],l["default"],Object(s["factory"])("chipGroup"),Object(c["factory"])("inputValue")).extend({name:"v-chip",props:{active:{type:Boolean,default:!0},activeClass:{type:String,default:function(){return this.chipGroup?this.chipGroup.activeClass:""}},close:Boolean,closeIcon:{type:String,default:"$delete"},closeLabel:{type:String,default:"$vuetify.close"},disabled:Boolean,draggable:Boolean,filter:Boolean,filterIcon:{type:String,default:"$complete"},label:Boolean,link:Boolean,outlined:Boolean,pill:Boolean,tag:{type:String,default:"span"},textColor:String,value:null},data:function(){return{proxyClass:"v-chip--active"}},computed:{classes:function(){return p(p(p(p(p({"v-chip":!0},u["default"].options.computed.classes.call(this)),{"v-chip--clickable":this.isClickable,"v-chip--disabled":this.disabled,"v-chip--draggable":this.draggable,"v-chip--label":this.label,"v-chip--link":this.isLink,"v-chip--no-color":!this.color,"v-chip--outlined":this.outlined,"v-chip--pill":this.pill,"v-chip--removable":this.hasClose}),this.themeClasses),this.sizeableClasses),this.groupClasses)},hasClose:function(){return Boolean(this.close)},isClickable:function(){return Boolean(u["default"].options.computed.isClickable.call(this)||this.chipGroup)}},created:function(){var t=this,e=[["outline","outlined"],["selected","input-value"],["value","active"],["@input","@active.sync"]];e.forEach((function(e){var n=v(e,2),r=n[0],i=n[1];t.$attrs.hasOwnProperty(r)&&Object(d["breaking"])(r,i,t)}))},methods:{click:function(t){this.$emit("click",t),this.chipGroup&&this.toggle()},genFilter:function(){var t=[];return this.isActive&&t.push(this.$createElement(a["default"],{staticClass:"v-chip__filter",props:{left:!0}},this.filterIcon)),this.$createElement(i["VExpandXTransition"],t)},genClose:function(){var t=this;return this.$createElement(a["default"],{staticClass:"v-chip__close",props:{right:!0,size:18},attrs:{"aria-label":this.$vuetify.lang.t(this.closeLabel)},on:{click:function(e){e.stopPropagation(),e.preventDefault(),t.$emit("click:close"),t.$emit("update:active",!1)}}},this.closeIcon)},genContent:function(){return this.$createElement("span",{staticClass:"v-chip__content"},[this.filter&&this.genFilter(),Object(f["getSlot"])(this),this.hasClose&&this.genClose()])}},render:function(t){var e=[this.genContent()],n=this.generateRouteLink(),r=n.tag,i=n.data;i.attrs=p(p({},i.attrs),{draggable:this.draggable?"true":void 0,tabindex:this.chipGroup&&!this.disabled?0:i.attrs.tabindex}),i.directives.push({name:"show",value:this.active}),i=this.setBackgroundColor(this.color,i);var a=this.textColor||this.outlined&&this.color;return t(r,this.setTextColor(a,i),e)}})},"./src/components/VChip/index.ts": +/*!***************************************!*\ + !*** ./src/components/VChip/index.ts ***! + \***************************************/ +/*! exports provided: VChip, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VChip */"./src/components/VChip/VChip.ts");n.d(e,"VChip",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VChipGroup/VChipGroup.sass": +/*!***************************************************!*\ + !*** ./src/components/VChipGroup/VChipGroup.sass ***! + \***************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VChipGroup/VChipGroup.ts": +/*!*************************************************!*\ + !*** ./src/components/VChipGroup/VChipGroup.ts ***! + \*************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VChipGroup.sass */"./src/components/VChipGroup/VChipGroup.sass");var r=n(/*! ../VSlideGroup/VSlideGroup */"./src/components/VSlideGroup/VSlideGroup.ts"),i=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),a=n(/*! ../../util/mixins */"./src/util/mixins.ts"),o=function(){return o=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},u={rgba:{inputs:[["r",255,"int"],["g",255,"int"],["b",255,"int"],["a",1,"float"]],from:l["fromRGBA"]},hsla:{inputs:[["h",360,"int"],["s",1,"float"],["l",1,"float"],["a",1,"float"]],from:l["fromHSLA"]},hexa:{from:l["fromHexa"]}};e["default"]=s.a.extend({name:"v-color-picker-edit",props:{color:Object,disabled:Boolean,hideAlpha:Boolean,hideModeSwitch:Boolean,mode:{type:String,default:"rgba",validator:function(t){return Object.keys(u).includes(t)}}},data:function(){return{modes:u,internalMode:this.mode}},computed:{currentMode:function(){return this.modes[this.internalMode]}},watch:{mode:function(t){this.internalMode=t}},created:function(){this.internalMode=this.mode},methods:{getValue:function(t,e){return"float"===e?Math.round(100*t)/100:"int"===e?Math.round(t):0},parseValue:function(t,e){return"float"===e?parseFloat(t):"int"===e&&parseInt(t,10)||0},changeMode:function(){var t=Object.keys(this.modes),e=t.indexOf(this.internalMode),n=t[(e+1)%t.length];this.internalMode=n,this.$emit("update:mode",n)},genInput:function(t,e,n,r){return this.$createElement("div",{staticClass:"v-color-picker__input"},[this.$createElement("input",{key:t,attrs:e,domProps:{value:n},on:r}),this.$createElement("span",t.toUpperCase())])},genInputs:function(){var t=this;if("hexa"===this.internalMode){var e=this.color.hexa,n=this.hideAlpha&&e.endsWith("FF")?e.substr(0,7):e;return this.genInput("hex",{maxlength:this.hideAlpha?7:9,disabled:this.disabled},n,{change:function(e){var n=e.target;t.$emit("update:color",t.currentMode.from(Object(a["parseHex"])(n.value)))}})}var r=this.hideAlpha?this.currentMode.inputs.slice(0,-1):this.currentMode.inputs;return r.map((function(e){var n=c(e,3),r=n[0],i=n[1],a=n[2],o=t.color[t.internalMode];return t.genInput(r,{type:"number",min:0,max:i,step:"float"===a?"0.01":"int"===a?"1":void 0,disabled:t.disabled},t.getValue(o[r],a),{input:function(e){var n,i=e.target,s=t.parseValue(i.value||"0",a);t.$emit("update:color",t.currentMode.from(Object.assign({},o,(n={},n[r]=s,n)),t.color.alpha))}})}))},genSwitch:function(){return this.$createElement(r["default"],{props:{small:!0,icon:!0,disabled:this.disabled},on:{click:this.changeMode}},[this.$createElement(i["default"],"$unfold")])}},render:function(t){return t("div",{staticClass:"v-color-picker__edit"},[this.genInputs(),!this.hideModeSwitch&&this.genSwitch()])}})},"./src/components/VColorPicker/VColorPickerPreview.sass": +/*!**************************************************************!*\ + !*** ./src/components/VColorPicker/VColorPickerPreview.sass ***! + \**************************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VColorPicker/VColorPickerPreview.ts": +/*!************************************************************!*\ + !*** ./src/components/VColorPicker/VColorPickerPreview.ts ***! + \************************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VColorPickerPreview.sass */"./src/components/VColorPicker/VColorPickerPreview.sass");var r=n(/*! ../VSlider/VSlider */"./src/components/VSlider/VSlider.ts"),i=n(/*! ../../util/colorUtils */"./src/util/colorUtils.ts"),a=n(/*! vue */"vue"),o=n.n(a),s=n(/*! ./util */"./src/components/VColorPicker/util/index.ts"),l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n2&&this.color.alpha>.5,light:Object(c["contrastRatio"])(this.color.rgba,d)>2&&this.color.alpha>.5}},"$success")]);return this.$createElement("div",{staticClass:"v-color-picker__color",on:{click:function(){return e.disabled||e.$emit("update:color",Object(a["fromHex"])("transparent"===t?"#00000000":t))}}},[n])},genSwatches:function(){var t=this;return this.swatches.map((function(e){var n=e.map(t.genColor);return t.$createElement("div",{staticClass:"v-color-picker__swatch"},n)}))}},render:function(t){return t("div",{staticClass:"v-color-picker__swatches",style:{maxWidth:Object(o["convertToUnit"])(this.maxWidth),maxHeight:Object(o["convertToUnit"])(this.maxHeight)}},[this.$createElement("div",this.genSwatches())])}})},"./src/components/VColorPicker/index.ts": +/*!**********************************************!*\ + !*** ./src/components/VColorPicker/index.ts ***! + \**********************************************/ +/*! exports provided: VColorPicker, VColorPickerSwatches, VColorPickerCanvas, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VColorPicker */"./src/components/VColorPicker/VColorPicker.ts");n.d(e,"VColorPicker",(function(){return r["default"]}));var i=n(/*! ./VColorPickerSwatches */"./src/components/VColorPicker/VColorPickerSwatches.ts");n.d(e,"VColorPickerSwatches",(function(){return i["default"]}));var a=n(/*! ./VColorPickerCanvas */"./src/components/VColorPicker/VColorPickerCanvas.ts");n.d(e,"VColorPickerCanvas",(function(){return a["default"]})),e["default"]=r["default"]},"./src/components/VColorPicker/util/index.ts": +/*!***************************************************!*\ + !*** ./src/components/VColorPicker/util/index.ts ***! + \***************************************************/ +/*! exports provided: fromHSVA, fromHSLA, fromRGBA, fromHexa, fromHex, parseColor, extractColor, hasAlpha */function(t,e,n){"use strict";n.r(e),n.d(e,"fromHSVA",(function(){return s})),n.d(e,"fromHSLA",(function(){return l})),n.d(e,"fromRGBA",(function(){return c})),n.d(e,"fromHexa",(function(){return u})),n.d(e,"fromHex",(function(){return h})),n.d(e,"parseColor",(function(){return f})),n.d(e,"extractColor",(function(){return v})),n.d(e,"hasAlpha",(function(){return g}));var r=n(/*! ../../../util/colorUtils */"./src/util/colorUtils.ts");function i(t){return i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i(t)}var a=function(){return a=Object.assign||function(t){for(var e,n=1,r=arguments.length;n7:"object"===i(t)&&(d(t,["a"])||d(t,["alpha"])))}},"./src/components/VCombobox/VCombobox.ts": +/*!***********************************************!*\ + !*** ./src/components/VCombobox/VCombobox.ts ***! + \***********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ../VAutocomplete/VAutocomplete.sass */"./src/components/VAutocomplete/VAutocomplete.sass");var r=n(/*! ../VSelect/VSelect */"./src/components/VSelect/VSelect.ts"),i=n(/*! ../VAutocomplete/VAutocomplete */"./src/components/VAutocomplete/VAutocomplete.ts"),a=n(/*! ../../util/helpers */"./src/util/helpers.ts");function o(t){return o="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},o(t)}var s=function(){return s=Object.assign||function(t){for(var e,n=1,r=arguments.length;n-1||this.$nextTick(this.updateSelf)},onKeyDown:function(t){var e=t.keyCode;!t.ctrlKey&&[a["keyCodes"].home,a["keyCodes"].end].includes(e)||r["default"].options.methods.onKeyDown.call(this,t),this.multiple&&e===a["keyCodes"].left&&0===this.$refs.input.selectionStart?this.updateSelf():e===a["keyCodes"].enter&&this.onEnterDown(t),this.changeSelectedIndex(e)},onTabDown:function(t){if(this.multiple&&this.internalSearch&&-1===this.getMenuIndex())return t.preventDefault(),t.stopPropagation(),this.updateTags();i["default"].options.methods.onTabDown.call(this,t)},selectItem:function(t){this.editingIndex>-1?this.updateEditing():(i["default"].options.methods.selectItem.call(this,t),this.internalSearch&&this.multiple&&this.getText(t).toLocaleLowerCase().includes(this.internalSearch.toLocaleLowerCase())&&(this.internalSearch=null))},setSelectedItems:function(){null==this.internalValue||""===this.internalValue?this.selectedItems=[]:this.selectedItems=this.multiple?this.internalValue:[this.internalValue]},setValue:function(t){r["default"].options.methods.setValue.call(this,void 0===t?this.internalSearch:t)},updateEditing:function(){var t=this,e=this.internalValue.slice(),n=this.selectedItems.findIndex((function(e){return t.getText(e)===t.internalSearch}));if(n>-1){var r="object"===o(e[n])?Object.assign({},e[n]):e[n];e.splice(n,1),e.push(r)}else e[this.editingIndex]=this.internalSearch;this.setValue(e),this.editingIndex=-1,this.internalSearch=null},updateCombobox:function(){if(this.searchIsDirty){this.internalSearch!==this.getText(this.internalValue)&&this.setValue();var t=Boolean(this.$scopedSlots.selection)||this.hasChips;t&&(this.internalSearch=null)}},updateSelf:function(){this.multiple?this.updateTags():this.updateCombobox()},updateTags:function(){var t=this,e=this.getMenuIndex();if(!(e<0&&!this.searchIsDirty||!this.internalSearch)){if(this.editingIndex>-1)return this.updateEditing();var n=this.selectedItems.findIndex((function(e){return t.internalSearch===t.getText(e)})),r=n>-1&&"object"===o(this.selectedItems[n])?Object.assign({},this.selectedItems[n]):this.internalSearch;if(n>-1){var i=this.internalValue.slice();i.splice(n,1),this.setValue(i)}if(e>-1)return this.internalSearch=null;this.selectItem(r),this.internalSearch=null}},onPaste:function(t){var e;if(this.$emit("paste",t),this.multiple&&!this.searchIsDirty){var n=null===(e=t.clipboardData)||void 0===e?void 0:e.getData("text/vnd.vuetify.autocomplete.item+plain");n&&-1===this.findExistingIndex(n)&&(t.preventDefault(),r["default"].options.methods.selectItem.call(this,n))}},clearableCallback:function(){this.editingIndex=-1,i["default"].options.methods.clearableCallback.call(this)}}})},"./src/components/VCombobox/index.ts": +/*!*******************************************!*\ + !*** ./src/components/VCombobox/index.ts ***! + \*******************************************/ +/*! exports provided: VCombobox, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VCombobox */"./src/components/VCombobox/VCombobox.ts");n.d(e,"VCombobox",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VContent/VContent.ts": +/*!*********************************************!*\ + !*** ./src/components/VContent/VContent.ts ***! + \*********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VMain/VMain */"./src/components/VMain/VMain.ts"),i=n(/*! ../../util/console */"./src/util/console.ts");e["default"]=r["default"].extend({name:"v-main",created:function(){Object(i["deprecate"])("v-content","v-main",this)},render:function(t){var e=r["default"].options.render.call(this,t);return e.data.staticClass+=" v-content",e.children[0].data.staticClass+=" v-content__wrap",t(e.tag,e.data,e.children)}})},"./src/components/VContent/index.ts": +/*!******************************************!*\ + !*** ./src/components/VContent/index.ts ***! + \******************************************/ +/*! exports provided: VContent, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VContent */"./src/components/VContent/VContent.ts");n.d(e,"VContent",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VCounter/VCounter.sass": +/*!***********************************************!*\ + !*** ./src/components/VCounter/VCounter.sass ***! + \***********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VCounter/VCounter.ts": +/*!*********************************************!*\ + !*** ./src/components/VCounter/VCounter.ts ***! + \*********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VCounter.sass */"./src/components/VCounter/VCounter.sass");var r=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),i=n(/*! ../../util/mixins */"./src/util/mixins.ts"),a=function(){return a=Object.assign||function(t){for(var e,n=1,r=arguments.length;ni;return t("div",{staticClass:"v-counter",class:a({"error--text":l},Object(r["functionalThemeClasses"])(e))},s)}})},"./src/components/VCounter/index.ts": +/*!******************************************!*\ + !*** ./src/components/VCounter/index.ts ***! + \******************************************/ +/*! exports provided: VCounter, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VCounter */"./src/components/VCounter/VCounter.ts");n.d(e,"VCounter",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VData/VData.ts": +/*!***************************************!*\ + !*** ./src/components/VData/VData.ts ***! + \***************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../../util/helpers */"./src/util/helpers.ts"),i=n(/*! vue */"vue"),a=n.n(i),o=function(){return o=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},l=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0&&(t=n.sortDesc).push.apply(t,l([],s(Object(r["fillArray"])(u,!1)),!1)),h>0&&(e=n.groupDesc).push.apply(e,l([],s(Object(r["fillArray"])(h,!1)),!1)),{internalOptions:n}},computed:{itemsLength:function(){return this.serverItemsLength>=0?this.serverItemsLength:this.filteredItems.length},pageCount:function(){return this.internalOptions.itemsPerPage<=0?1:Math.ceil(this.itemsLength/this.internalOptions.itemsPerPage)},pageStart:function(){return-1!==this.internalOptions.itemsPerPage&&this.items.length?(this.internalOptions.page-1)*this.internalOptions.itemsPerPage:0},pageStop:function(){return-1===this.internalOptions.itemsPerPage?this.itemsLength:this.items.length?Math.min(this.itemsLength,this.internalOptions.page*this.internalOptions.itemsPerPage):0},isGrouped:function(){return!!this.internalOptions.groupBy.length},pagination:function(){return{page:this.internalOptions.page,itemsPerPage:this.internalOptions.itemsPerPage,pageStart:this.pageStart,pageStop:this.pageStop,pageCount:this.pageCount,itemsLength:this.itemsLength}},filteredItems:function(){var t=this.items.slice();return!this.disableFiltering&&this.serverItemsLength<=0&&(t=this.customFilter(t,this.search)),t},computedItems:function(){var t=this.filteredItems.slice();return(!this.disableSort||this.internalOptions.groupBy.length)&&this.serverItemsLength<=0&&(t=this.sortItems(t)),!this.disablePagination&&this.serverItemsLength<=0&&(t=this.paginateItems(t)),t},groupedItems:function(){return this.isGrouped?this.groupItems(this.computedItems):null},scopedProps:function(){return{sort:this.sort,sortArray:this.sortArray,group:this.group,items:this.computedItems,options:this.internalOptions,updateOptions:this.updateOptions,pagination:this.pagination,groupedItems:this.groupedItems,originalItemsLength:this.items.length}},computedOptions:function(){return o({},this.options)}},watch:{computedOptions:{handler:function(t,e){Object(r["deepEqual"])(t,e)||this.updateOptions(t)},deep:!0,immediate:!0},internalOptions:{handler:function(t,e){Object(r["deepEqual"])(t,e)||this.$emit("update:options",t)},deep:!0,immediate:!0},page:function(t){this.updateOptions({page:t})},"internalOptions.page":function(t){this.$emit("update:page",t)},itemsPerPage:function(t){this.updateOptions({itemsPerPage:t})},"internalOptions.itemsPerPage":function(t){this.$emit("update:items-per-page",t)},sortBy:function(t){this.updateOptions({sortBy:Object(r["wrapInArray"])(t)})},"internalOptions.sortBy":function(t,e){!Object(r["deepEqual"])(t,e)&&this.$emit("update:sort-by",Array.isArray(this.sortBy)?t:t[0])},sortDesc:function(t){this.updateOptions({sortDesc:Object(r["wrapInArray"])(t)})},"internalOptions.sortDesc":function(t,e){!Object(r["deepEqual"])(t,e)&&this.$emit("update:sort-desc",Array.isArray(this.sortDesc)?t:t[0])},groupBy:function(t){this.updateOptions({groupBy:Object(r["wrapInArray"])(t)})},"internalOptions.groupBy":function(t,e){!Object(r["deepEqual"])(t,e)&&this.$emit("update:group-by",Array.isArray(this.groupBy)?t:t[0])},groupDesc:function(t){this.updateOptions({groupDesc:Object(r["wrapInArray"])(t)})},"internalOptions.groupDesc":function(t,e){!Object(r["deepEqual"])(t,e)&&this.$emit("update:group-desc",Array.isArray(this.groupDesc)?t:t[0])},multiSort:function(t){this.updateOptions({multiSort:t})},"internalOptions.multiSort":function(t){this.$emit("update:multi-sort",t)},mustSort:function(t){this.updateOptions({mustSort:t})},"internalOptions.mustSort":function(t){this.$emit("update:must-sort",t)},pageCount:{handler:function(t){this.$emit("page-count",t)},immediate:!0},computedItems:{handler:function(t){this.$emit("current-items",t)},immediate:!0},pagination:{handler:function(t,e){Object(r["deepEqual"])(t,e)||this.$emit("pagination",this.pagination)},immediate:!0}},methods:{toggle:function(t,e,n,i,a,o){var s=e.slice(),l=n.slice(),c=s.findIndex((function(e){return e===t}));return c<0?(o||(s=[],l=[]),s.push(t),l.push(!1)):c>=0&&!l[c]?l[c]=!0:a?l[c]=!1:(s.splice(c,1),l.splice(c,1)),Object(r["deepEqual"])(s,e)&&Object(r["deepEqual"])(l,n)||(i=1),{by:s,desc:l,page:i}},group:function(t){var e=this.toggle(t,this.internalOptions.groupBy,this.internalOptions.groupDesc,this.internalOptions.page,!0,!1),n=e.by,r=e.desc,i=e.page;this.updateOptions({groupBy:n,groupDesc:r,page:i})},sort:function(t){if(Array.isArray(t))return this.sortArray(t);var e=this.toggle(t,this.internalOptions.sortBy,this.internalOptions.sortDesc,this.internalOptions.page,this.internalOptions.mustSort,this.internalOptions.multiSort),n=e.by,r=e.desc,i=e.page;this.updateOptions({sortBy:n,sortDesc:r,page:i})},sortArray:function(t){var e=this,n=t.map((function(t){var n=e.internalOptions.sortBy.findIndex((function(e){return e===t}));return n>-1&&e.internalOptions.sortDesc[n]}));this.updateOptions({sortBy:t,sortDesc:n})},updateOptions:function(t){this.internalOptions=o(o(o({},this.internalOptions),t),{page:this.serverItemsLength<0?Math.max(1,Math.min(t.page||this.internalOptions.page,this.pageCount)):t.page||this.internalOptions.page})},sortItems:function(t){var e=[],n=[];return this.disableSort||(e=this.internalOptions.sortBy,n=this.internalOptions.sortDesc),this.internalOptions.groupBy.length&&(e=l(l([],s(this.internalOptions.groupBy),!1),s(e),!1),n=l(l([],s(this.internalOptions.groupDesc),!1),s(n),!1)),this.customSort(t,e,n,this.locale)},groupItems:function(t){return this.customGroup(t,this.internalOptions.groupBy,this.internalOptions.groupDesc)},paginateItems:function(t){return-1===this.serverItemsLength&&t.length<=this.pageStart&&(this.internalOptions.page=Math.max(1,Math.ceil(t.length/this.internalOptions.itemsPerPage))||1),t.slice(this.pageStart,this.pageStop)}},render:function(){return this.$scopedSlots.default&&this.$scopedSlots.default(this.scopedProps)}})},"./src/components/VData/index.ts": +/*!***************************************!*\ + !*** ./src/components/VData/index.ts ***! + \***************************************/ +/*! exports provided: VData, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VData */"./src/components/VData/VData.ts");n.d(e,"VData",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VDataIterator/VDataFooter.sass": +/*!*******************************************************!*\ + !*** ./src/components/VDataIterator/VDataFooter.sass ***! + \*******************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VDataIterator/VDataFooter.ts": +/*!*****************************************************!*\ + !*** ./src/components/VDataIterator/VDataFooter.ts ***! + \*****************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VDataFooter.sass */"./src/components/VDataIterator/VDataFooter.sass");var r=n(/*! ../VSelect/VSelect */"./src/components/VSelect/VSelect.ts"),i=n(/*! ../VIcon */"./src/components/VIcon/index.ts"),a=n(/*! ../VBtn */"./src/components/VBtn/index.ts"),o=n(/*! vue */"vue"),s=n.n(o),l=n(/*! ../../util/helpers */"./src/util/helpers.ts");function c(t){return c="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},c(t)}e["default"]=s.a.extend({name:"v-data-footer",props:{options:{type:Object,required:!0},pagination:{type:Object,required:!0},itemsPerPageOptions:{type:Array,default:function(){return[5,10,15,-1]}},prevIcon:{type:String,default:"$prev"},nextIcon:{type:String,default:"$next"},firstIcon:{type:String,default:"$first"},lastIcon:{type:String,default:"$last"},itemsPerPageText:{type:String,default:"$vuetify.dataFooter.itemsPerPageText"},itemsPerPageAllText:{type:String,default:"$vuetify.dataFooter.itemsPerPageAll"},showFirstLastPage:Boolean,showCurrentPage:Boolean,disablePagination:Boolean,disableItemsPerPage:Boolean,pageText:{type:String,default:"$vuetify.dataFooter.pageText"}},computed:{disableNextPageIcon:function(){return this.options.itemsPerPage<=0||this.options.page*this.options.itemsPerPage>=this.pagination.itemsLength||this.pagination.pageStop<0},computedDataItemsPerPageOptions:function(){var t=this;return this.itemsPerPageOptions.map((function(e){return"object"===c(e)?e:t.genDataItemsPerPageOption(e)}))}},methods:{updateOptions:function(t){this.$emit("update:options",Object.assign({},this.options,t))},onFirstPage:function(){this.updateOptions({page:1})},onPreviousPage:function(){this.updateOptions({page:this.options.page-1})},onNextPage:function(){this.updateOptions({page:this.options.page+1})},onLastPage:function(){this.updateOptions({page:this.pagination.pageCount})},onChangeItemsPerPage:function(t){this.updateOptions({itemsPerPage:t,page:1})},genDataItemsPerPageOption:function(t){return{text:-1===t?this.$vuetify.lang.t(this.itemsPerPageAllText):String(t),value:t}},genItemsPerPageSelect:function(){var t=this.options.itemsPerPage,e=this.computedDataItemsPerPageOptions;return e.length<=1?null:(e.find((function(e){return e.value===t}))||(t=e[0]),this.$createElement("div",{staticClass:"v-data-footer__select"},[this.$vuetify.lang.t(this.itemsPerPageText),this.$createElement(r["default"],{attrs:{"aria-label":this.$vuetify.lang.t(this.itemsPerPageText)},props:{disabled:this.disableItemsPerPage,items:e,value:t,hideDetails:!0,auto:!0,minWidth:"75px"},on:{input:this.onChangeItemsPerPage}})]))},genPaginationInfo:function(){var t=["–"],e=this.pagination.itemsLength,n=this.pagination.pageStart,r=this.pagination.pageStop;return this.pagination.itemsLength&&this.pagination.itemsPerPage?(n=this.pagination.pageStart+1,r=e=this.pagination.pageCount||-1===this.options.itemsPerPage,this.$vuetify.lang.t("$vuetify.dataFooter.lastPage"),this.$vuetify.rtl?this.firstIcon:this.lastIcon))),[this.$createElement("div",{staticClass:"v-data-footer__icons-before"},t),this.showCurrentPage&&this.$createElement("span",[this.options.page.toString()]),this.$createElement("div",{staticClass:"v-data-footer__icons-after"},e)]}},render:function(){return this.$createElement("div",{staticClass:"v-data-footer"},[Object(l["getSlot"])(this,"prepend"),this.genItemsPerPageSelect(),this.genPaginationInfo(),this.genIcons()])}})},"./src/components/VDataIterator/VDataIterator.ts": +/*!*******************************************************!*\ + !*** ./src/components/VDataIterator/VDataIterator.ts ***! + \*******************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VData */"./src/components/VData/index.ts"),i=n(/*! ./VDataFooter */"./src/components/VDataIterator/VDataFooter.ts"),a=n(/*! ../../mixins/mobile */"./src/mixins/mobile/index.ts"),o=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),s=n(/*! ../../util/mixins */"./src/util/mixins.ts"),l=n(/*! ../../util/helpers */"./src/util/helpers.ts"),c=n(/*! ../../util/console */"./src/util/console.ts"),u=function(){return u=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=Object(s["default"])(a["default"],o["default"]).extend({name:"v-data-iterator",props:u(u({},r["VData"].options.props),{itemKey:{type:String,default:"id"},value:{type:Array,default:function(){return[]}},singleSelect:Boolean,expanded:{type:Array,default:function(){return[]}},mobileBreakpoint:u(u({},a["default"].options.props.mobileBreakpoint),{default:600}),singleExpand:Boolean,loading:[Boolean,String],noResultsText:{type:String,default:"$vuetify.dataIterator.noResultsText"},noDataText:{type:String,default:"$vuetify.noDataText"},loadingText:{type:String,default:"$vuetify.dataIterator.loadingText"},hideDefaultFooter:Boolean,footerProps:Object,selectableKey:{type:String,default:"isSelectable"}}),data:function(){return{selection:{},expansion:{},internalCurrentItems:[],shiftKeyDown:!1,lastEntry:-1}},computed:{everyItem:function(){var t=this;return!!this.selectableItems.length&&this.selectableItems.every((function(e){return t.isSelected(e)}))},someItems:function(){var t=this;return this.selectableItems.some((function(e){return t.isSelected(e)}))},sanitizedFooterProps:function(){return Object(l["camelizeObjectKeys"])(this.footerProps)},selectableItems:function(){var t=this;return this.internalCurrentItems.filter((function(e){return t.isSelectable(e)}))}},watch:{value:{handler:function(t){var e=this;this.selection=t.reduce((function(t,n){return t[Object(l["getObjectValueByPath"])(n,e.itemKey)]=n,t}),{})},immediate:!0},selection:function(t,e){Object(l["deepEqual"])(Object.keys(t),Object.keys(e))||this.$emit("input",Object.values(t))},expanded:{handler:function(t){var e=this;this.expansion=t.reduce((function(t,n){return t[Object(l["getObjectValueByPath"])(n,e.itemKey)]=!0,t}),{})},immediate:!0},expansion:function(t,e){var n=this;if(!Object(l["deepEqual"])(t,e)){var r=Object.keys(t).filter((function(e){return t[e]})),i=r.length?this.items.filter((function(t){return r.includes(String(Object(l["getObjectValueByPath"])(t,n.itemKey)))})):[];this.$emit("update:expanded",i)}}},created:function(){var t=this,e=[["disable-initial-sort","sort-by"],["filter","custom-filter"],["pagination","options"],["total-items","server-items-length"],["hide-actions","hide-default-footer"],["rows-per-page-items","footer-props.items-per-page-options"],["rows-per-page-text","footer-props.items-per-page-text"],["prev-icon","footer-props.prev-icon"],["next-icon","footer-props.next-icon"]];e.forEach((function(e){var n=h(e,2),r=n[0],i=n[1];t.$attrs.hasOwnProperty(r)&&Object(c["breaking"])(r,i,t)}));var n=["expand","content-class","content-props","content-tag"];n.forEach((function(e){t.$attrs.hasOwnProperty(e)&&Object(c["removed"])(e)}))},mounted:function(){window.addEventListener("keydown",this.onKeyDown),window.addEventListener("keyup",this.onKeyUp)},beforeDestroy:function(){window.removeEventListener("keydown",this.onKeyDown),window.removeEventListener("keyup",this.onKeyUp)},methods:{onKeyDown:function(t){this.shiftKeyDown=t.keyCode===l["keyCodes"].shift||t.shiftKey},onKeyUp:function(t){t.keyCode!==l["keyCodes"].shift&&t.shiftKey||(this.shiftKeyDown=!1)},toggleSelectAll:function(t){for(var e=Object.assign({},this.selection),n=0;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},s=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},o=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};function S(t,e,n){return function(r){var i=Object(m["getObjectValueByPath"])(t,r.value);return r.filter?r.filter(i,e,t):n(i,e,t)}}function C(t,e,n,r,i,a){return e="string"===typeof e?e.trim():null,"union"===a?e&&r.length||n.length?t.filter((function(t){return!(!n.length||!n.every(S(t,e,m["defaultFilter"])))||e&&r.some(S(t,e,i))})):t:"intersection"===a?t.filter((function(t){var a=n.every(S(t,e,m["defaultFilter"])),o=!e||r.some(S(t,e,i));return a&&o})):t}e["default"]=Object(g["default"])(i["VDataIterator"],f["default"],p["default"]).extend({name:"v-data-table",directives:{ripple:v["default"]},props:{headers:{type:Array,default:function(){return[]}},showSelect:Boolean,checkboxColor:String,showExpand:Boolean,showGroupBy:Boolean,height:[Number,String],hideDefaultHeader:Boolean,caption:String,dense:Boolean,headerProps:Object,calculateWidths:Boolean,fixedHeader:Boolean,headersLength:Number,expandIcon:{type:String,default:"$expand"},customFilter:{type:Function,default:m["defaultFilter"]},filterMode:{type:String,default:"intersection"},itemClass:{type:[String,Function],default:function(){return""}},itemStyle:{type:[String,Function],default:function(){return""}},loaderHeight:{type:[Number,String],default:4}},data:function(){return{internalGroupBy:[],openCache:{},widths:[]}},computed:{computedHeaders:function(){var t=this;if(!this.headers)return[];var e=this.headers.filter((function(e){return void 0===e.value||!t.internalGroupBy.find((function(t){return t===e.value}))})),n={text:"",sortable:!1,width:"1px"};if(this.showSelect){var r=e.findIndex((function(t){return"data-table-select"===t.value}));r<0?e.unshift(w(w({},n),{value:"data-table-select"})):e.splice(r,1,w(w({},n),e[r]))}if(this.showExpand){r=e.findIndex((function(t){return"data-table-expand"===t.value}));r<0?e.unshift(w(w({},n),{value:"data-table-expand"})):e.splice(r,1,w(w({},n),e[r]))}return e},colspanAttrs:function(){return this.isMobile?void 0:{colspan:this.headersLength||this.computedHeaders.length}},columnSorters:function(){return this.computedHeaders.reduce((function(t,e){return e.sort&&(t[e.value]=e.sort),t}),{})},headersWithCustomFilters:function(){return this.headers.filter((function(t){return t.filter&&(!t.hasOwnProperty("filterable")||!0===t.filterable)}))},headersWithoutCustomFilters:function(){return this.headers.filter((function(t){return!t.filter&&(!t.hasOwnProperty("filterable")||!0===t.filterable)}))},sanitizedHeaderProps:function(){return Object(m["camelizeObjectKeys"])(this.headerProps)},computedItemsPerPage:function(){var t=this.options&&this.options.itemsPerPage?this.options.itemsPerPage:this.itemsPerPage,e=this.sanitizedFooterProps.itemsPerPageOptions;if(e&&!e.find((function(e){return"number"===typeof e?e===t:e.value===t}))){var n=e[0];return"object"===x(n)?n.value:n}return t},groupByText:function(){var t,e,n,r=this;return null!==(n=null===(e=null===(t=this.headers)||void 0===t?void 0:t.find((function(t){var e;return t.value===(null===(e=r.internalGroupBy)||void 0===e?void 0:e[0])})))||void 0===e?void 0:e.text)&&void 0!==n?n:""}},created:function(){var t=this,e=[["sort-icon","header-props.sort-icon"],["hide-headers","hide-default-header"],["select-all","show-select"]];e.forEach((function(e){var n=k(e,2),r=n[0],i=n[1];t.$attrs.hasOwnProperty(r)&&Object(y["breaking"])(r,i,t)}))},mounted:function(){this.calculateWidths&&(window.addEventListener("resize",this.calcWidths),this.calcWidths())},beforeDestroy:function(){this.calculateWidths&&window.removeEventListener("resize",this.calcWidths)},methods:{calcWidths:function(){this.widths=Array.from(this.$el.querySelectorAll("th")).map((function(t){return t.clientWidth}))},customFilterWithColumns:function(t,e){return C(t,e,this.headersWithCustomFilters,this.headersWithoutCustomFilters,this.customFilter,this.filterMode)},customSortWithHeaders:function(t,e,n,r){return this.customSort(t,e,n,r,this.columnSorters)},createItemProps:function(t,e){var n=this,r=w(w({},i["VDataIterator"].options.methods.createItemProps.call(this,t,e)),{headers:this.computedHeaders});return w(w({},r),{attrs:{class:{"v-data-table__selected":r.isSelected}},on:w(w({},this.getDefaultMouseEventHandlers(":row",(function(){return r}),!0)),{click:function(e){return n.$emit("click:row",t,r,e)}})})},genCaption:function(t){return this.caption?[this.$createElement("caption",[this.caption])]:Object(m["getSlot"])(this,"caption",t,!0)},genColgroup:function(t){var e=this;return this.$createElement("colgroup",this.computedHeaders.map((function(t){return e.$createElement("col",{class:{divider:t.divider}})})))},genLoading:function(){var t=this.$createElement("th",{staticClass:"column",attrs:this.colspanAttrs},[this.genProgress()]),e=this.$createElement("tr",{staticClass:"v-data-table__progress"},[t]);return this.$createElement("thead",[e])},genHeaders:function(t){var e={props:w(w({},this.sanitizedHeaderProps),{headers:this.computedHeaders,options:t.options,mobile:this.isMobile,showGroupBy:this.showGroupBy,checkboxColor:this.checkboxColor,someItems:this.someItems,everyItem:this.everyItem,singleSelect:this.singleSelect,disableSort:this.disableSort}),on:{sort:t.sort,group:t.group,"toggle-select-all":this.toggleSelectAll}},n=[Object(m["getSlot"])(this,"header",w(w({},e),{isMobile:this.isMobile}))];if(!this.hideDefaultHeader){var r=Object(m["getPrefixedScopedSlots"])("header.",this.$scopedSlots);n.push(this.$createElement(o["default"],w(w({},e),{scopedSlots:r})))}return this.loading&&n.push(this.genLoading()),n},genEmptyWrapper:function(t){return this.$createElement("tr",{staticClass:"v-data-table__empty-wrapper"},[this.$createElement("td",{attrs:this.colspanAttrs},t)])},genItems:function(t,e){var n=this.genEmpty(e.originalItemsLength,e.pagination.itemsLength);return n?[n]:e.groupedItems?this.genGroupedRows(e.groupedItems,e):this.genRows(t,e)},genGroupedRows:function(t,e){var n=this;return t.map((function(t){return n.openCache.hasOwnProperty(t.name)||n.$set(n.openCache,t.name,!0),n.$scopedSlots.group?n.$scopedSlots.group({group:t.name,options:e.options,isMobile:n.isMobile,items:t.items,headers:n.computedHeaders}):n.genDefaultGroupedRow(t.name,t.items,e)}))},genDefaultGroupedRow:function(t,e,n){var r=this,i=!!this.openCache[t],o=[this.$createElement("template",{slot:"row.content"},this.genRows(e,n))],l=function(){return r.$set(r.openCache,t,!r.openCache[t])},u=function(){return n.updateOptions({groupBy:[],groupDesc:[]})};if(this.$scopedSlots["group.header"])o.unshift(this.$createElement("template",{slot:"column.header"},[this.$scopedSlots["group.header"]({group:t,groupBy:n.options.groupBy,isMobile:this.isMobile,items:e,headers:this.computedHeaders,isOpen:i,toggle:l,remove:u})]));else{var h=this.$createElement(a["default"],{staticClass:"ma-0",props:{icon:!0,small:!0},on:{click:l}},[this.$createElement(s["default"],[i?"$minus":"$plus"])]),d=this.$createElement(a["default"],{staticClass:"ma-0",props:{icon:!0,small:!0},on:{click:u}},[this.$createElement(s["default"],["$close"])]),f=this.$createElement("td",{staticClass:"text-start",attrs:this.colspanAttrs},[h,this.groupByText+": "+t,d]);o.unshift(this.$createElement("template",{slot:"column.header"},[f]))}return this.$scopedSlots["group.summary"]&&o.push(this.$createElement("template",{slot:"column.summary"},[this.$scopedSlots["group.summary"]({group:t,groupBy:n.options.groupBy,isMobile:this.isMobile,items:e,headers:this.computedHeaders,isOpen:i,toggle:l})])),this.$createElement(c["default"],{key:t,props:{value:i}},o)},genRows:function(t,e){return this.$scopedSlots.item?this.genScopedRows(t,e):this.genDefaultRows(t,e)},genScopedRows:function(t,e){for(var n=[],r=0;r0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},s=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i=0,c=this.options.sortDesc[i];n.class.push("sortable");var u=this.getAria(l,c),h=u.ariaLabel,d=u.ariaSort;n.attrs["aria-label"]+=(t.text?": ":"")+h,n.attrs["aria-sort"]=d,l&&(n.class.push("active"),n.class.push(c?"desc":"asc")),"end"===t.align?r.unshift(this.genSortIcon()):r.push(this.genSortIcon()),this.options.multiSort&&l&&r.push(this.$createElement("span",{class:"v-data-table-header__sort-badge"},[String(i+1)]))}return this.showGroupBy&&!1!==t.groupable&&r.push(this.genGroupByToggle(t)),this.$createElement("th",n,r)}},render:function(){var t=this;return this.$createElement("thead",{staticClass:"v-data-table-header"},[this.$createElement("tr",this.headers.map((function(e){return t.genHeader(e)})))])}})},"./src/components/VDataTable/VDataTableHeaderMobile.ts": +/*!*************************************************************!*\ + !*** ./src/components/VDataTable/VDataTableHeaderMobile.ts ***! + \*************************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../../util/mixins */"./src/util/mixins.ts"),i=n(/*! ../VSelect/VSelect */"./src/components/VSelect/VSelect.ts"),a=n(/*! ../VChip */"./src/components/VChip/index.ts"),o=n(/*! ./mixins/header */"./src/components/VDataTable/mixins/header.ts"),s=n(/*! ../../util/helpers */"./src/util/helpers.ts"),l=function(t,e){var n="function"===typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,a=n.call(t),o=[];try{while((void 0===e||e-- >0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},c=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i=0,o=this.options.sortDesc[r];return n.push(this.$createElement("div",{staticClass:"v-chip__close",class:{sortable:!0,active:i,asc:i&&!o,desc:i&&o}},[this.genSortIcon()])),this.$createElement(a["default"],{staticClass:"sortable",on:{click:function(n){n.stopPropagation(),e.$emit("sort",t.item.value)}}},n)},genSortSelect:function(t){var e=this;return this.$createElement(i["default"],{props:{label:this.$vuetify.lang.t(this.sortByText),items:t,hideDetails:!0,multiple:this.options.multiSort,value:this.options.multiSort?this.options.sortBy:this.options.sortBy[0],menuProps:{closeOnContentClick:!0}},on:{change:function(t){return e.$emit("sort",t)}},scopedSlots:{selection:function(t){return e.genSortChip(t)}}})}},render:function(t){var e=[],n=this.headers.find((function(t){return"data-table-select"===t.value}));n&&!this.singleSelect&&e.push(this.$createElement("div",{class:c(["v-data-table-header-mobile__select"],l(Object(s["wrapInArray"])(n.class)),!1),attrs:{width:n.width}},[this.genSelectAll()]));var r=this.headers.filter((function(t){return!1!==t.sortable&&"data-table-select"!==t.value})).map((function(t){return{text:t.text,value:t.value}}));!this.disableSort&&r.length&&e.push(this.genSortSelect(r));var i=e.length?t("th",[t("div",{staticClass:"v-data-table-header-mobile__wrapper"},e)]):void 0,a=t("tr",[i]);return t("thead",{staticClass:"v-data-table-header v-data-table-header-mobile"},[a])}})},"./src/components/VDataTable/VEditDialog.sass": +/*!****************************************************!*\ + !*** ./src/components/VDataTable/VEditDialog.sass ***! + \****************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VDataTable/VEditDialog.ts": +/*!**************************************************!*\ + !*** ./src/components/VDataTable/VEditDialog.ts ***! + \**************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VEditDialog.sass */"./src/components/VDataTable/VEditDialog.sass");var r=n(/*! ../../mixins/returnable */"./src/mixins/returnable/index.ts"),i=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),a=n(/*! ../../util/helpers */"./src/util/helpers.ts"),o=n(/*! ../VBtn */"./src/components/VBtn/index.ts"),s=n(/*! ../VMenu */"./src/components/VMenu/index.ts"),l=n(/*! ../../util/mixins */"./src/util/mixins.ts");e["default"]=Object(l["default"])(r["default"],i["default"]).extend({name:"v-edit-dialog",props:{cancelText:{default:"Cancel"},large:Boolean,eager:Boolean,persistent:Boolean,saveText:{default:"Save"},transition:{type:String,default:"slide-x-reverse-transition"}},data:function(){return{isActive:!1}},watch:{isActive:function(t){t?(this.$emit("open"),setTimeout(this.focus,50)):this.$emit("close")}},methods:{cancel:function(){this.isActive=!1,this.$emit("cancel")},focus:function(){var t=this.$refs.content.querySelector("input");t&&t.focus()},genButton:function(t,e){return this.$createElement(o["default"],{props:{text:!0,color:"primary",light:!0},on:{click:t}},e)},genActions:function(){var t=this;return this.$createElement("div",{class:"v-small-dialog__actions"},[this.genButton(this.cancel,this.cancelText),this.genButton((function(){t.save(t.returnValue),t.$emit("save")}),this.saveText)])},genContent:function(){var t=this;return this.$createElement("div",{staticClass:"v-small-dialog__content",on:{keydown:function(e){e.keyCode===a["keyCodes"].esc&&t.cancel(),e.keyCode===a["keyCodes"].enter&&(t.save(t.returnValue),t.$emit("save"))}},ref:"content"},Object(a["getSlot"])(this,"input"))}},render:function(t){var e=this;return t(s["default"],{staticClass:"v-small-dialog",class:this.themeClasses,props:{contentClass:"v-small-dialog__menu-content",transition:this.transition,origin:"top right",right:!0,value:this.isActive,closeOnClick:!this.persistent,closeOnContentClick:!1,eager:this.eager,light:this.light,dark:this.dark},on:{input:function(t){return e.isActive=t}},scopedSlots:{activator:function(n){var r=n.on;return t("div",{staticClass:"v-small-dialog__activator",on:r},[t("span",{staticClass:"v-small-dialog__activator__content"},Object(a["getSlot"])(e))])}}},[this.genContent(),this.large?this.genActions():null])}})},"./src/components/VDataTable/VSimpleTable.sass": +/*!*****************************************************!*\ + !*** ./src/components/VDataTable/VSimpleTable.sass ***! + \*****************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VDataTable/VSimpleTable.ts": +/*!***************************************************!*\ + !*** ./src/components/VDataTable/VSimpleTable.ts ***! + \***************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VSimpleTable.sass */"./src/components/VDataTable/VSimpleTable.sass");var r=n(/*! ../../util/helpers */"./src/util/helpers.ts"),i=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),a=n(/*! ../../util/mixins */"./src/util/mixins.ts"),o=function(){return o=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=Object(h["default"])(l["default"],c["default"]).extend({name:"v-date-picker",props:{activePicker:String,allowedDates:Function,dayFormat:Function,disabled:Boolean,events:{type:[Array,Function,Object],default:function(){return null}},eventColor:{type:[Array,Function,Object,String],default:function(){return"warning"}},firstDayOfWeek:{type:[String,Number],default:0},headerDateFormat:Function,localeFirstDayOfYear:{type:[String,Number],default:0},max:String,min:String,monthFormat:Function,multiple:Boolean,nextIcon:{type:String,default:"$next"},nextMonthAriaLabel:{type:String,default:"$vuetify.datePicker.nextMonthAriaLabel"},nextYearAriaLabel:{type:String,default:"$vuetify.datePicker.nextYearAriaLabel"},pickerDate:String,prevIcon:{type:String,default:"$prev"},prevMonthAriaLabel:{type:String,default:"$vuetify.datePicker.prevMonthAriaLabel"},prevYearAriaLabel:{type:String,default:"$vuetify.datePicker.prevYearAriaLabel"},range:Boolean,reactive:Boolean,readonly:Boolean,scrollable:Boolean,showCurrent:{type:[Boolean,String],default:!0},selectedItemsText:{type:String,default:"$vuetify.datePicker.itemsSelected"},showAdjacentMonths:Boolean,showWeek:Boolean,titleDateFormat:Function,type:{type:String,default:"date",validator:function(t){return["date","month"].includes(t)}},value:[Array,String],weekdayFormat:Function,yearFormat:Function,yearIcon:String},data:function(){var t=this,e=new Date;return{internalActivePicker:this.type.toUpperCase(),inputDay:null,inputMonth:null,inputYear:null,isReversing:!1,now:e,tableDate:function(){if(t.pickerDate)return t.pickerDate;var n=Object(d["wrapInArray"])(t.value),r=n[n.length-1]||("string"===typeof t.showCurrent?t.showCurrent:e.getFullYear()+"-"+(e.getMonth()+1));return Object(v["sanitizeDateString"])(r,"date"===t.type?"month":"year")}()}},computed:{multipleValue:function(){return Object(d["wrapInArray"])(this.value)},isMultiple:function(){return this.multiple||this.range},lastValue:function(){return this.isMultiple?this.multipleValue[this.multipleValue.length-1]:this.value},selectedMonths:function(){return this.value&&"month"!==this.type?this.isMultiple?this.multipleValue.map((function(t){return t.substr(0,7)})):this.value.substr(0,7):this.value},current:function(){return!0===this.showCurrent?Object(v["sanitizeDateString"])(this.now.getFullYear()+"-"+(this.now.getMonth()+1)+"-"+this.now.getDate(),this.type):this.showCurrent||null},inputDate:function(){return"date"===this.type?this.inputYear+"-"+Object(v["pad"])(this.inputMonth+1)+"-"+Object(v["pad"])(this.inputDay):this.inputYear+"-"+Object(v["pad"])(this.inputMonth+1)},tableMonth:function(){return Number((this.pickerDate||this.tableDate).split("-")[1])-1},tableYear:function(){return Number((this.pickerDate||this.tableDate).split("-")[0])},minMonth:function(){return this.min?Object(v["sanitizeDateString"])(this.min,"month"):null},maxMonth:function(){return this.max?Object(v["sanitizeDateString"])(this.max,"month"):null},minYear:function(){return this.min?Object(v["sanitizeDateString"])(this.min,"year"):null},maxYear:function(){return this.max?Object(v["sanitizeDateString"])(this.max,"year"):null},formatters:function(){return{year:this.yearFormat||Object(v["createNativeLocaleFormatter"])(this.currentLocale,{year:"numeric",timeZone:"UTC"},{length:4}),titleDate:this.titleDateFormat||(this.isMultiple?this.defaultTitleMultipleDateFormatter:this.defaultTitleDateFormatter)}},defaultTitleMultipleDateFormatter:function(){var t=this;return function(e){return e.length?1===e.length?t.defaultTitleDateFormatter(e[0]):t.$vuetify.lang.t(t.selectedItemsText,e.length):"-"}},defaultTitleDateFormatter:function(){var t={year:{year:"numeric",timeZone:"UTC"},month:{month:"long",timeZone:"UTC"},date:{weekday:"short",month:"short",day:"numeric",timeZone:"UTC"}},e=Object(v["createNativeLocaleFormatter"])(this.currentLocale,t[this.type],{start:0,length:{date:10,month:7,year:4}[this.type]}),n=function(t){return e(t).replace(/([^\d\s])([\d])/g,(function(t,e,n){return e+" "+n})).replace(", ",",
    ")};return this.landscape?n:e}},watch:{internalActivePicker:{immediate:!0,handler:function(t){this.$emit("update:active-picker",t)}},activePicker:function(t){this.internalActivePicker=t},tableDate:function(t,e){var n="month"===this.type?"year":"month";this.isReversing=Object(v["sanitizeDateString"])(t,n)0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=Object(c["default"])(a["default"],o["default"],s["default"]).extend({name:"v-date-picker-header",props:{disabled:Boolean,format:Function,min:String,max:String,nextAriaLabel:String,nextIcon:{type:String,default:"$next"},prevAriaLabel:String,prevIcon:{type:String,default:"$prev"},readonly:Boolean,value:{type:[Number,String],required:!0}},data:function(){return{isReversing:!1}},computed:{formatter:function(){return this.format?this.format:String(this.value).split("-")[1]?Object(l["createNativeLocaleFormatter"])(this.currentLocale,{month:"long",year:"numeric",timeZone:"UTC"},{length:7}):Object(l["createNativeLocaleFormatter"])(this.currentLocale,{year:"numeric",timeZone:"UTC"},{length:4})}},watch:{value:function(t,e){this.isReversing=t0?this.nextAriaLabel:this.prevAriaLabel,a=n?this.$vuetify.lang.t(n):void 0,o=this.disabled||t<0&&this.min&&this.calculateChange(t)0&&this.max&&this.calculateChange(t)>this.max;return this.$createElement(r["default"],{attrs:{"aria-label":a},props:{dark:this.dark,disabled:o,icon:!0,light:this.light},on:{click:function(n){n.stopPropagation(),e.$emit("input",e.calculateChange(t))}}},[this.$createElement(i["default"],t<0===!this.$vuetify.rtl?this.prevIcon:this.nextIcon)])},calculateChange:function(t){var e=d(String(this.value).split("-").map(Number),2),n=e[0],r=e[1];return null==r?""+(n+t):Object(l["monthChange"])(String(this.value),t)},genHeader:function(){var t=this,e=!this.disabled&&(this.color||"accent"),n=this.$createElement("div",this.setTextColor(e,{key:String(this.value)}),[this.$createElement("button",{attrs:{type:"button"},on:{click:function(){return t.$emit("toggle")}}},Object(u["getSlot"])(this)||[this.formatter(String(this.value))])]),r=this.$createElement("transition",{props:{name:this.isReversing===!this.$vuetify.rtl?"tab-reverse-transition":"tab-transition"}},[n]);return this.$createElement("div",{staticClass:"v-date-picker-header__value",class:{"v-date-picker-header__value--disabled":this.disabled}},[r])}},render:function(){return this.$createElement("div",{staticClass:"v-date-picker-header",class:h({"v-date-picker-header--disabled":this.disabled},this.themeClasses)},[this.genBtn(-1),this.genHeader(),this.genBtn(1)])}})},"./src/components/VDatePicker/VDatePickerMonthTable.ts": +/*!*************************************************************!*\ + !*** ./src/components/VDatePicker/VDatePickerMonthTable.ts ***! + \*************************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./mixins/date-picker-table */"./src/components/VDatePicker/mixins/date-picker-table.ts"),i=n(/*! ./util */"./src/components/VDatePicker/util/index.ts"),a=n(/*! ../../util/mixins */"./src/util/mixins.ts");e["default"]=Object(a["default"])(r["default"]).extend({name:"v-date-picker-month-table",computed:{formatter:function(){return this.format||Object(i["createNativeLocaleFormatter"])(this.currentLocale,{month:"short",timeZone:"UTC"},{start:5,length:2})}},methods:{calculateTableDate:function(t){return""+(parseInt(this.tableDate,10)+Math.sign(t||1))},genTBody:function(){for(var t=this,e=[],n=Array(3).fill(null),r=12/n.length,a=function(r){var a=n.map((function(e,a){var o=r*n.length+a,s=t.displayedYear+"-"+Object(i["pad"])(o+1);return t.$createElement("td",{key:o},[t.genButton(s,!1,"month",t.formatter)])}));e.push(o.$createElement("tr",{key:r},a))},o=this,s=0;s=r;i--)t.push(this.genYearItem(i));return t}},render:function(){return this.$createElement("ul",{staticClass:"v-date-picker-years",ref:"years"},this.genYearItems())}})},"./src/components/VDatePicker/index.ts": +/*!*********************************************!*\ + !*** ./src/components/VDatePicker/index.ts ***! + \*********************************************/ +/*! exports provided: VDatePicker, VDatePickerTitle, VDatePickerHeader, VDatePickerDateTable, VDatePickerMonthTable, VDatePickerYears, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VDatePicker */"./src/components/VDatePicker/VDatePicker.ts");n.d(e,"VDatePicker",(function(){return r["default"]}));var i=n(/*! ./VDatePickerTitle */"./src/components/VDatePicker/VDatePickerTitle.ts");n.d(e,"VDatePickerTitle",(function(){return i["default"]}));var a=n(/*! ./VDatePickerHeader */"./src/components/VDatePicker/VDatePickerHeader.ts");n.d(e,"VDatePickerHeader",(function(){return a["default"]}));var o=n(/*! ./VDatePickerDateTable */"./src/components/VDatePicker/VDatePickerDateTable.ts");n.d(e,"VDatePickerDateTable",(function(){return o["default"]}));var s=n(/*! ./VDatePickerMonthTable */"./src/components/VDatePicker/VDatePickerMonthTable.ts");n.d(e,"VDatePickerMonthTable",(function(){return s["default"]}));var l=n(/*! ./VDatePickerYears */"./src/components/VDatePicker/VDatePickerYears.ts");n.d(e,"VDatePickerYears",(function(){return l["default"]})),e["default"]={$_vuetify_subcomponents:{VDatePicker:r["default"],VDatePickerTitle:i["default"],VDatePickerHeader:a["default"],VDatePickerDateTable:o["default"],VDatePickerMonthTable:s["default"],VDatePickerYears:l["default"]}}},"./src/components/VDatePicker/mixins/date-picker-table.ts": +/*!****************************************************************!*\ + !*** ./src/components/VDatePicker/mixins/date-picker-table.ts ***! + \****************************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ../VDatePickerTable.sass */"./src/components/VDatePicker/VDatePickerTable.sass");var r=n(/*! ../../../directives/touch */"./src/directives/touch/index.ts"),i=n(/*! ../../../mixins/colorable */"./src/mixins/colorable/index.ts"),a=n(/*! ../../../mixins/localable */"./src/mixins/localable/index.ts"),o=n(/*! ../../../mixins/themeable */"./src/mixins/themeable/index.ts"),s=n(/*! ../util */"./src/components/VDatePicker/util/index.ts"),l=n(/*! ../util/isDateAllowed */"./src/components/VDatePicker/util/isDateAllowed.ts"),c=n(/*! ../../../util/mergeData */"./src/util/mergeData.ts"),u=n(/*! ../../../util/mixins */"./src/util/mixins.ts"),h=n(/*! ../../../util/helpers */"./src/util/helpers.ts"),d=function(){return d=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},p=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i=Object(s["sanitizeDateString"])(this.min,r))||t>0&&(!this.max||n<=Object(s["sanitizeDateString"])(this.max,r))},wheel:function(t,e){this.$emit("update:table-date",e(t.deltaY))},touch:function(t,e){this.$emit("update:table-date",e(t))},genTable:function(t,e,n){var r=this,i=this.$createElement("transition",{props:{name:this.computedTransition}},[this.$createElement("table",{key:this.tableDate},e)]),a={name:"touch",value:{left:function(t){return t.offsetX<-15&&r.isValidScroll(1,n)&&r.touch(1,n)},right:function(t){return t.offsetX>15&&r.isValidScroll(-1,n)&&r.touch(-1,n)}}};return this.$createElement("div",{staticClass:t,class:d({"v-date-picker-table--disabled":this.disabled},this.themeClasses),on:!this.disabled&&this.scrollable?{wheel:function(t){t.preventDefault(),r.isValidScroll(t.deltaY,n)&&r.wheelThrottle(t,n)}}:void 0,directives:[a]},[i])},isSelected:function(t){if(Array.isArray(this.value)){if(this.range&&2===this.value.length){var e=f(p([],f(this.value),!1).sort(),2),n=e[0],r=e[1];return n<=t&&t<=r}return-1!==this.value.indexOf(t)}return t===this.value}}})},"./src/components/VDatePicker/util/createNativeLocaleFormatter.ts": +/*!************************************************************************!*\ + !*** ./src/components/VDatePicker/util/createNativeLocaleFormatter.ts ***! + \************************************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./pad */"./src/components/VDatePicker/util/pad.ts"),i=function(t,e){var n="function"===typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,a=n.call(t),o=[];try{while((void 0===e||e-- >0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};function a(t,e,n){void 0===n&&(n={start:0,length:0});var a=function(t){var e=i(t.trim().split(" ")[0].split("-"),3),n=e[0],a=e[1],o=e[2];return[Object(r["default"])(n,4),Object(r["default"])(a||1),Object(r["default"])(o||1)].join("-")};try{var o=new Intl.DateTimeFormat(t||void 0,e);return function(t){return o.format(new Date(a(t)+"T00:00:00+00:00"))}}catch(s){return n.start||n.length?function(t){return a(t).substr(n.start||0,n.length)}:void 0}}e["default"]=a},"./src/components/VDatePicker/util/eventHelpers.ts": +/*!*********************************************************!*\ + !*** ./src/components/VDatePicker/util/eventHelpers.ts ***! + \*********************************************************/ +/*! exports provided: createItemTypeNativeListeners, createItemTypeListeners */function(t,e,n){"use strict";function r(t,e,n){return Object.keys(t.$listeners).reduce((function(r,i){return i.endsWith(e)&&(r[i.slice(0,-e.length)]=function(e){return t.$emit(i,n,e)}),r}),{})}function i(t,e){return Object.keys(t.$listeners).reduce((function(n,r){return r.endsWith(e)&&(n[r]=t.$listeners[r]),n}),{})}n.r(e),n.d(e,"createItemTypeNativeListeners",(function(){return r})),n.d(e,"createItemTypeListeners",(function(){return i}))},"./src/components/VDatePicker/util/index.ts": +/*!**************************************************!*\ + !*** ./src/components/VDatePicker/util/index.ts ***! + \**************************************************/ +/*! exports provided: createItemTypeListeners, createItemTypeNativeListeners, createNativeLocaleFormatter, monthChange, sanitizeDateString, pad */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./eventHelpers */"./src/components/VDatePicker/util/eventHelpers.ts");n.d(e,"createItemTypeListeners",(function(){return r["createItemTypeListeners"]})),n.d(e,"createItemTypeNativeListeners",(function(){return r["createItemTypeNativeListeners"]}));var i=n(/*! ./createNativeLocaleFormatter */"./src/components/VDatePicker/util/createNativeLocaleFormatter.ts");n.d(e,"createNativeLocaleFormatter",(function(){return i["default"]}));var a=n(/*! ./monthChange */"./src/components/VDatePicker/util/monthChange.ts");n.d(e,"monthChange",(function(){return a["default"]}));var o=n(/*! ./sanitizeDateString */"./src/components/VDatePicker/util/sanitizeDateString.ts");n.d(e,"sanitizeDateString",(function(){return o["default"]}));var s=n(/*! ./pad */"./src/components/VDatePicker/util/pad.ts");n.d(e,"pad",(function(){return s["default"]}))},"./src/components/VDatePicker/util/isDateAllowed.ts": +/*!**********************************************************!*\ + !*** ./src/components/VDatePicker/util/isDateAllowed.ts ***! + \**********************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";function r(t,e,n,r){return(!r||r(t))&&(!e||t>=e.substr(0,10))&&(!n||t<=n)}n.r(e),n.d(e,"default",(function(){return r}))},"./src/components/VDatePicker/util/monthChange.ts": +/*!********************************************************!*\ + !*** ./src/components/VDatePicker/util/monthChange.ts ***! + \********************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./pad */"./src/components/VDatePicker/util/pad.ts"),i=function(t,e){var n="function"===typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,a=n.call(t),o=[];try{while((void 0===e||e-- >0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=function(t,e){var n=i(t.split("-").map(Number),2),a=n[0],o=n[1];return o+e===0?a-1+"-12":o+e===13?a+1+"-01":a+"-"+Object(r["default"])(o+e)}},"./src/components/VDatePicker/util/pad.ts": +/*!************************************************!*\ + !*** ./src/components/VDatePicker/util/pad.ts ***! + \************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=function(t,e,n){return e>>=0,t=String(t),n=String(n),t.length>e?String(t):(e-=t.length,e>n.length&&(n+=n.repeat(e/n.length)),n.slice(0,e)+String(t))};e["default"]=function(t,e){return void 0===e&&(e=2),r(t,e,"0")}},"./src/components/VDatePicker/util/sanitizeDateString.ts": +/*!***************************************************************!*\ + !*** ./src/components/VDatePicker/util/sanitizeDateString.ts ***! + \***************************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./pad */"./src/components/VDatePicker/util/pad.ts"),i=function(t,e){var n="function"===typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,a=n.call(t),o=[];try{while((void 0===e||e-- >0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=function(t,e){var n=i(t.split("-"),3),a=n[0],o=n[1],s=void 0===o?1:o,l=n[2],c=void 0===l?1:l;return(a+"-"+Object(r["default"])(s)+"-"+Object(r["default"])(c)).substr(0,{date:10,month:7,year:4}[e])}},"./src/components/VDialog/VDialog.sass": +/*!*********************************************!*\ + !*** ./src/components/VDialog/VDialog.sass ***! + \*********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VDialog/VDialog.ts": +/*!*******************************************!*\ + !*** ./src/components/VDialog/VDialog.ts ***! + \*******************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VDialog.sass */"./src/components/VDialog/VDialog.sass");var r=n(/*! ../VThemeProvider */"./src/components/VThemeProvider/index.ts"),i=n(/*! ../../mixins/activatable */"./src/mixins/activatable/index.ts"),a=n(/*! ../../mixins/dependent */"./src/mixins/dependent/index.ts"),o=n(/*! ../../mixins/detachable */"./src/mixins/detachable/index.ts"),s=n(/*! ../../mixins/overlayable */"./src/mixins/overlayable/index.ts"),l=n(/*! ../../mixins/returnable */"./src/mixins/returnable/index.ts"),c=n(/*! ../../mixins/stackable */"./src/mixins/stackable/index.ts"),u=n(/*! ../../directives/click-outside */"./src/directives/click-outside/index.ts"),h=n(/*! ../../util/mixins */"./src/util/mixins.ts"),d=n(/*! ../../util/console */"./src/util/console.ts"),f=n(/*! ../../util/helpers */"./src/util/helpers.ts"),p=function(){return p=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},g=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i=this.getMaxZIndex()},hideScroll:function(){this.fullscreen?document.documentElement.classList.add("overflow-y-hidden"):s["default"].options.methods.hideScroll.call(this)},show:function(){var t=this;!this.fullscreen&&!this.hideOverlay&&this.genOverlay(),this.$nextTick((function(){t.$nextTick((function(){var e,n;(null===(e=t.$refs.dialog)||void 0===e?void 0:e.contains(document.activeElement))||(t.previousActiveElement=document.activeElement,null===(n=t.$refs.dialog)||void 0===n||n.focus()),t.bind()}))}))},bind:function(){window.addEventListener("focusin",this.onFocusin)},unbind:function(){window.removeEventListener("focusin",this.onFocusin)},onClickOutside:function(t){this.$emit("click:outside",t),this.persistent?this.noClickAnimation||this.animateClick():this.isActive=!1},onKeydown:function(t){if(t.keyCode===f["keyCodes"].esc&&!this.getOpenDependents().length)if(this.persistent)this.noClickAnimation||this.animateClick();else{this.isActive=!1;var e=this.getActivator();this.$nextTick((function(){return e&&e.focus()}))}this.$emit("keydown",t)},onFocusin:function(t){if(t&&this.retainFocus){var e=t.target;if(e&&this.$refs.dialog&&![document,this.$refs.dialog].includes(e)&&!this.$refs.dialog.contains(e)&&this.activeZIndex>=this.getMaxZIndex()&&!this.getOpenDependentElements().some((function(t){return t.contains(e)}))){var n=this.$refs.dialog.querySelectorAll('button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])'),r=g([],v(n),!1).find((function(t){return!t.hasAttribute("disabled")&&!t.matches('[tabindex="-1"]')}));r&&r.focus()}}},genContent:function(){var t=this;return this.showLazyContent((function(){return[t.$createElement(r["VThemeProvider"],{props:{root:!0,light:t.light,dark:t.dark}},[t.$createElement("div",{class:t.contentClasses,attrs:p({role:"dialog","aria-modal":t.hideOverlay?void 0:"true"},t.getScopeIdAttrs()),on:{keydown:t.onKeydown},style:{zIndex:t.activeZIndex},ref:"content"},[t.genTransition()])])]}))},genTransition:function(){var t=this.genInnerContent();return this.transition?this.$createElement("transition",{props:{name:this.transition,origin:this.origin,appear:!0}},[t]):t},genInnerContent:function(){var t={class:this.classes,attrs:{tabindex:this.isActive?0:void 0},ref:"dialog",directives:[{name:"click-outside",value:{handler:this.onClickOutside,closeConditional:this.closeConditional,include:this.getOpenDependentElements}},{name:"show",value:this.isActive}],style:{transformOrigin:this.origin}};return this.fullscreen||(t.style=p(p({},t.style),{maxWidth:Object(f["convertToUnit"])(this.maxWidth),width:Object(f["convertToUnit"])(this.width)})),this.$createElement("div",t,this.getContentSlot())}},render:function(t){return t("div",{staticClass:"v-dialog__container",class:{"v-dialog__container--attached":""===this.attach||!0===this.attach||"attach"===this.attach}},[this.genActivator(),this.genContent()])}})},"./src/components/VDialog/index.ts": +/*!*****************************************!*\ + !*** ./src/components/VDialog/index.ts ***! + \*****************************************/ +/*! exports provided: VDialog, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VDialog */"./src/components/VDialog/VDialog.ts");n.d(e,"VDialog",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VDivider/VDivider.sass": +/*!***********************************************!*\ + !*** ./src/components/VDivider/VDivider.sass ***! + \***********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VDivider/VDivider.ts": +/*!*********************************************!*\ + !*** ./src/components/VDivider/VDivider.ts ***! + \*********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VDivider.sass */"./src/components/VDivider/VDivider.sass");var r=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),i=function(){return i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0&&"boolean"===typeof this.value[0]&&Object(i["breaking"])(':value="[true, false, true]"',':value="[0, 2]"',this)},methods:{updateItem:function(t,e){var n=this.getValue(t,e),r=this.getValue(t,e+1);t.isActive=this.toggleMethod(n),t.nextIsActive=this.toggleMethod(r)}}})},"./src/components/VExpansionPanel/index.ts": +/*!*************************************************!*\ + !*** ./src/components/VExpansionPanel/index.ts ***! + \*************************************************/ +/*! exports provided: VExpansionPanels, VExpansionPanel, VExpansionPanelHeader, VExpansionPanelContent, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VExpansionPanels */"./src/components/VExpansionPanel/VExpansionPanels.ts");n.d(e,"VExpansionPanels",(function(){return r["default"]}));var i=n(/*! ./VExpansionPanel */"./src/components/VExpansionPanel/VExpansionPanel.ts");n.d(e,"VExpansionPanel",(function(){return i["default"]}));var a=n(/*! ./VExpansionPanelContent */"./src/components/VExpansionPanel/VExpansionPanelContent.ts");n.d(e,"VExpansionPanelContent",(function(){return a["default"]}));var o=n(/*! ./VExpansionPanelHeader */"./src/components/VExpansionPanel/VExpansionPanelHeader.ts");n.d(e,"VExpansionPanelHeader",(function(){return o["default"]})),e["default"]={$_vuetify_subcomponents:{VExpansionPanels:r["default"],VExpansionPanel:i["default"],VExpansionPanelHeader:o["default"],VExpansionPanelContent:a["default"]}}},"./src/components/VFileInput/VFileInput.sass": +/*!***************************************************!*\ + !*** ./src/components/VFileInput/VFileInput.sass ***! + \***************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VFileInput/VFileInput.ts": +/*!*************************************************!*\ + !*** ./src/components/VFileInput/VFileInput.ts ***! + \*************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VFileInput.sass */"./src/components/VFileInput/VFileInput.sass");var r=n(/*! ../VTextField */"./src/components/VTextField/index.ts"),i=n(/*! ../VChip */"./src/components/VChip/index.ts"),a=n(/*! ../../util/helpers */"./src/util/helpers.ts"),o=n(/*! ../../util/console */"./src/util/console.ts"),s=n(/*! ../../util/mergeData */"./src/util/mergeData.ts");function l(t){return l="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},l(t)}var c=function(){return c=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},h=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0},isLabelActive:function(){return this.isDirty},text:function(){var t=this;return this.isDirty||!this.persistentPlaceholder&&!this.isFocused&&this.hasLabel?this.internalArrayValue.map((function(e){var n=e.name,r=void 0===n?"":n,i=e.size,o=void 0===i?0:i,s=t.truncateText(r);return t.showSize?s+" ("+Object(a["humanReadableFileSize"])(o,1024===t.base)+")":s})):[this.placeholder]},base:function(){return"boolean"!==typeof this.showSize?this.showSize:void 0},hasChips:function(){return this.chips||this.smallChips}},watch:{readonly:{handler:function(t){!0===t&&Object(o["consoleError"])("readonly is not supported on ",this)},immediate:!0},value:function(t){var e=this.multiple?t:t?[t]:[];Object(a["deepEqual"])(e,this.$refs.input.files)||(this.$refs.input.value="")}},methods:{clearableCallback:function(){this.internalValue=this.multiple?[]:null,this.$refs.input.value=""},genChips:function(){var t=this;return this.isDirty?this.text.map((function(e,n){return t.$createElement(i["VChip"],{props:{small:t.smallChips},on:{"click:close":function(){var e=t.internalValue;e.splice(n,1),t.internalValue=e}}},[e])})):[]},genControl:function(){var t=r["default"].options.methods.genControl.call(this);return this.hideInput&&(t.data.style=Object(s["mergeStyles"])(t.data.style,{display:"none"})),t},genInput:function(){var t=r["default"].options.methods.genInput.call(this);return t.data.attrs.multiple=this.multiple,delete t.data.domProps.value,delete t.data.on.input,t.data.on.change=this.onInput,[this.genSelections(),t]},genPrependSlot:function(){var t=this;if(!this.prependIcon)return null;var e=this.genIcon("prepend",(function(){t.$refs.input.click()}));return this.genSlot("prepend","outer",[e])},genSelectionText:function(){var t=this.text.length;return t<2?this.text:this.showSize&&!this.counter?[this.computedCounterValue]:[this.$vuetify.lang.t(this.counterString,t)]},genSelections:function(){var t=this,e=[];return this.isDirty&&this.$scopedSlots.selection?this.internalArrayValue.forEach((function(n,r){t.$scopedSlots.selection&&e.push(t.$scopedSlots.selection({text:t.text[r],file:n,index:r}))})):e.push(this.hasChips&&this.isDirty?this.genChips():this.genSelectionText()),this.$createElement("div",{staticClass:"v-file-input__text",class:{"v-file-input__text--placeholder":this.placeholder&&!this.isDirty,"v-file-input__text--chips":this.hasChips&&!this.$scopedSlots.selection}},e)},genTextFieldSlot:function(){var t=this,e=r["default"].options.methods.genTextFieldSlot.call(this);return e.data.on=c(c({},e.data.on||{}),{click:function(e){e.target&&"LABEL"===e.target.nodeName||t.$refs.input.click()}}),e},onInput:function(t){var e=h([],u(t.target.files||[]),!1);this.internalValue=this.multiple?e:e[0],this.initialValue=this.internalValue},onKeyDown:function(t){this.$emit("keydown",t)},truncateText:function(t){if(t.length0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},c=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i4}(function(t){t["xSmall"]="12px",t["small"]="16px",t["default"]="24px",t["medium"]="28px",t["large"]="36px",t["xLarge"]="40px"})(r||(r={}));var v=Object(h["default"])(i["default"],a["default"],o["default"],s["default"]).extend({name:"v-icon",props:{dense:Boolean,disabled:Boolean,left:Boolean,right:Boolean,size:[Number,String],tag:{type:String,required:!1,default:"i"}},computed:{medium:function(){return!1},hasClickListener:function(){return Boolean(this.listeners$.click||this.listeners$["!click"])}},methods:{getIcon:function(){var t="";return this.$slots.default&&(t=this.$slots.default[0].text.trim()),Object(l["remapInternalIcon"])(this,t)},getSize:function(){var t={xSmall:this.xSmall,small:this.small,medium:this.medium,large:this.large,xLarge:this.xLarge},e=Object(l["keys"])(t).find((function(e){return t[e]}));return e&&r[e]||Object(l["convertToUnit"])(this.size)},getDefaultData:function(){return{staticClass:"v-icon notranslate",class:{"v-icon--disabled":this.disabled,"v-icon--left":this.left,"v-icon--link":this.hasClickListener,"v-icon--right":this.right,"v-icon--dense":this.dense},attrs:d({"aria-hidden":!this.hasClickListener,disabled:this.hasClickListener&&this.disabled,type:this.hasClickListener?"button":void 0},this.attrs$),on:this.listeners$}},getSvgWrapperData:function(){var t=this.getSize(),e=d(d({},this.getDefaultData()),{style:t?{fontSize:t,height:t,width:t}:void 0});return this.applyColors(e),e},applyColors:function(t){t.class=d(d({},t.class),this.themeClasses),this.setTextColor(this.color,t)},renderFontIcon:function(t,e){var n=[],r=this.getDefaultData(),i="material-icons",a=t.indexOf("-"),o=a<=-1;o?n.push(t):(i=t.slice(0,a),f(i)&&(i="")),r.class[i]=!0,r.class[t]=!o;var s=this.getSize();return s&&(r.style={fontSize:s}),this.applyColors(r),e(this.hasClickListener?"button":this.tag,r,n)},renderSvgIcon:function(t,e){var n={class:"v-icon__svg",attrs:{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",role:"img","aria-hidden":!0}},r=this.getSize();return r&&(n.style={fontSize:r,height:r,width:r}),e(this.hasClickListener?"button":"span",this.getSvgWrapperData(),[e("svg",n,[e("path",{attrs:{d:t}})])])},renderSvgIconComponent:function(t,e){var n={class:{"v-icon__component":!0}},r=this.getSize();r&&(n.style={fontSize:r,height:r,width:r}),this.applyColors(n);var i=t.component;return n.props=t.props,n.nativeOn=n.on,e(this.hasClickListener?"button":"span",this.getSvgWrapperData(),[e(i,n)])}},render:function(t){var e=this.getIcon();return"string"===typeof e?p(e)?this.renderSvgIcon(e,t):this.renderFontIcon(e,t):this.renderSvgIconComponent(e,t)}});e["default"]=u.a.extend({name:"v-icon",$_wrapperFor:v,functional:!0,render:function(t,e){var n=e.data,r=e.children,i="";return n.domProps&&(i=n.domProps.textContent||n.domProps.innerHTML||i,delete n.domProps.textContent,delete n.domProps.innerHTML),t(v,n,i?[i]:r)}})},"./src/components/VIcon/index.ts": +/*!***************************************!*\ + !*** ./src/components/VIcon/index.ts ***! + \***************************************/ +/*! exports provided: VIcon, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VIcon */"./src/components/VIcon/VIcon.ts");n.d(e,"VIcon",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VImg/VImg.sass": +/*!***************************************!*\ + !*** ./src/components/VImg/VImg.sass ***! + \***************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VImg/VImg.ts": +/*!*************************************!*\ + !*** ./src/components/VImg/VImg.ts ***! + \*************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VImg.sass */"./src/components/VImg/VImg.sass");var r=n(/*! ../../directives/intersect */"./src/directives/intersect/index.ts"),i=n(/*! ../VResponsive */"./src/components/VResponsive/index.ts"),a=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),o=n(/*! ../../util/mixins */"./src/util/mixins.ts"),s=n(/*! ../../util/mergeData */"./src/util/mergeData.ts"),l=n(/*! ../../util/console */"./src/util/console.ts"),c=n(/*! ../../util/helpers */"./src/util/helpers.ts");function u(t){return u="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}var h="undefined"!==typeof window&&"IntersectionObserver"in window;e["default"]=Object(o["default"])(i["default"],a["default"]).extend({name:"v-img",directives:{intersect:r["default"]},props:{alt:String,contain:Boolean,eager:Boolean,gradient:String,lazySrc:String,options:{type:Object,default:function(){return{root:void 0,rootMargin:void 0,threshold:void 0}}},position:{type:String,default:"center center"},sizes:String,src:{type:[String,Object],default:""},srcset:String,transition:{type:[Boolean,String],default:"fade-transition"}},data:function(){return{currentSrc:"",image:null,isLoading:!0,calculatedAspectRatio:void 0,naturalWidth:void 0,hasError:!1}},computed:{computedAspectRatio:function(){return Number(this.normalisedSrc.aspect||this.calculatedAspectRatio)},normalisedSrc:function(){return this.src&&"object"===u(this.src)?{src:this.src.src,srcset:this.srcset||this.src.srcset,lazySrc:this.lazySrc||this.src.lazySrc,aspect:Number(this.aspectRatio||this.src.aspect)}:{src:this.src,srcset:this.srcset,lazySrc:this.lazySrc,aspect:Number(this.aspectRatio||0)}},__cachedImage:function(){if(!(this.normalisedSrc.src||this.normalisedSrc.lazySrc||this.gradient))return[];var t=[],e=this.isLoading?this.normalisedSrc.lazySrc:this.currentSrc;this.gradient&&t.push("linear-gradient("+this.gradient+")"),e&&t.push('url("'+e+'")');var n=this.$createElement("div",{staticClass:"v-image__image",class:{"v-image__image--preload":this.isLoading,"v-image__image--contain":this.contain,"v-image__image--cover":!this.contain},style:{backgroundImage:t.join(", "),backgroundPosition:this.position},key:+this.isLoading});return this.transition?this.$createElement("transition",{attrs:{name:this.transition,mode:"in-out"}},[n]):n}},watch:{src:function(){this.isLoading?this.loadImage():this.init(void 0,void 0,!0)},"$vuetify.breakpoint.width":"getSrc"},mounted:function(){this.init()},methods:{init:function(t,e,n){if(!h||n||this.eager){if(this.normalisedSrc.lazySrc){var r=new Image;r.src=this.normalisedSrc.lazySrc,this.pollForSize(r,null)}this.normalisedSrc.src&&this.loadImage()}},onLoad:function(){this.getSrc(),this.isLoading=!1,this.$emit("load",this.src),this.image&&(this.normalisedSrc.src.endsWith(".svg")||this.normalisedSrc.src.startsWith("data:image/svg+xml"))&&(this.image.naturalHeight&&this.image.naturalWidth?(this.naturalWidth=this.image.naturalWidth,this.calculatedAspectRatio=this.image.naturalWidth/this.image.naturalHeight):this.calculatedAspectRatio=1)},onError:function(){this.hasError=!0,this.$emit("error",this.src)},getSrc:function(){this.image&&(this.currentSrc=this.image.currentSrc||this.image.src)},loadImage:function(){var t=this,e=new Image;this.image=e,e.onload=function(){e.decode?e.decode().catch((function(e){Object(l["consoleWarn"])("Failed to decode image, trying to render anyway\n\nsrc: "+t.normalisedSrc.src+(e.message?"\nOriginal error: "+e.message:""),t)})).then(t.onLoad):t.onLoad()},e.onerror=this.onError,this.hasError=!1,this.sizes&&(e.sizes=this.sizes),this.normalisedSrc.srcset&&(e.srcset=this.normalisedSrc.srcset),e.src=this.normalisedSrc.src,this.$emit("loadstart",this.normalisedSrc.src),this.aspectRatio||this.pollForSize(e),this.getSrc()},pollForSize:function(t,e){var n=this;void 0===e&&(e=100);var r=function r(){var i=t.naturalHeight,a=t.naturalWidth;i||a?(n.naturalWidth=a,n.calculatedAspectRatio=a/i):t.complete||!n.isLoading||n.hasError||null==e||setTimeout(r,e)};r()},genContent:function(){var t=i["default"].options.methods.genContent.call(this);return this.naturalWidth&&this._b(t.data,"div",{style:{width:this.naturalWidth+"px"}}),t},__genPlaceholder:function(){var t=Object(c["getSlot"])(this,"placeholder");if(t){var e=this.isLoading?[this.$createElement("div",{staticClass:"v-image__placeholder"},t)]:[];return this.transition?this.$createElement("transition",{props:{appear:!0,name:this.transition}},e):e[0]}}},render:function(t){var e=i["default"].options.render.call(this,t),n=Object(s["default"])(e.data,{staticClass:"v-image",attrs:{"aria-label":this.alt,role:this.alt?"img":void 0},class:this.themeClasses,directives:h?[{name:"intersect",modifiers:{once:!0},value:{handler:this.init,options:this.options}}]:void 0});return e.children=[this.__cachedSizer,this.__cachedImage,this.__genPlaceholder(),this.genContent()],t(e.tag,n,e.children)}})},"./src/components/VImg/index.ts": +/*!**************************************!*\ + !*** ./src/components/VImg/index.ts ***! + \**************************************/ +/*! exports provided: VImg, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VImg */"./src/components/VImg/VImg.ts");n.d(e,"VImg",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VInput/VInput.sass": +/*!*******************************************!*\ + !*** ./src/components/VInput/VInput.sass ***! + \*******************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VInput/VInput.ts": +/*!*****************************************!*\ + !*** ./src/components/VInput/VInput.ts ***! + \*****************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VInput.sass */"./src/components/VInput/VInput.sass");var r=n(/*! ../VIcon */"./src/components/VIcon/index.ts"),i=n(/*! ../VLabel */"./src/components/VLabel/index.ts"),a=n(/*! ../VMessages */"./src/components/VMessages/index.ts"),o=n(/*! ../../mixins/binds-attrs */"./src/mixins/binds-attrs/index.ts"),s=n(/*! ../../mixins/validatable */"./src/mixins/validatable/index.ts"),l=n(/*! ../../util/helpers */"./src/util/helpers.ts"),c=n(/*! ../../util/mergeData */"./src/util/mergeData.ts"),u=n(/*! ../../util/mixins */"./src/util/mixins.ts"),h=function(){return h=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0},hasHint:function(){return!this.hasMessages&&!!this.hint&&(this.persistentHint||this.isFocused)},hasLabel:function(){return!(!this.$slots.label&&!this.label)},internalValue:{get:function(){return this.lazyValue},set:function(t){this.lazyValue=t,this.$emit(this.$_modelEvent,t)}},isDirty:function(){return!!this.lazyValue},isLabelActive:function(){return this.isDirty},messagesToDisplay:function(){var t=this;return this.hasHint?[this.hint]:this.hasMessages?this.validations.map((function(e){if("string"===typeof e)return e;var n=e(t.internalValue);return"string"===typeof n?n:""})).filter((function(t){return""!==t})):[]},showDetails:function(){return!1===this.hideDetails||"auto"===this.hideDetails&&this.hasDetails}},watch:{value:function(t){this.lazyValue=t}},beforeCreate:function(){this.$_modelEvent=this.$options.model&&this.$options.model.event||"input"},methods:{genContent:function(){return[this.genPrependSlot(),this.genControl(),this.genAppendSlot()]},genControl:function(){return this.$createElement("div",{staticClass:"v-input__control",attrs:{title:this.attrs$.title}},[this.genInputSlot(),this.genMessages()])},genDefaultSlot:function(){return[this.genLabel(),Object(l["getSlot"])(this)]},genIcon:function(t,e,n){var i,a=this;void 0===n&&(n={});var o=this[t+"Icon"],s="click:"+Object(l["kebabCase"])(t),u=!(!this.listeners$[s]&&!e),h={prepend:"prependAction",prependInner:"prependAction",append:"appendAction",appendOuter:"appendAction",clear:"clear"}[t],d=u&&h?this.$vuetify.lang.t("$vuetify.input."+h,null!==(i=this.label)&&void 0!==i?i:""):void 0,f=Object(c["default"])({attrs:{"aria-label":d,color:this.validationState,dark:this.dark,disabled:this.isDisabled,light:this.light,tabindex:"clear"===t?-1:void 0},on:u?{click:function(t){t.preventDefault(),t.stopPropagation(),a.$emit(s,t),e&&e(t)},mouseup:function(t){t.preventDefault(),t.stopPropagation()}}:void 0},n);return this.$createElement("div",{staticClass:"v-input__icon",class:t?"v-input__icon--"+Object(l["kebabCase"])(t):void 0},[this.$createElement(r["default"],f,o)])},genInputSlot:function(){return this.$createElement("div",this.setBackgroundColor(this.backgroundColor,{staticClass:"v-input__slot",style:{height:Object(l["convertToUnit"])(this.height)},on:{click:this.onClick,mousedown:this.onMouseDown,mouseup:this.onMouseUp},ref:"input-slot"}),[this.genDefaultSlot()])},genLabel:function(){return this.hasLabel?this.$createElement(i["default"],{props:{color:this.validationState,dark:this.dark,disabled:this.isDisabled,focused:this.hasState,for:this.computedId,light:this.light}},Object(l["getSlot"])(this,"label")||this.label):null},genMessages:function(){var t=this;return this.showDetails?this.$createElement(a["default"],{props:{color:this.hasHint?"":this.validationState,dark:this.dark,light:this.light,value:this.messagesToDisplay},attrs:{role:this.hasMessages?"alert":null},scopedSlots:{default:function(e){return Object(l["getSlot"])(t,"message",e)}}}):null},genSlot:function(t,e,n){if(!n.length)return null;var r=t+"-"+e;return this.$createElement("div",{staticClass:"v-input__"+r,ref:r},n)},genPrependSlot:function(){var t=[];return this.$slots.prepend?t.push(this.$slots.prepend):this.prependIcon&&t.push(this.genIcon("prepend")),this.genSlot("prepend","outer",t)},genAppendSlot:function(){var t=[];return this.$slots.append?t.push(this.$slots.append):this.appendIcon&&t.push(this.genIcon("append")),this.genSlot("append","outer",t)},onClick:function(t){this.$emit("click",t)},onMouseDown:function(t){this.hasMouseDown=!0,this.$emit("mousedown",t)},onMouseUp:function(t){this.hasMouseDown=!1,this.$emit("mouseup",t)}},render:function(t){return t("div",this.setTextColor(this.validationState,{staticClass:"v-input",class:this.classes}),this.genContent())}})},"./src/components/VInput/index.ts": +/*!****************************************!*\ + !*** ./src/components/VInput/index.ts ***! + \****************************************/ +/*! exports provided: VInput, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VInput */"./src/components/VInput/VInput.ts");n.d(e,"VInput",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VItemGroup/VItem.sass": +/*!**********************************************!*\ + !*** ./src/components/VItemGroup/VItem.sass ***! + \**********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VItemGroup/VItem.ts": +/*!********************************************!*\ + !*** ./src/components/VItemGroup/VItem.ts ***! + \********************************************/ +/*! exports provided: BaseItem, default */function(t,e,n){"use strict";n.r(e),n.d(e,"BaseItem",(function(){return c}));n(/*! ./VItem.sass */"./src/components/VItemGroup/VItem.sass");var r=n(/*! ../../mixins/groupable */"./src/mixins/groupable/index.ts"),i=n(/*! ../../util/mixins */"./src/util/mixins.ts"),a=n(/*! ../../util/console */"./src/util/console.ts"),o=n(/*! vue */"vue"),s=n.n(o),l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n-1&&r.length-1<1||null!=this.max&&i<0&&r.length+1>this.max||(i>-1?r.splice(i,1):r.push(t),this.internalValue=r)},updateSingle:function(t){var e=this.valueComparator(this.internalValue,t);this.mandatory&&e||(this.internalValue=e?void 0:t)}},render:function(t){return t(this.tag,this.genData(),Object(l["getSlot"])(this))}});e["default"]=u.extend({name:"v-item-group",provide:function(){return{itemGroup:this}}})},"./src/components/VItemGroup/index.ts": +/*!********************************************!*\ + !*** ./src/components/VItemGroup/index.ts ***! + \********************************************/ +/*! exports provided: VItem, VItemGroup, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VItem */"./src/components/VItemGroup/VItem.ts");n.d(e,"VItem",(function(){return r["default"]}));var i=n(/*! ./VItemGroup */"./src/components/VItemGroup/VItemGroup.ts");n.d(e,"VItemGroup",(function(){return i["default"]})),e["default"]={$_vuetify_subcomponents:{VItem:r["default"],VItemGroup:i["default"]}}},"./src/components/VLabel/VLabel.sass": +/*!*******************************************!*\ + !*** ./src/components/VLabel/VLabel.sass ***! + \*******************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VLabel/VLabel.ts": +/*!*****************************************!*\ + !*** ./src/components/VLabel/VLabel.ts ***! + \*****************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VLabel.sass */"./src/components/VLabel/VLabel.sass");var r=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),i=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),a=n(/*! ../../util/mixins */"./src/util/mixins.ts"),o=n(/*! ../../util/helpers */"./src/util/helpers.ts"),s=n(/*! ../../util/mergeData */"./src/util/mergeData.ts"),l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};e["default"]=r["default"].extend().extend({name:"v-list",provide:function(){return{isInList:!0,list:this}},inject:{isInMenu:{default:!1},isInNav:{default:!1}},props:{dense:Boolean,disabled:Boolean,expand:Boolean,flat:Boolean,nav:Boolean,rounded:Boolean,subheader:Boolean,threeLine:Boolean,twoLine:Boolean},data:function(){return{groups:[]}},computed:{classes:function(){return a(a({},r["default"].options.computed.classes.call(this)),{"v-list--dense":this.dense,"v-list--disabled":this.disabled,"v-list--flat":this.flat,"v-list--nav":this.nav,"v-list--rounded":this.rounded,"v-list--subheader":this.subheader,"v-list--two-line":this.twoLine,"v-list--three-line":this.threeLine})}},methods:{register:function(t){this.groups.push(t)},unregister:function(t){var e=this.groups.findIndex((function(e){return e._uid===t._uid}));e>-1&&this.groups.splice(e,1)},listClick:function(t){var e,n;if(!this.expand)try{for(var r=o(this.groups),i=r.next();!i.done;i=r.next()){var a=i.value;a.toggle(t)}}catch(s){e={error:s}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(e)throw e.error}}}},render:function(t){var e={staticClass:"v-list",class:this.classes,style:this.styles,attrs:a({role:this.isInNav||this.isInMenu?void 0:"list"},this.attrs$),on:this.listeners$};return t(this.tag,this.setBackgroundColor(this.color,e),Object(i["getSlot"])(this))}})},"./src/components/VList/VListGroup.sass": +/*!**********************************************!*\ + !*** ./src/components/VList/VListGroup.sass ***! + \**********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VList/VListGroup.ts": +/*!********************************************!*\ + !*** ./src/components/VList/VListGroup.ts ***! + \********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VListGroup.sass */"./src/components/VList/VListGroup.sass");var r=n(/*! ../VIcon */"./src/components/VIcon/index.ts"),i=n(/*! ./VListItem */"./src/components/VList/VListItem.ts"),a=n(/*! ./VListItemIcon */"./src/components/VList/VListItemIcon.ts"),o=n(/*! ../../mixins/binds-attrs */"./src/mixins/binds-attrs/index.ts"),s=n(/*! ../../mixins/bootable */"./src/mixins/bootable/index.ts"),l=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),c=n(/*! ../../mixins/toggleable */"./src/mixins/toggleable/index.ts"),u=n(/*! ../../mixins/registrable */"./src/mixins/registrable/index.ts"),h=n(/*! ../../directives/ripple */"./src/directives/ripple/index.ts"),d=n(/*! ../transitions */"./src/components/transitions/index.ts"),f=n(/*! ../../util/mixins */"./src/util/mixins.ts"),p=n(/*! ../../util/helpers */"./src/util/helpers.ts"),v=function(){return v=Object.assign||function(t){for(var e,n=1,r=arguments.length;n1&&(n.staticClass+=" v-list-item__action--stack"),t("div",n,i)}})},"./src/components/VList/VListItemAvatar.ts": +/*!*************************************************!*\ + !*** ./src/components/VList/VListItemAvatar.ts ***! + \*************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VAvatar */"./src/components/VAvatar/index.ts"),i=function(){return i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},b=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i-1})))},styles:function(){return{maxHeight:this.calculatedMaxHeight,minWidth:this.calculatedMinWidth,maxWidth:this.calculatedMaxWidth,top:this.calculatedTop,left:this.calculatedLeft,transformOrigin:this.origin,zIndex:this.zIndex||this.activeZIndex}}},watch:{isActive:function(t){t||(this.listIndex=-1)},isContentActive:function(t){this.hasJustFocused=t},listIndex:function(t,e){if(t in this.tiles){var n=this.tiles[t];n.classList.add("v-list-item--highlighted");var r=this.$refs.content.scrollTop,i=this.$refs.content.clientHeight;r>n.offsetTop-8?Object(g["default"])(n.offsetTop-n.clientHeight,{appOffset:!1,duration:300,container:this.$refs.content}):r+i=this.touchArea.right?this.isActive=!0:!this.right&&this.isActive&&(this.isActive=!1)))},swipeRight:function(t){this.isActive&&!this.right||(this.calculateTouchArea(),Math.abs(t.touchendX-t.touchstartX)<100||(!this.right&&t.touchstartX<=this.touchArea.left?this.isActive=!0:this.right&&this.isActive&&(this.isActive=!1)))},updateApplication:function(){if(!this.isActive||this.isMobile||this.temporary||!this.$el)return 0;var t=Number(this.miniVariant?this.miniVariantWidth:this.width);return isNaN(t)?this.$el.clientWidth:t},updateMiniVariant:function(t){this.expandOnHover&&this.miniVariant!==t&&this.$emit("update:mini-variant",t)}},render:function(t){var e=[this.genPrepend(),this.genContent(),this.genAppend(),this.genBorder()];return(this.src||Object(p["getSlot"])(this,"img"))&&e.unshift(this.genBackground()),t(this.tag,this.setBackgroundColor(this.color,{class:this.classes,style:this.styles,directives:this.genDirectives(),on:this.genListeners()}),e)}})},"./src/components/VNavigationDrawer/index.ts": +/*!***************************************************!*\ + !*** ./src/components/VNavigationDrawer/index.ts ***! + \***************************************************/ +/*! exports provided: VNavigationDrawer, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VNavigationDrawer */"./src/components/VNavigationDrawer/VNavigationDrawer.ts");n.d(e,"VNavigationDrawer",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VOtpInput/VOtpInput.sass": +/*!*************************************************!*\ + !*** ./src/components/VOtpInput/VOtpInput.sass ***! + \*************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VOtpInput/VOtpInput.ts": +/*!***********************************************!*\ + !*** ./src/components/VOtpInput/VOtpInput.ts ***! + \***********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ../VTextField/VTextField.sass */"./src/components/VTextField/VTextField.sass"),n(/*! ./VOtpInput.sass */"./src/components/VOtpInput/VOtpInput.sass");var r=n(/*! ../VInput */"./src/components/VInput/index.ts"),i=n(/*! ../VTextField/VTextField */"./src/components/VTextField/VTextField.ts"),a=n(/*! ../../directives/ripple */"./src/directives/ripple/index.ts"),o=n(/*! ../../util/helpers */"./src/util/helpers.ts"),s=n(/*! ../../util/console */"./src/util/console.ts"),l=n(/*! ../../util/mixins */"./src/util/mixins.ts"),c=function(){return c=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},h=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;in)break;o[l]=a[s].toString()}a.length||o.splice(e,1),this.otp=o,this.internalValue=this.otp.join(""),e+a.length>=+this.length?(this.onCompleted(),this.clearFocus(e)):a.length&&this.changeFocus(e+a.length)},clearFocus:function(t){var e=this.$refs.input[t];e.blur()},onKeyDown:function(t){t.keyCode===o["keyCodes"].enter&&this.$emit("change",this.internalValue),this.$emit("keydown",t)},onMouseDown:function(t,e){t.target!==this.$refs.input[e]&&(t.preventDefault(),t.stopPropagation()),r["default"].options.methods.onMouseDown.call(this,t)},onMouseUp:function(t,e){this.hasMouseDown&&this.focus(t,e),r["default"].options.methods.onMouseUp.call(this,t)},changeFocus:function(t){this.onFocus(void 0,t||0)},updateValue:function(t){this.hasColor=t,t?this.initialValue=this.lazyValue:this.initialValue!==this.lazyValue&&this.$emit("change",this.lazyValue)},onKeyUp:function(t,e){t.preventDefault();var n=t.key;if(!["Tab","Shift","Meta","Control","Alt"].includes(n)&&!["Delete"].includes(n))return"ArrowLeft"===n||"Backspace"===n&&!this.otp[e]?e>0&&this.changeFocus(e-1):"ArrowRight"===n?e+1<+this.length&&this.changeFocus(e+1):void 0},onCompleted:function(){var t=this.otp.join("");t.length===+this.length&&this.$emit("finish",t)}},render:function(t){return t("div",{staticClass:"v-otp-input",class:this.themeClasses},this.genContent())}})},"./src/components/VOtpInput/index.ts": +/*!*******************************************!*\ + !*** ./src/components/VOtpInput/index.ts ***! + \*******************************************/ +/*! exports provided: VOtpInput, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VOtpInput */"./src/components/VOtpInput/VOtpInput.ts");n.d(e,"VOtpInput",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VOverflowBtn/VOverflowBtn.sass": +/*!*******************************************************!*\ + !*** ./src/components/VOverflowBtn/VOverflowBtn.sass ***! + \*******************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VOverflowBtn/VOverflowBtn.ts": +/*!*****************************************************!*\ + !*** ./src/components/VOverflowBtn/VOverflowBtn.ts ***! + \*****************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VOverflowBtn.sass */"./src/components/VOverflowBtn/VOverflowBtn.sass");var r=n(/*! ../VSelect/VSelect */"./src/components/VSelect/VSelect.ts"),i=n(/*! ../VAutocomplete */"./src/components/VAutocomplete/index.ts"),a=n(/*! ../VTextField/VTextField */"./src/components/VTextField/VTextField.ts"),o=n(/*! ../VBtn */"./src/components/VBtn/index.ts"),s=n(/*! ../../util/console */"./src/util/console.ts"),l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},h=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;iNumber.MAX_SAFE_INTEGER)return[];var e=Math.min(Math.max(0,t)||this.length,Math.max(0,this.maxButtons)||this.length,this.length);if(this.length<=e)return this.range(1,this.length);var n=e%2===0?1:0,r=Math.floor(e/2),i=this.length-r+1+n;if(this.value>r&&this.value0?t:1;for(var r=t;r<=e;r++)n.push(r);return n},genIcon:function(t,e,n,i,a){return t("li",[t("button",this.setBackgroundColor(this.navigationColor,{staticClass:"v-pagination__navigation",class:{"v-pagination__navigation--disabled":n},attrs:{disabled:n,type:"button","aria-label":a},on:n?{}:{click:i}}),[t(r["default"],{props:{color:this.navigationTextColor}},[e])])])},genItem:function(t,e){var n=this,r=e===this.value&&(this.color||"primary"),i=e===this.value,a=i?this.currentPageAriaLabel:this.pageAriaLabel;return t("button",this.setBackgroundColor(r,{staticClass:"v-pagination__item",class:{"v-pagination__item--active":e===this.value},attrs:{type:"button","aria-current":i,"aria-label":this.$vuetify.lang.t(a,e)},on:{click:function(){return n.$emit("input",e)}}}),[e.toString()])},genItems:function(t){var e=this;return this.items.map((function(n,r){return t("li",{key:r},[isNaN(Number(n))?t("span",{class:"v-pagination__more"},[n.toString()]):e.genItem(t,n)])}))},genList:function(t,e){return t("ul",{directives:[{modifiers:{quiet:!0},name:"resize",value:this.onResize}],class:this.classes},e)}},render:function(t){var e=[this.genIcon(t,this.$vuetify.rtl?this.nextIcon:this.prevIcon,this.value<=1,this.previous,this.$vuetify.lang.t(this.previousAriaLabel)),this.genItems(t),this.genIcon(t,this.$vuetify.rtl?this.prevIcon:this.nextIcon,this.value>=this.length,this.next,this.$vuetify.lang.t(this.nextAriaLabel))];return t("nav",{attrs:{role:"navigation","aria-label":this.$vuetify.lang.t(this.wrapperAriaLabel)}},[this.genList(t,e)])}})},"./src/components/VPagination/index.ts": +/*!*********************************************!*\ + !*** ./src/components/VPagination/index.ts ***! + \*********************************************/ +/*! exports provided: VPagination, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VPagination */"./src/components/VPagination/VPagination.ts");n.d(e,"VPagination",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VParallax/VParallax.sass": +/*!*************************************************!*\ + !*** ./src/components/VParallax/VParallax.sass ***! + \*************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VParallax/VParallax.ts": +/*!***********************************************!*\ + !*** ./src/components/VParallax/VParallax.ts ***! + \***********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VParallax.sass */"./src/components/VParallax/VParallax.sass");var r=n(/*! ../../mixins/translatable */"./src/mixins/translatable/index.ts"),i=n(/*! ../../util/mixins */"./src/util/mixins.ts"),a=n(/*! ../../util/helpers */"./src/util/helpers.ts"),o=Object(i["default"])(r["default"]);e["default"]=o.extend().extend({name:"v-parallax",props:{alt:{type:String,default:""},height:{type:[String,Number],default:500},src:String,srcset:String},data:function(){return{isBooted:!1}},computed:{styles:function(){return{display:"block",opacity:this.isBooted?1:0,transform:"translate(-50%, "+this.parallax+"px)"}}},mounted:function(){this.init()},methods:{init:function(){var t=this,e=this.$refs.img;e&&(e.complete?(this.translate(),this.listeners()):e.addEventListener("load",(function(){t.translate(),t.listeners()}),!1),this.isBooted=!0)},objHeight:function(){return this.$refs.img.naturalHeight}},render:function(t){var e={staticClass:"v-parallax__image",style:this.styles,attrs:{src:this.src,srcset:this.srcset,alt:this.alt},ref:"img"},n=t("div",{staticClass:"v-parallax__image-container"},[t("img",e)]),r=t("div",{staticClass:"v-parallax__content"},Object(a["getSlot"])(this));return t("div",{staticClass:"v-parallax",style:{height:this.height+"px"},on:this.$listeners},[n,r])}})},"./src/components/VParallax/index.ts": +/*!*******************************************!*\ + !*** ./src/components/VParallax/index.ts ***! + \*******************************************/ +/*! exports provided: VParallax, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VParallax */"./src/components/VParallax/VParallax.ts");n.d(e,"VParallax",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VPicker/VPicker.sass": +/*!*********************************************!*\ + !*** ./src/components/VPicker/VPicker.sass ***! + \*********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VPicker/VPicker.ts": +/*!*******************************************!*\ + !*** ./src/components/VPicker/VPicker.ts ***! + \*******************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VPicker.sass */"./src/components/VPicker/VPicker.sass"),n(/*! ../VCard/VCard.sass */"./src/components/VCard/VCard.sass");var r=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),i=n(/*! ../../mixins/elevatable */"./src/mixins/elevatable/index.ts"),a=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),o=n(/*! ../../util/helpers */"./src/util/helpers.ts"),s=n(/*! ../../util/mixins */"./src/util/mixins.ts"),l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n100?100:parseFloat(this.value)},strokeDashArray:function(){return Math.round(1e3*this.circumference)/1e3},strokeDashOffset:function(){return(100-this.normalizedValue)/100*this.circumference+"px"},strokeWidth:function(){return Number(this.width)/+this.size*this.viewBoxSize*2},styles:function(){return{height:Object(a["convertToUnit"])(this.calculatedSize),width:Object(a["convertToUnit"])(this.calculatedSize)}},svgStyles:function(){return{transform:"rotate("+Number(this.rotate)+"deg)"}},viewBoxSize:function(){return this.radius/(1-Number(this.width)/+this.size)}},methods:{genCircle:function(t,e){return this.$createElement("circle",{class:"v-progress-circular__"+t,attrs:{fill:"transparent",cx:2*this.viewBoxSize,cy:2*this.viewBoxSize,r:this.radius,"stroke-width":this.strokeWidth,"stroke-dasharray":this.strokeDashArray,"stroke-dashoffset":e}})},genSvg:function(){var t=[this.indeterminate||this.genCircle("underlay",0),this.genCircle("overlay",this.strokeDashOffset)];return this.$createElement("svg",{style:this.svgStyles,attrs:{xmlns:"http://www.w3.org/2000/svg",viewBox:this.viewBoxSize+" "+this.viewBoxSize+" "+2*this.viewBoxSize+" "+2*this.viewBoxSize}},t)},genInfo:function(){return this.$createElement("div",{staticClass:"v-progress-circular__info"},Object(a["getSlot"])(this))},onObserve:function(t,e,n){this.isVisible=n}},render:function(t){return t("div",this.setTextColor(this.color,{staticClass:"v-progress-circular",attrs:{role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":this.indeterminate?void 0:this.normalizedValue},class:this.classes,directives:[{name:"intersect",value:this.onObserve}],style:this.styles,on:this.$listeners}),[this.genSvg(),this.genInfo()])}})},"./src/components/VProgressCircular/index.ts": +/*!***************************************************!*\ + !*** ./src/components/VProgressCircular/index.ts ***! + \***************************************************/ +/*! exports provided: VProgressCircular, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VProgressCircular */"./src/components/VProgressCircular/VProgressCircular.ts");n.d(e,"VProgressCircular",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VProgressLinear/VProgressLinear.sass": +/*!*************************************************************!*\ + !*** ./src/components/VProgressLinear/VProgressLinear.sass ***! + \*************************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VProgressLinear/VProgressLinear.ts": +/*!***********************************************************!*\ + !*** ./src/components/VProgressLinear/VProgressLinear.ts ***! + \***********************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VProgressLinear.sass */"./src/components/VProgressLinear/VProgressLinear.sass");var r=n(/*! ../transitions */"./src/components/transitions/index.ts"),i=n(/*! ../../directives/intersect */"./src/directives/intersect/index.ts"),a=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),o=n(/*! ../../mixins/positionable */"./src/mixins/positionable/index.ts"),s=n(/*! ../../mixins/proxyable */"./src/mixins/proxyable/index.ts"),l=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),c=n(/*! ../../util/helpers */"./src/util/helpers.ts"),u=n(/*! ../../util/mixins */"./src/util/mixins.ts"),h=function(){return h=Object.assign||function(t){for(var e,n=1,r=arguments.length;n100?100:parseFloat(t)}},render:function(t){var e={staticClass:"v-progress-linear",attrs:{role:"progressbar","aria-valuemin":0,"aria-valuemax":this.normalizedBuffer,"aria-valuenow":this.indeterminate?void 0:this.normalizedValue},class:this.classes,directives:[{name:"intersect",value:this.onObserve}],style:{bottom:this.bottom?0:void 0,height:this.active?Object(c["convertToUnit"])(this.height):0,top:this.top?0:void 0},on:this.genListeners()};return t("div",e,[this.__cachedStream,this.__cachedBackground,this.__cachedBuffer,this.__cachedBar,this.genContent()])}})},"./src/components/VProgressLinear/index.ts": +/*!*************************************************!*\ + !*** ./src/components/VProgressLinear/index.ts ***! + \*************************************************/ +/*! exports provided: VProgressLinear, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VProgressLinear */"./src/components/VProgressLinear/VProgressLinear.ts");n.d(e,"VProgressLinear",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VRadioGroup/VRadio.sass": +/*!************************************************!*\ + !*** ./src/components/VRadioGroup/VRadio.sass ***! + \************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VRadioGroup/VRadio.ts": +/*!**********************************************!*\ + !*** ./src/components/VRadioGroup/VRadio.ts ***! + \**********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VRadio.sass */"./src/components/VRadioGroup/VRadio.sass");var r=n(/*! ../VLabel */"./src/components/VLabel/index.ts"),i=n(/*! ../VIcon */"./src/components/VIcon/index.ts"),a=n(/*! ../VInput */"./src/components/VInput/index.ts"),o=n(/*! ../../mixins/binds-attrs */"./src/mixins/binds-attrs/index.ts"),s=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),l=n(/*! ../../mixins/groupable */"./src/mixins/groupable/index.ts"),c=n(/*! ../../mixins/rippleable */"./src/mixins/rippleable/index.ts"),u=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),h=n(/*! ../../mixins/selectable */"./src/mixins/selectable/index.ts"),d=n(/*! ../../util/helpers */"./src/util/helpers.ts"),f=n(/*! ../../util/mixins */"./src/util/mixins.ts"),p=n(/*! ../../util/mergeData */"./src/util/mergeData.ts"),v=function(){return v=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},s=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;in[1]||n[1]=0}},watch:{internalValue:function(t){t!==this.value&&this.$emit("input",t)},value:function(t){this.internalValue=t}},methods:{createClickFn:function(t){var e=this;return function(n){if(!e.readonly){var r=e.genHoverIndex(n,t);e.clearable&&e.internalValue===r?e.internalValue=0:e.internalValue=r}}},createProps:function(t){var e={index:t,value:this.internalValue,click:this.createClickFn(t),isFilled:Math.floor(this.internalValue)>t,isHovered:Math.floor(this.hoverIndex)>t};return this.halfIncrements&&(e.isHalfHovered=!e.isHovered&&(this.hoverIndex-t)%1>0,e.isHalfFilled=!e.isFilled&&(this.internalValue-t)%1>0),e},genHoverIndex:function(t,e){var n=this.isHalfEvent(t);return this.halfIncrements&&this.$vuetify.rtl&&(n=!n),e+(n?.5:1)},getIconName:function(t){var e=this.isHovering?t.isHovered:t.isFilled,n=this.isHovering?t.isHalfHovered:t.isHalfFilled;return e?this.fullIcon:n?this.halfIcon:this.emptyIcon},getColor:function(t){if(this.isHovering){if(t.isHovered||t.isHalfHovered)return this.color}else if(t.isFilled||t.isHalfFilled)return this.color;return this.backgroundColor},isHalfEvent:function(t){if(this.halfIncrements){var e=t.target&&t.target.getBoundingClientRect();if(e&&t.pageX-e.left=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},y={closeOnClick:!1,closeOnContentClick:!1,disableKeys:!0,openOnClick:!1,maxHeight:304},b=Object(v["default"])(s["default"],l["default"],c["default"],u["default"]);e["default"]=b.extend().extend({name:"v-select",directives:{ClickOutside:h["default"]},props:{appendIcon:{type:String,default:"$dropdown"},attach:{type:null,default:!1},cacheItems:Boolean,chips:Boolean,clearable:Boolean,deletableChips:Boolean,disableLookup:Boolean,eager:Boolean,hideSelected:Boolean,items:{type:Array,default:function(){return[]}},itemColor:{type:String,default:"primary"},itemDisabled:{type:[String,Array,Function],default:"disabled"},itemText:{type:[String,Array,Function],default:"text"},itemValue:{type:[String,Array,Function],default:"value"},menuProps:{type:[String,Array,Object],default:function(){return y}},multiple:Boolean,openOnClear:Boolean,returnObject:Boolean,smallChips:Boolean},data:function(){return{cachedItems:this.cacheItems?this.items:[],menuIsBooted:!1,isMenuActive:!1,lastItem:20,lazyValue:void 0!==this.value?this.value:this.multiple?[]:void 0,selectedIndex:-1,selectedItems:[],keyboardLookupPrefix:"",keyboardLookupLastTime:0}},computed:{allItems:function(){return this.filterDuplicates(this.cachedItems.concat(this.items))},classes:function(){return g(g({},s["default"].options.computed.classes.call(this)),{"v-select":!0,"v-select--chips":this.hasChips,"v-select--chips--small":this.smallChips,"v-select--is-menu-active":this.isMenuActive,"v-select--is-multi":this.multiple})},computedItems:function(){return this.allItems},computedOwns:function(){return"list-"+this._uid},computedCounterValue:function(){var t,e=this.multiple?this.selectedItems:(null!==(t=this.getText(this.selectedItems[0]))&&void 0!==t?t:"").toString();return"function"===typeof this.counterValue?this.counterValue(e):e.length},directives:function(){var t=this;return this.isFocused?[{name:"click-outside",value:{handler:this.blur,closeConditional:this.closeConditional,include:function(){return t.getOpenDependentElements()}}}]:void 0},dynamicHeight:function(){return"auto"},hasChips:function(){return this.chips||this.smallChips},hasSlot:function(){return Boolean(this.hasChips||this.$scopedSlots.selection)},isDirty:function(){return this.selectedItems.length>0},listData:function(){var t,e=this.$vnode&&this.$vnode.context.$options._scopeId,n=e?(t={},t[e]=!0,t):{};return{attrs:g(g({},n),{id:this.computedOwns}),props:{action:this.multiple,color:this.itemColor,dense:this.dense,hideSelected:this.hideSelected,items:this.virtualizedItems,itemDisabled:this.itemDisabled,itemText:this.itemText,itemValue:this.itemValue,noDataText:this.$vuetify.lang.t(this.noDataText),selectedItems:this.selectedItems},on:{select:this.selectItem},scopedSlots:{item:this.$scopedSlots.item}}},staticList:function(){return(this.$slots["no-data"]||this.$slots["prepend-item"]||this.$slots["append-item"])&&Object(p["consoleError"])("assert: staticList should not be called if slots are used"),this.$createElement(a["default"],this.listData)},virtualizedItems:function(){return this.$_menuProps.auto?this.computedItems:this.computedItems.slice(0,this.lastItem)},menuCanShow:function(){return!0},$_menuProps:function(){var t="string"===typeof this.menuProps?this.menuProps.split(","):this.menuProps;return Array.isArray(t)&&(t=t.reduce((function(t,e){return t[e.trim()]=!0,t}),{})),g(g(g({},y),{eager:this.eager,value:this.menuCanShow&&this.isMenuActive,nudgeBottom:t.offsetY?1:0}),t)}},watch:{internalValue:function(t){var e=this;this.initialValue=t,this.setSelectedItems(),this.multiple&&this.$nextTick((function(){var t;null===(t=e.$refs.menu)||void 0===t||t.updateDimensions()})),this.hideSelected&&this.$nextTick((function(){e.onScroll()}))},isMenuActive:function(t){var e=this;window.setTimeout((function(){return e.onMenuActiveChange(t)}))},items:{immediate:!0,handler:function(t){var e=this;this.cacheItems&&this.$nextTick((function(){e.cachedItems=e.filterDuplicates(e.cachedItems.concat(t))})),this.setSelectedItems()}}},methods:{blur:function(t){s["default"].options.methods.blur.call(this,t),this.isMenuActive=!1,this.isFocused=!1,this.selectedIndex=-1,this.setMenuIndex(-1)},activateMenu:function(){this.isInteractive&&!this.isMenuActive&&(this.isMenuActive=!0)},clearableCallback:function(){var t=this;this.setValue(this.multiple?[]:null),this.setMenuIndex(-1),this.$nextTick((function(){return t.$refs.input&&t.$refs.input.focus()})),this.openOnClear&&(this.isMenuActive=!0)},closeConditional:function(t){return!this.isMenuActive||!this._isDestroyed&&(!this.getContent()||!this.getContent().contains(t.target))&&this.$el&&!this.$el.contains(t.target)&&t.target!==this.$el},filterDuplicates:function(t){for(var e=new Map,n=0;n1||t.ctrlKey||t.metaKey||t.altKey)){var n=1e3,r=performance.now();r-this.keyboardLookupLastTime>n&&(this.keyboardLookupPrefix=""),this.keyboardLookupPrefix+=t.key.toLowerCase(),this.keyboardLookupLastTime=r;var i=this.allItems.findIndex((function(t){var n,r=(null!==(n=e.getText(t))&&void 0!==n?n:"").toString();return r.toLowerCase().startsWith(e.keyboardLookupPrefix)})),a=this.allItems[i];-1!==i&&(this.lastItem=Math.max(this.lastItem,i+5),this.setValue(this.returnObject?a:this.getValue(a)),this.$nextTick((function(){return e.$refs.menu.getTiles()})),setTimeout((function(){return e.setMenuIndex(i)})))}},onKeyDown:function(t){var e=this;if(!this.isReadonly||t.keyCode===f["keyCodes"].tab){var n=t.keyCode,r=this.$refs.menu;if(this.$emit("keydown",t),r)return this.isMenuActive&&[f["keyCodes"].up,f["keyCodes"].down,f["keyCodes"].home,f["keyCodes"].end,f["keyCodes"].enter].includes(n)&&this.$nextTick((function(){r.changeListIndex(t),e.$emit("update:list-index",r.listIndex)})),[f["keyCodes"].enter,f["keyCodes"].space].includes(n)&&this.activateMenu(),!this.isMenuActive&&[f["keyCodes"].up,f["keyCodes"].down,f["keyCodes"].home,f["keyCodes"].end].includes(n)?this.onUpDown(t):n===f["keyCodes"].esc?this.onEscDown(t):n===f["keyCodes"].tab?this.onTabDown(t):n===f["keyCodes"].space?this.onSpaceDown(t):void 0}},onMenuActiveChange:function(t){if(!(this.multiple&&!t||this.getMenuIndex()>-1)){var e=this.$refs.menu;if(e&&this.isDirty){this.$refs.menu.getTiles();for(var n=0;nthis.computedItems.length)return;var e=this.getContent().scrollHeight-(this.getContent().scrollTop+this.getContent().clientHeight)<200;e&&(this.lastItem+=20)}else requestAnimationFrame((function(){var e=t.getContent();e&&(e.scrollTop=0)}))},onSpaceDown:function(t){t.preventDefault()},onTabDown:function(t){var e=this.$refs.menu;if(e){var n=e.activeTile;!this.multiple&&n&&this.isMenuActive?(t.preventDefault(),t.stopPropagation(),n.click()):this.blur(t)}},onUpDown:function(t){var e=this,n=this.$refs.menu;if(n){if(t.preventDefault(),this.multiple)return this.activateMenu();var r=t.keyCode;n.isBooted=!0,window.requestAnimationFrame((function(){if(n.getTiles(),!n.hasClickableTiles)return e.activateMenu();switch(r){case f["keyCodes"].up:n.prevTile();break;case f["keyCodes"].down:n.nextTile();break;case f["keyCodes"].home:n.firstTile();break;case f["keyCodes"].end:n.lastTile();break}e.selectItem(e.allItems[e.getMenuIndex()])}))}},selectItem:function(t){var e=this;if(this.multiple){var n=(this.internalValue||[]).slice(),r=this.findExistingIndex(t);if(-1!==r?n.splice(r,1):n.push(t),this.setValue(n.map((function(t){return e.returnObject?t:e.getValue(t)}))),this.hideSelected)this.setMenuIndex(-1);else{var i=this.computedItems.indexOf(t);~i&&(this.$nextTick((function(){return e.$refs.menu.getTiles()})),setTimeout((function(){return e.setMenuIndex(i)})))}}else this.setValue(this.returnObject?t:this.getValue(t)),this.isMenuActive=!1},setMenuIndex:function(t){this.$refs.menu&&(this.$refs.menu.listIndex=t)},setSelectedItems:function(){var t,e,n=this,r=[],i=this.multiple&&Array.isArray(this.internalValue)?this.internalValue:[this.internalValue],a=function(t){var e=o.allItems.findIndex((function(e){return n.valueComparator(n.getValue(e),n.getValue(t))}));e>-1&&r.push(o.allItems[e])},o=this;try{for(var s=m(i),l=s.next();!l.done;l=s.next()){var c=l.value;a(c)}}catch(u){t={error:u}}finally{try{l&&!l.done&&(e=s.return)&&e.call(s)}finally{if(t)throw t.error}}this.selectedItems=r},setValue:function(t){this.valueComparator(t,this.internalValue)||(this.internalValue=t,this.$emit("change",t))},isAppendInner:function(t){var e=this.$refs["append-inner"];return e&&(e===t||e.contains(t))}}})},"./src/components/VSelect/VSelectList.ts": +/*!***********************************************!*\ + !*** ./src/components/VSelect/VSelectList.ts ***! + \***********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VCheckbox/VSimpleCheckbox */"./src/components/VCheckbox/VSimpleCheckbox.ts"),i=n(/*! ../VDivider */"./src/components/VDivider/index.ts"),a=n(/*! ../VSubheader */"./src/components/VSubheader/index.ts"),o=n(/*! ../VList */"./src/components/VList/index.ts"),s=n(/*! ../../directives/ripple */"./src/directives/ripple/index.ts"),l=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),c=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),u=n(/*! ../../util/helpers */"./src/util/helpers.ts"),h=n(/*! ../../util/mixins */"./src/util/mixins.ts"),d=function(){return d=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0?this.genAction(n,l):null,this.genTileContent(n,r)]);var u=this,h=this.$scopedSlots.item({parent:u,item:n,attrs:d(d({},c.attrs),c.props),on:c.on});return this.needsTile(h)?this.$createElement(o["VListItem"],c,h):h},genTileContent:function(t,e){return void 0===e&&(e=0),this.$createElement(o["VListItemContent"],[this.$createElement(o["VListItemTitle"],[this.genFilteredText(this.getText(t))])])},hasItem:function(t){return this.parsedItems.indexOf(this.getValue(t))>-1},needsTile:function(t){return 1!==t.length||null==t[0].componentOptions||"v-list-item"!==t[0].componentOptions.Ctor.options.name},getDisabled:function(t){return Boolean(Object(u["getPropertyFromItem"])(t,this.itemDisabled,!1))},getText:function(t){return String(Object(u["getPropertyFromItem"])(t,this.itemText,t))},getValue:function(t){return Object(u["getPropertyFromItem"])(t,this.itemValue,this.getText(t))}},render:function(){for(var t=[],e=this.items.length,n=0;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=Object(o["default"])(r["default"],i["default"],a["default"]).extend({name:"VSkeletonLoader",props:{boilerplate:Boolean,loading:Boolean,loadingText:{type:String,default:"$vuetify.loading"},tile:Boolean,transition:String,type:String,types:{type:Object,default:function(){return{}}}},computed:{attrs:function(){return this.isLoading?l({"aria-busy":!this.boilerplate||void 0,"aria-live":this.boilerplate?void 0:"polite","aria-label":this.boilerplate?void 0:this.$vuetify.lang.t(this.loadingText),role:this.boilerplate?void 0:"alert"},this.$attrs):this.$attrs},classes:function(){return l(l({"v-skeleton-loader--boilerplate":this.boilerplate,"v-skeleton-loader--is-loading":this.isLoading,"v-skeleton-loader--tile":this.tile},this.themeClasses),this.elevationClasses)},isLoading:function(){return!("default"in this.$scopedSlots)||this.loading},rootTypes:function(){return l({actions:"button@2",article:"heading, paragraph",avatar:"avatar",button:"button",card:"image, card-heading","card-avatar":"image, list-item-avatar","card-heading":"heading",chip:"chip","date-picker":"list-item, card-heading, divider, date-picker-options, date-picker-days, actions","date-picker-options":"text, avatar@2","date-picker-days":"avatar@28",heading:"heading",image:"image","list-item":"text","list-item-avatar":"avatar, text","list-item-two-line":"sentences","list-item-avatar-two-line":"avatar, sentences","list-item-three-line":"paragraph","list-item-avatar-three-line":"avatar, paragraph",paragraph:"text@3",sentences:"text@2",table:"table-heading, table-thead, table-tbody, table-tfoot","table-heading":"heading, text","table-thead":"heading@6","table-tbody":"table-row-divider@6","table-row-divider":"table-row, divider","table-row":"table-cell@6","table-cell":"text","table-tfoot":"text@2, avatar@2",text:"text"},this.types)}},methods:{genBone:function(t,e){return this.$createElement("div",{staticClass:"v-skeleton-loader__"+t+" v-skeleton-loader__bone"},e)},genBones:function(t){var e=this,n=c(t.split("@"),2),r=n[0],i=n[1],a=function(){return e.genStructure(r)};return Array.from({length:i}).map(a)},genStructure:function(t){var e=[];t=t||this.type||"";var n=this.rootTypes[t]||"";if(t===n);else{if(t.indexOf(",")>-1)return this.mapBones(t);if(t.indexOf("@")>-1)return this.genBones(t);n.indexOf(",")>-1?e=this.mapBones(n):n.indexOf("@")>-1?e=this.genBones(n):n&&e.push(this.genStructure(n))}return[this.genBone(t,e)]},genSkeleton:function(){var t=[];return this.isLoading?t.push(this.genStructure()):t.push(Object(s["getSlot"])(this)),this.transition?this.$createElement("transition",{props:{name:this.transition},on:{afterEnter:this.resetStyles,beforeEnter:this.onBeforeEnter,beforeLeave:this.onBeforeLeave,leaveCancelled:this.resetStyles}},t):t},mapBones:function(t){return t.replace(/\s/g,"").split(",").map(this.genStructure)},onBeforeEnter:function(t){this.resetStyles(t),this.isLoading&&(t._initialStyle={display:t.style.display,transition:t.style.transition},t.style.setProperty("transition","none","important"))},onBeforeLeave:function(t){t.style.setProperty("display","none","important")},resetStyles:function(t){t._initialStyle&&(t.style.display=t._initialStyle.display||"",t.style.transition=t._initialStyle.transition,delete t._initialStyle)}},render:function(t){return t("div",{staticClass:"v-skeleton-loader",attrs:this.attrs,on:this.$listeners,class:this.classes,style:this.isLoading?this.measurableStyles:void 0},[this.genSkeleton()])}})},"./src/components/VSkeletonLoader/index.ts": +/*!*************************************************!*\ + !*** ./src/components/VSkeletonLoader/index.ts ***! + \*************************************************/ +/*! exports provided: VSkeletonLoader, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VSkeletonLoader */"./src/components/VSkeletonLoader/VSkeletonLoader.ts");n.d(e,"VSkeletonLoader",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VSlideGroup/VSlideGroup.sass": +/*!*****************************************************!*\ + !*** ./src/components/VSlideGroup/VSlideGroup.sass ***! + \*****************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VSlideGroup/VSlideGroup.ts": +/*!***************************************************!*\ + !*** ./src/components/VSlideGroup/VSlideGroup.ts ***! + \***************************************************/ +/*! exports provided: calculateUpdatedOffset, calculateCenteredOffset, BaseSlideGroup, default */function(t,e,n){"use strict";n.r(e),n.d(e,"calculateUpdatedOffset",(function(){return p})),n.d(e,"calculateCenteredOffset",(function(){return v})),n.d(e,"BaseSlideGroup",(function(){return g}));n(/*! ./VSlideGroup.sass */"./src/components/VSlideGroup/VSlideGroup.sass");var r=n(/*! ../VIcon */"./src/components/VIcon/index.ts"),i=n(/*! ../transitions */"./src/components/transitions/index.ts"),a=n(/*! ../VItemGroup/VItemGroup */"./src/components/VItemGroup/VItemGroup.ts"),o=n(/*! ../../mixins/mobile */"./src/mixins/mobile/index.ts"),s=n(/*! ../../directives/resize */"./src/directives/resize/index.ts"),l=n(/*! ../../directives/touch */"./src/directives/touch/index.ts"),c=n(/*! ../../util/mixins */"./src/util/mixins.ts"),u=n(/*! ../../util/helpers */"./src/util/helpers.ts"),h=function(){return h=Object.assign||function(t){for(var e,n=1,r=arguments.length;n=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};function f(t){var e=.501,n=Math.abs(t);return Math.sign(t)*(n/((1/e-2)*(1-n)+1))}function p(t,e,n,r){var i=t.clientWidth,a=n?e.content-t.offsetLeft-i:t.offsetLeft;n&&(r=-r);var o=e.wrapper+r,s=i+a,l=.4*i;return a<=r?r=Math.max(a-l,0):o<=s&&(r=Math.min(r-(o-s-l),e.content-e.wrapper)),n?-r:r}function v(t,e,n){var r=t.offsetLeft,i=t.clientWidth;if(n){var a=e.content-r-i/2-e.wrapper/2;return-Math.min(e.content-e.wrapper,Math.max(0,a))}a=r+i/2-e.wrapper/2;return Math.min(e.content-e.wrapper,Math.max(0,a))}var g=Object(c["default"])(a["BaseItemGroup"],o["default"]).extend({name:"base-slide-group",directives:{Resize:s["default"],Touch:l["default"]},props:{activeClass:{type:String,default:"v-slide-item--active"},centerActive:Boolean,nextIcon:{type:String,default:"$next"},prevIcon:{type:String,default:"$prev"},showArrows:{type:[Boolean,String],validator:function(t){return"boolean"===typeof t||["always","never","desktop","mobile"].includes(t)}}},data:function(){return{isOverflowing:!1,resizeTimeout:0,startX:0,isSwipingHorizontal:!1,isSwiping:!1,scrollOffset:0,widths:{content:0,wrapper:0}}},computed:{canTouch:function(){return"undefined"!==typeof window},__cachedNext:function(){return this.genTransition("next")},__cachedPrev:function(){return this.genTransition("prev")},classes:function(){return h(h({},a["BaseItemGroup"].options.computed.classes.call(this)),{"v-slide-group":!0,"v-slide-group--has-affixes":this.hasAffixes,"v-slide-group--is-overflowing":this.isOverflowing})},hasAffixes:function(){switch(this.showArrows){case"always":return!0;case"desktop":return!this.isMobile;case!0:return this.isOverflowing||Math.abs(this.scrollOffset)>0;case"mobile":return this.isMobile||this.isOverflowing||Math.abs(this.scrollOffset)>0;case"never":return!1;default:return!this.isMobile&&(this.isOverflowing||Math.abs(this.scrollOffset)>0)}},hasNext:function(){if(!this.hasAffixes)return!1;var t=this.widths,e=t.content,n=t.wrapper;return e>Math.abs(this.scrollOffset)+n},hasPrev:function(){return this.hasAffixes&&0!==this.scrollOffset}},watch:{internalValue:"setWidths",isOverflowing:"setWidths",scrollOffset:function(t){this.$vuetify.rtl&&(t=-t);var e=t<=0?f(-t):t>this.widths.content-this.widths.wrapper?-(this.widths.content-this.widths.wrapper)+f(this.widths.content-this.widths.wrapper-t):-t;this.$vuetify.rtl&&(e=-e),this.$refs.content.style.transform="translateX("+e+"px)"}},mounted:function(){var t=this;if("undefined"!==typeof ResizeObserver){var e=new ResizeObserver((function(){t.onResize()}));e.observe(this.$el),e.observe(this.$refs.content),this.$on("hook:destroyed",(function(){e.disconnect()}))}else{var n=0;this.$on("hook:beforeUpdate",(function(){var e;n=((null===(e=t.$refs.content)||void 0===e?void 0:e.children)||[]).length})),this.$on("hook:updated",(function(){var e;n!==((null===(e=t.$refs.content)||void 0===e?void 0:e.children)||[]).length&&t.setWidths()}))}},methods:{onScroll:function(){this.$refs.wrapper.scrollLeft=0},onFocusin:function(t){var e,n,r,i;if(this.isOverflowing)try{for(var a=d(Object(u["composedPath"])(t)),o=a.next();!o.done;o=a.next()){var s=o.value;try{for(var l=(r=void 0,d(this.items)),c=l.next();!c.done;c=l.next()){var h=c.value;if(h.$el===s)return void(this.scrollOffset=p(h.$el,this.widths,this.$vuetify.rtl,this.scrollOffset))}}catch(f){r={error:f}}finally{try{c&&!c.done&&(i=l.return)&&i.call(l)}finally{if(r)throw r.error}}}}catch(v){e={error:v}}finally{try{o&&!o.done&&(n=a.return)&&n.call(a)}finally{if(e)throw e.error}}},genNext:function(){var t=this,e=this.$scopedSlots.next?this.$scopedSlots.next({}):Object(u["getSlot"])(this,"next")||this.__cachedNext;return this.$createElement("div",{staticClass:"v-slide-group__next",class:{"v-slide-group__next--disabled":!this.hasNext},on:{click:function(){return t.onAffixClick("next")}},key:"next"},[e])},genContent:function(){return this.$createElement("div",{staticClass:"v-slide-group__content",ref:"content",on:{focusin:this.onFocusin}},Object(u["getSlot"])(this))},genData:function(){return{class:this.classes,directives:[{name:"resize",value:this.onResize}]}},genIcon:function(t){var e=t;this.$vuetify.rtl&&"prev"===t?e="next":this.$vuetify.rtl&&"next"===t&&(e="prev");var n=""+t[0].toUpperCase()+t.slice(1),i=this["has"+n];return this.showArrows||i?this.$createElement(r["default"],{props:{disabled:!i}},this[e+"Icon"]):null},genPrev:function(){var t=this,e=this.$scopedSlots.prev?this.$scopedSlots.prev({}):Object(u["getSlot"])(this,"prev")||this.__cachedPrev;return this.$createElement("div",{staticClass:"v-slide-group__prev",class:{"v-slide-group__prev--disabled":!this.hasPrev},on:{click:function(){return t.onAffixClick("prev")}},key:"prev"},[e])},genTransition:function(t){return this.$createElement(i["VFadeTransition"],[this.genIcon(t)])},genWrapper:function(){var t=this;return this.$createElement("div",{staticClass:"v-slide-group__wrapper",directives:[{name:"touch",value:{start:function(e){return t.overflowCheck(e,t.onTouchStart)},move:function(e){return t.overflowCheck(e,t.onTouchMove)},end:function(e){return t.overflowCheck(e,t.onTouchEnd)}}}],ref:"wrapper",on:{scroll:this.onScroll}},[this.genContent()])},calculateNewOffset:function(t,e,n,r){var i=n?-1:1,a=i*r+("prev"===t?-1:1)*e.wrapper;return i*Math.max(Math.min(a,e.content-e.wrapper),0)},onAffixClick:function(t){this.$emit("click:"+t),this.scrollTo(t)},onResize:function(){this._isDestroyed||this.setWidths()},onTouchStart:function(t){var e=this.$refs.content;this.startX=this.scrollOffset+t.touchstartX,e.style.setProperty("transition","none"),e.style.setProperty("willChange","transform")},onTouchMove:function(t){if(this.canTouch){if(!this.isSwiping){var e=t.touchmoveX-t.touchstartX,n=t.touchmoveY-t.touchstartY;this.isSwipingHorizontal=Math.abs(e)>Math.abs(n),this.isSwiping=!0}this.isSwipingHorizontal&&(this.scrollOffset=this.startX-t.touchmoveX,document.documentElement.style.overflowY="hidden")}},onTouchEnd:function(){if(this.canTouch){var t=this.$refs,e=t.content,n=t.wrapper,r=e.clientWidth-n.clientWidth;e.style.setProperty("transition",null),e.style.setProperty("willChange",null),this.$vuetify.rtl?this.scrollOffset>0||!this.isOverflowing?this.scrollOffset=0:this.scrollOffset<=-r&&(this.scrollOffset=-r):this.scrollOffset<0||!this.isOverflowing?this.scrollOffset=0:this.scrollOffset>=r&&(this.scrollOffset=r),this.isSwiping=!1,document.documentElement.style.removeProperty("overflow-y")}},overflowCheck:function(t,e){t.stopPropagation(),this.isOverflowing&&e(t)},scrollIntoView:function(){if(!this.selectedItem&&this.items.length){var t=this.items[this.items.length-1].$el.getBoundingClientRect(),e=this.$refs.wrapper.getBoundingClientRect();(this.$vuetify.rtl&&e.rightt.left)&&this.scrollTo("prev")}this.selectedItem&&(0===this.selectedIndex||!this.centerActive&&!this.isOverflowing?this.scrollOffset=0:this.centerActive?this.scrollOffset=v(this.selectedItem.$el,this.widths,this.$vuetify.rtl):this.isOverflowing&&(this.scrollOffset=p(this.selectedItem.$el,this.widths,this.$vuetify.rtl,this.scrollOffset)))},scrollTo:function(t){this.scrollOffset=this.calculateNewOffset(t,{content:this.$refs.content?this.$refs.content.clientWidth:0,wrapper:this.$refs.wrapper?this.$refs.wrapper.clientWidth:0},this.$vuetify.rtl,this.scrollOffset)},setWidths:function(){var t=this;window.requestAnimationFrame((function(){if(!t._isDestroyed){var e=t.$refs,n=e.content,r=e.wrapper;t.widths={content:n?n.clientWidth:0,wrapper:r?r.clientWidth:0},t.isOverflowing=t.widths.wrapper+10?parseFloat(this.step):0},inputWidth:function(){var t=(this.roundValue(this.internalValue)-this.minValue)/(this.maxValue-this.minValue)*100;return isNaN(t)?0:t},trackFillStyles:function(){var t,e=this.vertical?"bottom":"left",n=this.vertical?"top":"right",r=this.vertical?"height":"width",i=this.$vuetify.rtl?"auto":"0",a=this.$vuetify.rtl?"0":"auto",o=this.isDisabled?"calc("+this.inputWidth+"% - 10px)":this.inputWidth+"%";return t={transition:this.trackTransition},t[e]=i,t[n]=a,t[r]=o,t},trackStyles:function(){var t,e=this.vertical?this.$vuetify.rtl?"bottom":"top":this.$vuetify.rtl?"left":"right",n=this.vertical?"height":"width",r="0px",i=this.isDisabled?"calc("+(100-this.inputWidth)+"% - 10px)":"calc("+(100-this.inputWidth)+"%)";return t={transition:this.trackTransition},t[e]=r,t[n]=i,t},showTicks:function(){return this.tickLabels.length>0||!(this.isDisabled||!this.stepNumeric||!this.ticks)},numTicks:function(){return Math.ceil((this.maxValue-this.minValue)/this.stepNumeric)},showThumbLabel:function(){return!this.isDisabled&&!(!this.thumbLabel&&!this.$scopedSlots["thumb-label"])},computedTrackColor:function(){if(!this.isDisabled)return this.trackColor?this.trackColor:this.isDark?this.validationState:this.validationState||"primary lighten-3"},computedTrackFillColor:function(){if(!this.isDisabled)return this.trackFillColor?this.trackFillColor:this.validationState||this.computedColor},computedThumbColor:function(){return this.thumbColor?this.thumbColor:this.validationState||this.computedColor}},watch:{min:function(t){var e=parseFloat(t);e>this.internalValue&&this.$emit("input",e)},max:function(t){var e=parseFloat(t);e0}},a)},genThumbContainer:function(t,e,n,r,i,a,o){void 0===o&&(o="thumb");var s=[this.genThumb()],l=this.genThumbLabelContent(t);return this.showThumbLabel&&s.push(this.genThumbLabel(l)),this.$createElement("div",this.setTextColor(this.computedThumbColor,{ref:o,key:o,staticClass:"v-slider__thumb-container",class:{"v-slider__thumb-container--active":n,"v-slider__thumb-container--focused":r,"v-slider__thumb-container--show-label":this.showThumbLabel},style:this.getThumbContainerStyles(e),attrs:{role:"slider",tabindex:this.isDisabled?-1:this.$attrs.tabindex?this.$attrs.tabindex:0,"aria-label":this.$attrs["aria-label"]||this.label,"aria-valuemin":this.min,"aria-valuemax":this.max,"aria-valuenow":this.internalValue,"aria-readonly":String(this.isReadonly),"aria-orientation":this.vertical?"vertical":"horizontal"},on:{focus:i,blur:a,keydown:this.onKeyDown}}),s)},genThumbLabelContent:function(t){return this.$scopedSlots["thumb-label"]?this.$scopedSlots["thumb-label"]({value:t}):[this.$createElement("span",[String(t)])]},genThumbLabel:function(t){var e=Object(l["convertToUnit"])(this.thumbSize),n=this.vertical?"translateY(20%) translateY("+(Number(this.thumbSize)/3-1)+"px) translateX(55%) rotate(135deg)":"translateY(-20%) translateY(-12px) translateX(-50%) rotate(45deg)";return this.$createElement(i["VScaleTransition"],{props:{origin:"bottom center"}},[this.$createElement("div",{staticClass:"v-slider__thumb-label-container",directives:[{name:"show",value:this.isFocused||this.isActive||"always"===this.thumbLabel}]},[this.$createElement("div",this.setBackgroundColor(this.computedThumbColor,{staticClass:"v-slider__thumb-label",style:{height:e,width:e,transform:n}}),[this.$createElement("div",t)])])])},genThumb:function(){return this.$createElement("div",this.setBackgroundColor(this.computedThumbColor,{staticClass:"v-slider__thumb"}))},getThumbContainerStyles:function(t){var e,n=this.vertical?"top":"left",r=this.$vuetify.rtl?100-t:t;return r=this.vertical?100-r:r,e={transition:this.trackTransition},e[n]=r+"%",e},onSliderMouseDown:function(t){var e,n=this;if(t.preventDefault(),this.oldValue=this.internalValue,this.isActive=!0,null===(e=t.target)||void 0===e?void 0:e.matches(".v-slider__thumb-container, .v-slider__thumb-container *")){this.thumbPressed=!0;var r=t.target.getBoundingClientRect(),i="touches"in t?t.touches[0]:t;this.startOffset=this.vertical?i.clientY-(r.top+r.height/2):i.clientX-(r.left+r.width/2)}else this.startOffset=0,window.clearTimeout(this.mouseTimeout),this.mouseTimeout=window.setTimeout((function(){n.thumbPressed=!0}),300);var a=!l["passiveSupported"]||{passive:!0,capture:!0},o=!!l["passiveSupported"]&&{passive:!0},s="touches"in t;this.onMouseMove(t),this.app.addEventListener(s?"touchmove":"mousemove",this.onMouseMove,o),Object(l["addOnceEventListener"])(this.app,s?"touchend":"mouseup",this.onSliderMouseUp,a),this.$emit("start",this.internalValue)},onSliderMouseUp:function(t){t.stopPropagation(),window.clearTimeout(this.mouseTimeout),this.thumbPressed=!1;var e=!!l["passiveSupported"]&&{passive:!0};this.app.removeEventListener("touchmove",this.onMouseMove,e),this.app.removeEventListener("mousemove",this.onMouseMove,e),this.$emit("mouseup",t),this.$emit("end",this.internalValue),Object(l["deepEqual"])(this.oldValue,this.internalValue)||(this.$emit("change",this.internalValue),this.noClick=!0),this.isActive=!1},onMouseMove:function(t){"mousemove"===t.type&&(this.thumbPressed=!0),this.internalValue=this.parseMouseMove(t)},onKeyDown:function(t){if(this.isInteractive){var e=this.parseKeyDown(t,this.internalValue);null==e||ethis.maxValue||(this.internalValue=e,this.$emit("change",e))}},onSliderClick:function(t){if(this.noClick)this.noClick=!1;else{var e=this.$refs.thumb;e.focus(),this.onMouseMove(t),this.$emit("change",this.internalValue)}},onBlur:function(t){this.isFocused=!1,this.$emit("blur",t)},onFocus:function(t){this.isFocused=!0,this.$emit("focus",t)},parseMouseMove:function(t){var e=this.vertical?"top":"left",n=this.vertical?"height":"width",r=this.vertical?"clientY":"clientX",i=this.$refs.track.getBoundingClientRect(),a=e,o=i[a],s=n,l=i[s],c="touches"in t?t.touches[0][r]:t[r],u=Math.min(Math.max((c-o-this.startOffset)/l,0),1)||0;return this.vertical&&(u=1-u),this.$vuetify.rtl&&(u=1-u),parseFloat(this.min)+u*(this.maxValue-this.minValue)},parseKeyDown:function(t,e){if(this.isInteractive){var n=l["keyCodes"].pageup,r=l["keyCodes"].pagedown,i=l["keyCodes"].end,a=l["keyCodes"].home,o=l["keyCodes"].left,s=l["keyCodes"].right,c=l["keyCodes"].down,u=l["keyCodes"].up;if([n,r,i,a,o,s,c,u].includes(t.keyCode)){t.preventDefault();var h=this.stepNumeric||1,d=(this.maxValue-this.minValue)/h;if([o,s,c,u].includes(t.keyCode)){var f=this.$vuetify.rtl?[o,u]:[s,u],p=f.includes(t.keyCode)?1:-1,v=t.shiftKey?3:t.ctrlKey?2:1;e+=p*h*v}else if(t.keyCode===a)e=this.minValue;else if(t.keyCode===i)e=this.maxValue;else{p=t.keyCode===r?1:-1;e-=p*h*(d>100?d/10:10)}return e}}},roundValue:function(t){if(!this.stepNumeric)return t;var e=this.step.toString().trim(),n=e.indexOf(".")>-1?e.length-e.indexOf(".")-1:0,r=this.minValue%this.stepNumeric,i=Math.round((t-r)/this.stepNumeric)*this.stepNumeric+r;return parseFloat(Math.min(i,this.maxValue).toFixed(n))}}})},"./src/components/VSlider/index.ts": +/*!*****************************************!*\ + !*** ./src/components/VSlider/index.ts ***! + \*****************************************/ +/*! exports provided: VSlider, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VSlider */"./src/components/VSlider/VSlider.ts");n.d(e,"VSlider",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VSnackbar/VSnackbar.sass": +/*!*************************************************!*\ + !*** ./src/components/VSnackbar/VSnackbar.sass ***! + \*************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VSnackbar/VSnackbar.ts": +/*!***********************************************!*\ + !*** ./src/components/VSnackbar/VSnackbar.ts ***! + \***********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VSnackbar.sass */"./src/components/VSnackbar/VSnackbar.sass");var r=n(/*! ../VSheet/VSheet */"./src/components/VSheet/VSheet.ts"),i=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),a=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),o=n(/*! ../../mixins/toggleable */"./src/mixins/toggleable/index.ts"),s=n(/*! ../../mixins/positionable */"./src/mixins/positionable/index.ts"),l=n(/*! ../../util/mixins */"./src/util/mixins.ts"),c=n(/*! ../../util/helpers */"./src/util/helpers.ts"),u=n(/*! ../../util/console */"./src/util/console.ts");e["default"]=Object(l["default"])(r["default"],i["default"],o["default"],Object(s["factory"])(["absolute","bottom","left","right","top"])).extend({name:"v-snackbar",props:{app:Boolean,centered:Boolean,contentClass:{type:String,default:""},multiLine:Boolean,text:Boolean,timeout:{type:[Number,String],default:5e3},transition:{type:[Boolean,String],default:"v-snack-transition",validator:function(t){return"string"===typeof t||!1===t}},vertical:Boolean},data:function(){return{activeTimeout:-1}},computed:{classes:function(){return{"v-snack--absolute":this.absolute,"v-snack--active":this.isActive,"v-snack--bottom":this.bottom||!this.top,"v-snack--centered":this.centered,"v-snack--has-background":this.hasBackground,"v-snack--left":this.left,"v-snack--multi-line":this.multiLine&&!this.vertical,"v-snack--right":this.right,"v-snack--text":this.text,"v-snack--top":this.top,"v-snack--vertical":this.vertical}},hasBackground:function(){return!this.text&&!this.outlined},isDark:function(){return this.hasBackground?!this.light:a["default"].options.computed.isDark.call(this)},styles:function(){if(this.absolute||!this.app)return{};var t=this.$vuetify.application,e=t.bar,n=t.bottom,r=t.footer,i=t.insetFooter,a=t.left,o=t.right,s=t.top;return{paddingBottom:Object(c["convertToUnit"])(n+r+i),paddingLeft:Object(c["convertToUnit"])(a),paddingRight:Object(c["convertToUnit"])(o),paddingTop:Object(c["convertToUnit"])(e+s)}}},watch:{isActive:"setTimeout",timeout:"setTimeout"},mounted:function(){this.isActive&&this.setTimeout()},created:function(){this.$attrs.hasOwnProperty("auto-height")&&Object(u["removed"])("auto-height",this),0==this.timeout&&Object(u["deprecate"])('timeout="0"',"-1",this)},methods:{genActions:function(){return this.$createElement("div",{staticClass:"v-snack__action "},[Object(c["getSlot"])(this,"action",{attrs:{class:"v-snack__btn"}})])},genContent:function(){var t;return this.$createElement("div",{staticClass:"v-snack__content",class:(t={},t[this.contentClass]=!0,t),attrs:{role:"status","aria-live":"polite"}},[Object(c["getSlot"])(this)])},genWrapper:function(){var t=this,e=this.hasBackground?this.setBackgroundColor:this.setTextColor,n=e(this.color,{staticClass:"v-snack__wrapper",class:r["default"].options.computed.classes.call(this),style:r["default"].options.computed.styles.call(this),directives:[{name:"show",value:this.isActive}],on:{pointerenter:function(){return window.clearTimeout(t.activeTimeout)},pointerleave:this.setTimeout}});return this.$createElement("div",n,[this.genContent(),this.genActions()])},genTransition:function(){return this.$createElement("transition",{props:{name:this.transition}},[this.genWrapper()])},setTimeout:function(){var t=this;window.clearTimeout(this.activeTimeout);var e=Number(this.timeout);this.isActive&&![0,-1].includes(e)&&(this.activeTimeout=window.setTimeout((function(){t.isActive=!1}),e))}},render:function(t){return t("div",{staticClass:"v-snack",class:this.classes,style:this.styles},[!1!==this.transition?this.genTransition():this.genWrapper()])}})},"./src/components/VSnackbar/index.ts": +/*!*******************************************!*\ + !*** ./src/components/VSnackbar/index.ts ***! + \*******************************************/ +/*! exports provided: VSnackbar, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VSnackbar */"./src/components/VSnackbar/VSnackbar.ts");n.d(e,"VSnackbar",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VSparkline/VSparkline.ts": +/*!*************************************************!*\ + !*** ./src/components/VSparkline/VSparkline.ts ***! + \*************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),i=n(/*! ../../util/mixins */"./src/util/mixins.ts"),a=n(/*! ./helpers/core */"./src/components/VSparkline/helpers/core.ts"),o=n(/*! ./helpers/path */"./src/components/VSparkline/helpers/path.ts");function s(t){return s="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"===typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},s(t)}var l=function(){return l=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0||this.$scopedSlots.label)},parsedLabels:function(){for(var t=[],e=this._values,n=e.length,r=0;t.length0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},i=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0&&(u=0),c<0&&(c=0);var h=a/l,d=(s-o)/(c-u||1),f=s-Math.abs(u*d);return t.map((function(t,e){var r=Math.abs(d*t);return{x:n+e*h,y:f-r+ +(t<0)*r,height:r,value:t}}))}},"./src/components/VSparkline/helpers/math.ts": +/*!***************************************************!*\ + !*** ./src/components/VSparkline/helpers/math.ts ***! + \***************************************************/ +/*! exports provided: checkCollinear, getDistance, moveTo */function(t,e,n){"use strict";function r(t){return parseInt(t,10)}function i(t,e,n){return r(t.x+n.x)===r(2*e.x)&&r(t.y+n.y)===r(2*e.y)}function a(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function o(t,e,n){var r={x:t.x-e.x,y:t.y-e.y},i=Math.sqrt(r.x*r.x+r.y*r.y),a={x:r.x/i,y:r.y/i};return{x:e.x+a.x*n,y:e.y+a.y*n}}n.r(e),n.d(e,"checkCollinear",(function(){return i})),n.d(e,"getDistance",(function(){return a})),n.d(e,"moveTo",(function(){return o}))},"./src/components/VSparkline/helpers/path.ts": +/*!***************************************************!*\ + !*** ./src/components/VSparkline/helpers/path.ts ***! + \***************************************************/ +/*! exports provided: genPath */function(t,e,n){"use strict";n.r(e),n.d(e,"genPath",(function(){return i}));var r=n(/*! ./math */"./src/components/VSparkline/helpers/math.ts");function i(t,e,n,i){void 0===n&&(n=!1),void 0===i&&(i=75);var a=t.shift(),o=t[t.length-1];return(n?"M"+a.x+" "+(i-a.x+2)+" L"+a.x+" "+a.y:"M"+a.x+" "+a.y)+t.map((function(n,i){var o=t[i+1],s=t[i-1]||a,l=o&&Object(r["checkCollinear"])(o,n,s);if(!o||l)return"L"+n.x+" "+n.y;var c=Math.min(Object(r["getDistance"])(s,n),Object(r["getDistance"])(o,n)),u=c/2=0;)this.steps[t].toggle(this.internalValue);for(t=this.content.length;--t>=0;)this.content[t].toggle(this.internalValue,this.isReverse)}},render:function(t){return t(this.tag,{staticClass:"v-stepper",class:this.classes,style:this.styles},Object(l["getSlot"])(this))}})},"./src/components/VStepper/VStepperContent.ts": +/*!****************************************************!*\ + !*** ./src/components/VStepper/VStepperContent.ts ***! + \****************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../transitions */"./src/components/transitions/index.ts"),i=n(/*! ../../mixins/registrable */"./src/mixins/registrable/index.ts"),a=n(/*! ../../util/helpers */"./src/util/helpers.ts"),o=n(/*! ../../util/mixins */"./src/util/mixins.ts"),s=Object(o["default"])(Object(i["inject"])("stepper","v-stepper-content","v-stepper"));e["default"]=s.extend().extend({name:"v-stepper-content",inject:{isVerticalProvided:{from:"isVertical"}},props:{step:{type:[Number,String],required:!0}},data:function(){return{height:0,isActive:null,isReverse:!1,isVertical:this.isVerticalProvided}},computed:{computedTransition:function(){var t=this.$vuetify.rtl?!this.isReverse:this.isReverse;return t?r["VTabReverseTransition"]:r["VTabTransition"]},styles:function(){return this.isVertical?{height:Object(a["convertToUnit"])(this.height)}:{}}},watch:{isActive:function(t,e){t&&null==e?this.height="auto":this.isVertical&&(this.isActive?this.enter():this.leave())}},mounted:function(){this.$refs.wrapper.addEventListener("transitionend",this.onTransition,!1),this.stepper&&this.stepper.register(this)},beforeDestroy:function(){this.$refs.wrapper.removeEventListener("transitionend",this.onTransition,!1),this.stepper&&this.stepper.unregister(this)},methods:{onTransition:function(t){this.isActive&&"height"===t.propertyName&&(this.height="auto")},enter:function(){var t=this,e=0;requestAnimationFrame((function(){e=t.$refs.wrapper.scrollHeight})),this.height=0,setTimeout((function(){return t.isActive&&(t.height=e||"auto")}),450)},leave:function(){var t=this;this.height=this.$refs.wrapper.clientHeight,setTimeout((function(){return t.height=0}),10)},toggle:function(t,e){this.isActive=t.toString()===this.step.toString(),this.isReverse=e}},render:function(t){var e={staticClass:"v-stepper__content"},n={staticClass:"v-stepper__wrapper",style:this.styles,ref:"wrapper"};this.isVertical||(e.directives=[{name:"show",value:this.isActive}]);var r=t("div",n,Object(a["getSlot"])(this)),i=t("div",e,[r]);return t(this.computedTransition,{on:this.$listeners},[i])}})},"./src/components/VStepper/VStepperStep.ts": +/*!*************************************************!*\ + !*** ./src/components/VStepper/VStepperStep.ts ***! + \*************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VIcon */"./src/components/VIcon/index.ts"),i=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),a=n(/*! ../../mixins/registrable */"./src/mixins/registrable/index.ts"),o=n(/*! ../../directives/ripple */"./src/directives/ripple/index.ts"),s=n(/*! ../../util/mixins */"./src/util/mixins.ts"),l=n(/*! ../../util/helpers */"./src/util/helpers.ts"),c=Object(s["default"])(i["default"],Object(a["inject"])("stepper","v-stepper-step","v-stepper"));e["default"]=c.extend().extend({name:"v-stepper-step",directives:{ripple:o["default"]},inject:["stepClick"],props:{color:{type:String,default:"primary"},complete:Boolean,completeIcon:{type:String,default:"$complete"},editable:Boolean,editIcon:{type:String,default:"$edit"},errorIcon:{type:String,default:"$error"},rules:{type:Array,default:function(){return[]}},step:[Number,String]},data:function(){return{isActive:!1,isInactive:!0}},computed:{classes:function(){return{"v-stepper__step--active":this.isActive,"v-stepper__step--editable":this.editable,"v-stepper__step--inactive":this.isInactive,"v-stepper__step--error error--text":this.hasError,"v-stepper__step--complete":this.complete}},hasError:function(){return this.rules.some((function(t){return!0!==t()}))}},mounted:function(){this.stepper&&this.stepper.register(this)},beforeDestroy:function(){this.stepper&&this.stepper.unregister(this)},methods:{click:function(t){t.stopPropagation(),this.$emit("click",t),this.editable&&this.stepClick(this.step)},genIcon:function(t){return this.$createElement(r["default"],t)},genLabel:function(){return this.$createElement("div",{staticClass:"v-stepper__label"},Object(l["getSlot"])(this))},genStep:function(){var t=!(this.hasError||!this.complete&&!this.isActive)&&this.color;return this.$createElement("span",this.setBackgroundColor(t,{staticClass:"v-stepper__step__step"}),this.genStepContent())},genStepContent:function(){var t=[];return this.hasError?t.push(this.genIcon(this.errorIcon)):this.complete?this.editable?t.push(this.genIcon(this.editIcon)):t.push(this.genIcon(this.completeIcon)):t.push(String(this.step)),t},keyboardClick:function(t){t.keyCode===l["keyCodes"].space&&this.click(t)},toggle:function(t){this.isActive=t.toString()===this.step.toString(),this.isInactive=Number(t)-1&&t.preventDefault(),t.detail&&this.$el.blur(),this.$emit("click",t),this.to||this.toggle())},toggle:function(){this.isActive&&(this.tabsBar.mandatory||this.to)||this.$emit("change")}},render:function(t){var e=this,n=this.generateRouteLink(),r=n.tag,i=n.data;return i.attrs=l(l({},i.attrs),{"aria-selected":String(this.isActive),role:"tab",tabindex:this.disabled?-1:0}),i.on=l(l({},i.on),{keydown:function(t){t.keyCode===o["keyCodes"].enter&&e.click(t),e.$emit("keydown",t)}}),t(r,i,Object(o["getSlot"])(this))}})},"./src/components/VTabs/VTabItem.ts": +/*!******************************************!*\ + !*** ./src/components/VTabs/VTabItem.ts ***! + \******************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VWindow/VWindowItem */"./src/components/VWindow/VWindowItem.ts");e["default"]=r["default"].extend({name:"v-tab-item",props:{id:String},methods:{genWindowItem:function(){var t=r["default"].options.methods.genWindowItem.call(this);return t.data.domProps=t.data.domProps||{},t.data.domProps.id=this.id||this.value,t}}})},"./src/components/VTabs/VTabs.sass": +/*!*****************************************!*\ + !*** ./src/components/VTabs/VTabs.sass ***! + \*****************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VTabs/VTabs.ts": +/*!***************************************!*\ + !*** ./src/components/VTabs/VTabs.ts ***! + \***************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VTabs.sass */"./src/components/VTabs/VTabs.sass");var r=n(/*! ./VTabsBar */"./src/components/VTabs/VTabsBar.ts"),i=n(/*! ./VTabsItems */"./src/components/VTabs/VTabsItems.ts"),a=n(/*! ./VTabsSlider */"./src/components/VTabs/VTabsSlider.ts"),o=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),s=n(/*! ../../mixins/proxyable */"./src/mixins/proxyable/index.ts"),l=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),c=n(/*! ../../directives/resize */"./src/directives/resize/index.ts"),u=n(/*! ../../util/helpers */"./src/util/helpers.ts"),h=n(/*! ../../util/mixins */"./src/util/mixins.ts"),d=function(){return d=Object.assign||function(t){for(var e,n=1,r=arguments.length;n=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};e["default"]=Object(o["default"])(r["BaseSlideGroup"],a["default"],i["default"]).extend({name:"v-tabs-bar",provide:function(){return{tabsBar:this}},computed:{classes:function(){return s(s(s({},r["BaseSlideGroup"].options.computed.classes.call(this)),{"v-tabs-bar":!0,"v-tabs-bar--is-mobile":this.isMobile,"v-tabs-bar--show-arrows":this.showArrows}),this.themeClasses)}},watch:{items:"callSlider",internalValue:"callSlider",$route:"onRouteChange"},methods:{callSlider:function(){this.isBooted&&this.$emit("call:slider")},genContent:function(){var t=r["BaseSlideGroup"].options.methods.genContent.call(this);return t.data=t.data||{},t.data.staticClass+=" v-tabs-bar__content",t},onRouteChange:function(t,e){var n,r;if(!this.mandatory){var i=this.items,a=t.path,o=e.path,s=!1,c=!1;try{for(var u=l(i),h=u.next();!h.done;h=u.next()){var d=h.value;if(d.to===o?c=!0:d.to===a&&(s=!0),s&&c)break}}catch(f){n={error:f}}finally{try{h&&!h.done&&(r=u.return)&&r.call(u)}finally{if(n)throw n.error}}!s&&c&&(this.internalValue=void 0)}}},render:function(t){var e=r["BaseSlideGroup"].options.render.call(this,t);return e.data.attrs={role:"tablist"},e}})},"./src/components/VTabs/VTabsItems.ts": +/*!********************************************!*\ + !*** ./src/components/VTabs/VTabsItems.ts ***! + \********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ../VWindow/VWindow */"./src/components/VWindow/VWindow.ts"),i=n(/*! ./../VItemGroup/VItemGroup */"./src/components/VItemGroup/VItemGroup.ts"),a=function(){return a=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},y=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,a=e.length;i0||this.badInput},isEnclosed:function(){return this.filled||this.isSolo||this.outlined},isLabelActive:function(){return this.isDirty||x.includes(this.type)},isSingle:function(){return this.isSolo||this.singleLine||this.fullWidth||this.filled&&!this.hasLabel},isSolo:function(){return this.solo||this.soloInverted},labelPosition:function(){var t=this.prefix&&!this.labelValue?this.prefixWidth:0;return this.labelValue&&this.prependWidth&&(t-=this.prependWidth),this.$vuetify.rtl===this.reverse?{left:t,right:"auto"}:{left:"auto",right:t}},showLabel:function(){return this.hasLabel&&!(this.isSingle&&this.labelValue)},labelValue:function(){return this.isFocused||this.isLabelActive||this.persistentPlaceholder}},watch:{outlined:"setLabelWidth",label:function(){this.$nextTick(this.setLabelWidth)},prefix:function(){this.$nextTick(this.setPrefixWidth)},isFocused:"updateValue",value:function(t){this.lazyValue=t}},created:function(){this.$attrs.hasOwnProperty("box")&&Object(f["breaking"])("box","filled",this),this.$attrs.hasOwnProperty("browser-autocomplete")&&Object(f["breaking"])("browser-autocomplete","autocomplete",this),this.shaped&&!(this.filled||this.outlined||this.isSolo)&&Object(f["consoleWarn"])("shaped should be used with either filled or outlined",this)},mounted:function(){var t=this;this.$watch((function(){return t.labelValue}),this.setLabelWidth),this.autofocus&&this.tryAutofocus(),requestAnimationFrame((function(){t.isBooted=!0,requestAnimationFrame((function(){t.isIntersecting||t.onResize()}))}))},methods:{focus:function(){this.onFocus()},blur:function(t){var e=this;window.requestAnimationFrame((function(){e.$refs.input&&e.$refs.input.blur()}))},clearableCallback:function(){var t=this;this.$refs.input&&this.$refs.input.focus(),this.$nextTick((function(){return t.internalValue=null}))},genAppendSlot:function(){var t=[];return this.$slots["append-outer"]?t.push(this.$slots["append-outer"]):this.appendOuterIcon&&t.push(this.genIcon("appendOuter")),this.genSlot("append","outer",t)},genPrependInnerSlot:function(){var t=[];return this.$slots["prepend-inner"]?t.push(this.$slots["prepend-inner"]):this.prependInnerIcon&&t.push(this.genIcon("prependInner")),this.genSlot("prepend","inner",t)},genIconSlot:function(){var t=[];return this.$slots.append?t.push(this.$slots.append):this.appendIcon&&t.push(this.genIcon("append")),this.genSlot("append","inner",t)},genInputSlot:function(){var t=r["default"].options.methods.genInputSlot.call(this),e=this.genPrependInnerSlot();return e&&(t.children=t.children||[],t.children.unshift(e)),t},genClearIcon:function(){return this.clearable?this.isDirty?this.genSlot("append","inner",[this.genIcon("clear",this.clearableCallback)]):this.genSlot("append","inner",[this.$createElement("div")]):null},genCounter:function(){var t,e,n;if(!this.hasCounter)return null;var r=!0===this.counter?this.attrs$.maxlength:this.counter,a={dark:this.dark,light:this.light,max:r,value:this.computedCounterValue};return null!==(n=null===(e=(t=this.$scopedSlots).counter)||void 0===e?void 0:e.call(t,{props:a}))&&void 0!==n?n:this.$createElement(i["default"],{props:a})},genControl:function(){return r["default"].options.methods.genControl.call(this)},genDefaultSlot:function(){return[this.genFieldset(),this.genTextFieldSlot(),this.genClearIcon(),this.genIconSlot(),this.genProgress()]},genFieldset:function(){return this.outlined?this.$createElement("fieldset",{attrs:{"aria-hidden":!0}},[this.genLegend()]):null},genLabel:function(){if(!this.showLabel)return null;var t={props:{absolute:!0,color:this.validationState,dark:this.dark,disabled:this.isDisabled,focused:!this.isSingle&&(this.isFocused||!!this.validationState),for:this.computedId,left:this.labelPosition.left,light:this.light,right:this.labelPosition.right,value:this.labelValue}};return this.$createElement(a["default"],t,Object(d["getSlot"])(this,"label")||this.label)},genLegend:function(){var t=this.singleLine||!this.labelValue&&!this.isDirty?0:this.labelWidth,e=this.$createElement("span",{domProps:{innerHTML:"​"},staticClass:"notranslate"});return this.$createElement("legend",{style:{width:this.isSingle?void 0:Object(d["convertToUnit"])(t)}},[e])},genInput:function(){var t=Object.assign({},this.listeners$);delete t.change;var e=this.attrs$,n=(e.title,g(e,["title"]));return this.$createElement("input",{style:{},domProps:{value:"number"===this.type&&Object.is(this.lazyValue,-0)?"-0":this.lazyValue},attrs:v(v({},n),{autofocus:this.autofocus,disabled:this.isDisabled,id:this.computedId,placeholder:this.persistentPlaceholder||this.isFocused||!this.hasLabel?this.placeholder:void 0,readonly:this.isReadonly,type:this.type}),on:Object.assign(t,{blur:this.onBlur,input:this.onInput,focus:this.onFocus,keydown:this.onKeyDown}),ref:"input",directives:[{name:"resize",modifiers:{quiet:!0},value:this.onResize}]})},genMessages:function(){if(!this.showDetails)return null;var t=r["default"].options.methods.genMessages.call(this),e=this.genCounter();return this.$createElement("div",{staticClass:"v-text-field__details"},[t,e])},genTextFieldSlot:function(){return this.$createElement("div",{staticClass:"v-text-field__slot"},[this.genLabel(),this.prefix?this.genAffix("prefix"):null,this.genInput(),this.suffix?this.genAffix("suffix"):null])},genAffix:function(t){return this.$createElement("div",{class:"v-text-field__"+t,ref:t},this[t])},onBlur:function(t){var e=this;this.isFocused=!1,t&&this.$nextTick((function(){return e.$emit("blur",t)}))},onClick:function(){this.isFocused||this.isDisabled||!this.$refs.input||this.$refs.input.focus()},onFocus:function(t){if(this.$refs.input){var e=Object(h["attachedRoot"])(this.$el);if(e)return e.activeElement!==this.$refs.input?this.$refs.input.focus():void(this.isFocused||(this.isFocused=!0,t&&this.$emit("focus",t)))}},onInput:function(t){var e=t.target;this.internalValue=e.value,this.badInput=e.validity&&e.validity.badInput},onKeyDown:function(t){t.keyCode===d["keyCodes"].enter&&this.lazyValue!==this.initialValue&&(this.initialValue=this.lazyValue,this.$emit("change",this.initialValue)),this.$emit("keydown",t)},onMouseDown:function(t){t.target!==this.$refs.input&&(t.preventDefault(),t.stopPropagation()),r["default"].options.methods.onMouseDown.call(this,t)},onMouseUp:function(t){this.hasMouseDown&&this.focus(),r["default"].options.methods.onMouseUp.call(this,t)},setLabelWidth:function(){this.outlined&&(this.labelWidth=this.$refs.label?Math.min(.75*this.$refs.label.scrollWidth+6,this.$el.offsetWidth-24):0)},setPrefixWidth:function(){this.$refs.prefix&&(this.prefixWidth=this.$refs.prefix.offsetWidth)},setPrependWidth:function(){this.outlined&&this.$refs["prepend-inner"]&&(this.prependWidth=this.$refs["prepend-inner"].offsetWidth)},tryAutofocus:function(){if(!this.autofocus||"undefined"===typeof document||!this.$refs.input)return!1;var t=Object(h["attachedRoot"])(this.$el);return!(!t||t.activeElement===this.$refs.input)&&(this.$refs.input.focus(),!0)},updateValue:function(t){this.hasColor=t,t?this.initialValue=this.lazyValue:this.initialValue!==this.lazyValue&&this.$emit("change",this.lazyValue)},onResize:function(){this.setLabelWidth(),this.setPrefixWidth(),this.setPrependWidth()}}})},"./src/components/VTextField/index.ts": +/*!********************************************!*\ + !*** ./src/components/VTextField/index.ts ***! + \********************************************/ +/*! exports provided: VTextField, default */function(t,e,n){"use strict";n.r(e);var r=n(/*! ./VTextField */"./src/components/VTextField/VTextField.ts");n.d(e,"VTextField",(function(){return r["default"]})),e["default"]=r["default"]},"./src/components/VTextarea/VTextarea.sass": +/*!*************************************************!*\ + !*** ./src/components/VTextarea/VTextarea.sass ***! + \*************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VTextarea/VTextarea.ts": +/*!***********************************************!*\ + !*** ./src/components/VTextarea/VTextarea.ts ***! + \***********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VTextarea.sass */"./src/components/VTextarea/VTextarea.sass");var r=n(/*! ../VTextField/VTextField */"./src/components/VTextField/VTextField.ts"),i=n(/*! ../../util/mixins */"./src/util/mixins.ts"),a=function(){return a=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o},d=Object(s["createRange"])(24),f=Object(s["createRange"])(12),p=f.map((function(t){return t+12})),v=Object(s["createRange"])(60),g={1:"hour",2:"minute",3:"second"};e["default"]=Object(c["default"])(a["default"],o["default"]).extend({name:"v-time-picker",props:{activePicker:String,allowedHours:[Function,Array],allowedMinutes:[Function,Array],allowedSeconds:[Function,Array],disabled:Boolean,format:{type:String,default:"ampm",validator:function(t){return["ampm","24hr"].includes(t)}},min:String,max:String,readonly:Boolean,scrollable:Boolean,useSeconds:Boolean,value:null,ampmInTitle:Boolean},data:function(){return{inputHour:null,inputMinute:null,inputSecond:null,lazyInputHour:null,lazyInputMinute:null,lazyInputSecond:null,period:"am",selecting:u["SelectingTimes"].Hour}},computed:{selectingHour:{get:function(){return this.selecting===u["SelectingTimes"].Hour},set:function(t){this.selecting=u["SelectingTimes"].Hour}},selectingMinute:{get:function(){return this.selecting===u["SelectingTimes"].Minute},set:function(t){this.selecting=u["SelectingTimes"].Minute}},selectingSecond:{get:function(){return this.selecting===u["SelectingTimes"].Second},set:function(t){this.selecting=u["SelectingTimes"].Second}},isAllowedHourCb:function(){var t,e=this;if(t=this.allowedHours instanceof Array?function(t){return e.allowedHours.includes(t)}:this.allowedHours,!this.min&&!this.max)return t;var n=this.min?Number(this.min.split(":")[0]):0,r=this.max?Number(this.max.split(":")[0]):23;return function(e){return e>=1*n&&e<=1*r&&(!t||t(e))}},isAllowedMinuteCb:function(){var t,e=this,n=!this.isAllowedHourCb||null===this.inputHour||this.isAllowedHourCb(this.inputHour);if(t=this.allowedMinutes instanceof Array?function(t){return e.allowedMinutes.includes(t)}:this.allowedMinutes,!this.min&&!this.max)return n?t:function(){return!1};var r=h(this.min?this.min.split(":").map(Number):[0,0],2),i=r[0],a=r[1],o=h(this.max?this.max.split(":").map(Number):[23,59],2),s=o[0],l=o[1],c=60*i+1*a,u=60*s+1*l;return function(r){var i=60*e.inputHour+r;return i>=c&&i<=u&&n&&(!t||t(r))}},isAllowedSecondCb:function(){var t,e=this,n=!this.isAllowedHourCb||null===this.inputHour||this.isAllowedHourCb(this.inputHour),r=n&&(!this.isAllowedMinuteCb||null===this.inputMinute||this.isAllowedMinuteCb(this.inputMinute));if(t=this.allowedSeconds instanceof Array?function(t){return e.allowedSeconds.includes(t)}:this.allowedSeconds,!this.min&&!this.max)return r?t:function(){return!1};var i=h(this.min?this.min.split(":").map(Number):[0,0,0],3),a=i[0],o=i[1],s=i[2],l=h(this.max?this.max.split(":").map(Number):[23,59,59],3),c=l[0],u=l[1],d=l[2],f=3600*a+60*o+1*(s||0),p=3600*c+60*u+1*(d||0);return function(n){var i=3600*e.inputHour+60*e.inputMinute+n;return i>=f&&i<=p&&r&&(!t||t(n))}},isAmPm:function(){return"ampm"===this.format}},watch:{activePicker:"setPicker",selecting:"emitPicker",value:"setInputData"},mounted:function(){this.setInputData(this.value),this.$on("update:period",this.setPeriod)},methods:{genValue:function(){return null==this.inputHour||null==this.inputMinute||this.useSeconds&&null==this.inputSecond?null:Object(l["default"])(this.inputHour)+":"+Object(l["default"])(this.inputMinute)+(this.useSeconds?":"+Object(l["default"])(this.inputSecond):"")},emitValue:function(){var t=this.genValue();null!==t&&this.$emit("input",t)},emitPicker:function(t){var e="HOUR";t===u["SelectingTimes"].Minute?e="MINUTE":t===u["SelectingTimes"].Second&&(e="SECOND"),this.$emit("update:active-picker",e)},setPicker:function(t){"HOUR"===t?this.selecting=u["SelectingTimes"].Hour:"MINUTE"===t?this.selecting=u["SelectingTimes"].Minute:"SECOND"===t&&this.useSeconds&&(this.selecting=u["SelectingTimes"].Second)},setPeriod:function(t){if(this.period=t,null!=this.inputHour){var e=this.inputHour+("am"===t?-12:12);this.inputHour=this.firstAllowed("hour",e),this.emitValue()}},setInputData:function(t){if(null==t||""===t)this.inputHour=null,this.inputMinute=null,this.inputSecond=null;else if(t instanceof Date)this.inputHour=t.getHours(),this.inputMinute=t.getMinutes(),this.inputSecond=t.getSeconds();else{var e=h(t.trim().toLowerCase().match(/^(\d+):(\d+)(:(\d+))?([ap]m)?$/)||new Array(6),6),n=e[1],r=e[2],i=e[4],a=e[5];this.inputHour=a?this.convert12to24(parseInt(n,10),a):parseInt(n,10),this.inputMinute=parseInt(r,10),this.inputSecond=parseInt(i||0,10)}this.period=null==this.inputHour||this.inputHour<12?"am":"pm"},convert24to12:function(t){return t?(t-1)%12+1:12},convert12to24:function(t,e){return t%12+("pm"===e?12:0)},onInput:function(t){this.selecting===u["SelectingTimes"].Hour?this.inputHour=this.isAmPm?this.convert12to24(t,this.period):t:this.selecting===u["SelectingTimes"].Minute?this.inputMinute=t:this.inputSecond=t,this.emitValue()},onChange:function(t){this.$emit("click:"+g[this.selecting],t);var e=this.selecting===(this.useSeconds?u["SelectingTimes"].Second:u["SelectingTimes"].Minute);if(this.selecting===u["SelectingTimes"].Hour?this.selecting=u["SelectingTimes"].Minute:this.useSeconds&&this.selecting===u["SelectingTimes"].Minute&&(this.selecting=u["SelectingTimes"].Second),this.inputHour!==this.lazyInputHour||this.inputMinute!==this.lazyInputMinute||this.useSeconds&&this.inputSecond!==this.lazyInputSecond){var n=this.genValue();null!==n&&(this.lazyInputHour=this.inputHour,this.lazyInputMinute=this.inputMinute,this.useSeconds&&(this.lazyInputSecond=this.inputSecond),e&&this.$emit("change",n))}},firstAllowed:function(t,e){var n="hour"===t?this.isAllowedHourCb:"minute"===t?this.isAllowedMinuteCb:this.isAllowedSecondCb;if(!n)return e;var r="minute"===t||"second"===t?v:this.isAmPm?e<12?f:p:d,i=r.find((function(t){return n((t+e)%r.length+r[0])}));return((i||0)+e)%r.length+r[0]},genClock:function(){return this.$createElement(i["default"],{props:{allowedValues:this.selecting===u["SelectingTimes"].Hour?this.isAllowedHourCb:this.selecting===u["SelectingTimes"].Minute?this.isAllowedMinuteCb:this.isAllowedSecondCb,color:this.color,dark:this.dark,disabled:this.disabled,double:this.selecting===u["SelectingTimes"].Hour&&!this.isAmPm,format:this.selecting===u["SelectingTimes"].Hour?this.isAmPm?this.convert24to12:function(t){return t}:function(t){return Object(l["default"])(t,2)},light:this.light,max:this.selecting===u["SelectingTimes"].Hour?this.isAmPm&&"am"===this.period?11:23:59,min:this.selecting===u["SelectingTimes"].Hour&&this.isAmPm&&"pm"===this.period?12:0,readonly:this.readonly,scrollable:this.scrollable,size:Number(this.width)-(!this.fullWidth&&this.landscape?80:20),step:this.selecting===u["SelectingTimes"].Hour?1:5,value:this.selecting===u["SelectingTimes"].Hour?this.inputHour:this.selecting===u["SelectingTimes"].Minute?this.inputMinute:this.inputSecond},on:{input:this.onInput,change:this.onChange},ref:"clock"})},genClockAmPm:function(){return this.$createElement("div",this.setTextColor(this.color||"primary",{staticClass:"v-time-picker-clock__ampm"}),[this.genPickerButton("period","am",this.$vuetify.lang.t("$vuetify.timePicker.am"),this.disabled||this.readonly),this.genPickerButton("period","pm",this.$vuetify.lang.t("$vuetify.timePicker.pm"),this.disabled||this.readonly)])},genPickerBody:function(){return this.$createElement("div",{staticClass:"v-time-picker-clock__container",key:this.selecting},[!this.ampmInTitle&&this.isAmPm&&this.genClockAmPm(),this.genClock()])},genPickerTitle:function(){var t=this;return this.$createElement(r["default"],{props:{ampm:this.isAmPm,ampmReadonly:this.isAmPm&&!this.ampmInTitle,disabled:this.disabled,hour:this.inputHour,minute:this.inputMinute,second:this.inputSecond,period:this.period,readonly:this.readonly,useSeconds:this.useSeconds,selecting:this.selecting},on:{"update:selecting":function(e){return t.selecting=e},"update:period":function(e){return t.$emit("update:period",e)}},ref:"title",slot:"title"})}},render:function(){return this.genPicker("v-picker--time")}})},"./src/components/VTimePicker/VTimePickerClock.sass": +/*!**********************************************************!*\ + !*** ./src/components/VTimePicker/VTimePickerClock.sass ***! + \**********************************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VTimePicker/VTimePickerClock.ts": +/*!********************************************************!*\ + !*** ./src/components/VTimePicker/VTimePickerClock.ts ***! + \********************************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VTimePickerClock.sass */"./src/components/VTimePicker/VTimePickerClock.sass");var r=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),i=n(/*! ../../mixins/themeable */"./src/mixins/themeable/index.ts"),a=n(/*! ../../util/mixins */"./src/util/mixins.ts"),o=function(){return o=Object.assign||function(t){for(var e,n=1,r=arguments.length;n=this.roundCount},handScale:function(t){return this.isInner(t)?this.innerRadiusScale:1},isAllowed:function(t){return!this.allowedValues||this.allowedValues(t)},genValues:function(){for(var t=[],e=this.min;e<=this.max;e+=this.step){var n=e===this.value&&(this.color||"accent");t.push(this.$createElement("span",this.setBackgroundColor(n,{staticClass:"v-time-picker-clock__item",class:{"v-time-picker-clock__item--active":e===this.displayedValue,"v-time-picker-clock__item--disabled":this.disabled||!this.isAllowed(e)},style:this.getTransform(e),domProps:{innerHTML:""+this.format(e)+""}})))}return t},genHand:function(){var t="scaleY("+this.handScale(this.displayedValue)+")",e=this.rotate+this.degreesPerUnit*(this.displayedValue-this.min),n=null!=this.value&&(this.color||"accent");return this.$createElement("div",this.setBackgroundColor(n,{staticClass:"v-time-picker-clock__hand",class:{"v-time-picker-clock__hand--inner":this.isInner(this.value)},style:{transform:"rotate("+e+"deg) "+t}}))},getTransform:function(t){var e=this.getPosition(t),n=e.x,r=e.y;return{left:50+50*n+"%",top:50+50*r+"%"}},getPosition:function(t){var e=this.rotate*Math.PI/180;return{x:Math.sin((t-this.min)*this.degrees+e)*this.handScale(t),y:-Math.cos((t-this.min)*this.degrees+e)*this.handScale(t)}},onMouseDown:function(t){t.preventDefault(),this.valueOnMouseDown=null,this.valueOnMouseUp=null,this.isDragging=!0,this.onDragMove(t)},onMouseUp:function(t){t.stopPropagation(),this.isDragging=!1,null!==this.valueOnMouseUp&&this.isAllowed(this.valueOnMouseUp)&&this.$emit("change",this.valueOnMouseUp)},onDragMove:function(t){if(t.preventDefault(),(this.isDragging||"click"===t.type)&&this.$refs.clock)for(var e,n=this.$refs.clock.getBoundingClientRect(),r=n.width,i=n.top,a=n.left,o=this.$refs.innerClock.getBoundingClientRect().width,s=("touches"in t?t.touches[0]:t),l=s.clientX,c=s.clientY,u={x:r/2,y:-r/2},h={x:l-a,y:i-c},d=Math.round(this.angle(u,h)-this.rotate+360)%360,f=this.double&&this.euclidean(u,h)<(o+o*this.innerRadiusScale)/4,p=Math.ceil(15/this.degreesPerUnit),v=0;v0)&&!(r=a.next()).done)o.push(r.value)}catch(s){i={error:s}}finally{try{r&&!r.done&&(n=a["return"])&&n.call(a)}finally{if(i)throw i.error}}return o};e["default"]=r["default"].extend({name:"v-toolbar",props:{absolute:Boolean,bottom:Boolean,collapse:Boolean,dense:Boolean,extended:Boolean,extensionHeight:{default:48,type:[Number,String]},flat:Boolean,floating:Boolean,prominent:Boolean,short:Boolean,src:{type:[String,Object],default:""},tag:{type:String,default:"header"}},data:function(){return{isExtended:!1}},computed:{computedHeight:function(){var t=this.computedContentHeight;if(!this.isExtended)return t;var e=parseInt(this.extensionHeight);return this.isCollapsed?t:t+(isNaN(e)?0:e)},computedContentHeight:function(){return this.height?parseInt(this.height):this.isProminent&&this.dense?96:this.isProminent&&this.short?112:this.isProminent?128:this.dense?48:this.short||this.$vuetify.breakpoint.smAndDown?56:64},classes:function(){return s(s({},r["default"].options.computed.classes.call(this)),{"v-toolbar":!0,"v-toolbar--absolute":this.absolute,"v-toolbar--bottom":this.bottom,"v-toolbar--collapse":this.collapse,"v-toolbar--collapsed":this.isCollapsed,"v-toolbar--dense":this.dense,"v-toolbar--extended":this.isExtended,"v-toolbar--flat":this.flat,"v-toolbar--floating":this.floating,"v-toolbar--prominent":this.isProminent})},isCollapsed:function(){return this.collapse},isProminent:function(){return this.prominent},styles:function(){return s(s({},this.measurableStyles),{height:Object(a["convertToUnit"])(this.computedHeight)})}},created:function(){var t=this,e=[["app",""],["manual-scroll",''],["clipped-left",""],["clipped-right",""],["inverted-scroll",""],["scroll-off-screen",""],["scroll-target",""],["scroll-threshold",""],["card",""]];e.forEach((function(e){var n=l(e,2),r=n[0],i=n[1];t.$attrs.hasOwnProperty(r)&&Object(o["breaking"])(r,i,t)}))},methods:{genBackground:function(){var t={height:Object(a["convertToUnit"])(this.computedHeight),src:this.src},e=this.$scopedSlots.img?this.$scopedSlots.img({props:t}):this.$createElement(i["default"],{props:t});return this.$createElement("div",{staticClass:"v-toolbar__image"},[e])},genContent:function(){return this.$createElement("div",{staticClass:"v-toolbar__content",style:{height:Object(a["convertToUnit"])(this.computedContentHeight)}},Object(a["getSlot"])(this))},genExtension:function(){return this.$createElement("div",{staticClass:"v-toolbar__extension",style:{height:Object(a["convertToUnit"])(this.extensionHeight)}},Object(a["getSlot"])(this,"extension"))}},render:function(t){this.isExtended=this.extended||!!this.$scopedSlots.extension;var e=[this.genContent()],n=this.setBackgroundColor(this.color,{class:this.classes,style:this.styles,on:this.$listeners});return this.isExtended&&e.push(this.genExtension()),(this.src||this.$scopedSlots.img)&&e.unshift(this.genBackground()),t(this.tag,n,e)}})},"./src/components/VToolbar/index.ts": +/*!******************************************!*\ + !*** ./src/components/VToolbar/index.ts ***! + \******************************************/ +/*! exports provided: VToolbar, VToolbarItems, VToolbarTitle, default */function(t,e,n){"use strict";n.r(e),n.d(e,"VToolbarItems",(function(){return o})),n.d(e,"VToolbarTitle",(function(){return a}));var r=n(/*! ./VToolbar */"./src/components/VToolbar/VToolbar.ts");n.d(e,"VToolbar",(function(){return r["default"]}));var i=n(/*! ../../util/helpers */"./src/util/helpers.ts"),a=Object(i["createSimpleFunctional"])("v-toolbar__title"),o=Object(i["createSimpleFunctional"])("v-toolbar__items");e["default"]={$_vuetify_subcomponents:{VToolbar:r["default"],VToolbarItems:o,VToolbarTitle:a}}},"./src/components/VTooltip/VTooltip.sass": +/*!***********************************************!*\ + !*** ./src/components/VTooltip/VTooltip.sass ***! + \***********************************************/ +/*! no static exports found */function(t,e,n){},"./src/components/VTooltip/VTooltip.ts": +/*!*********************************************!*\ + !*** ./src/components/VTooltip/VTooltip.ts ***! + \*********************************************/ +/*! exports provided: default */function(t,e,n){"use strict";n.r(e);n(/*! ./VTooltip.sass */"./src/components/VTooltip/VTooltip.sass");var r=n(/*! ../../mixins/activatable */"./src/mixins/activatable/index.ts"),i=n(/*! ../../mixins/colorable */"./src/mixins/colorable/index.ts"),a=n(/*! ../../mixins/delayable */"./src/mixins/delayable/index.ts"),o=n(/*! ../../mixins/dependent */"./src/mixins/dependent/index.ts"),s=n(/*! ../../mixins/menuable */"./src/mixins/menuable/index.ts"),l=n(/*! ../../util/helpers */"./src/util/helpers.ts"),c=n(/*! ../../util/console */"./src/util/console.ts"),u=n(/*! ../../util/mixins */"./src/util/mixins.ts");e["default"]=Object(u["default"])(i["default"],a["default"],o["default"],s["default"]).extend({name:"v-tooltip",props:{closeDelay:{type:[Number,String],default:0},disabled:Boolean,openDelay:{type:[Number,String],default:0},openOnHover:{type:Boolean,default:!0},openOnFocus:{type:Boolean,default:!0},tag:{type:String,default:"span"},transition:String},data:function(){return{calculatedMinWidth:0,closeDependents:!1}},computed:{calculatedLeft:function(){var t=this.dimensions,e=t.activator,n=t.content,r=!this.bottom&&!this.left&&!this.top&&!this.right,i=!1!==this.attach?e.offsetLeft:e.left,a=0;return this.top||this.bottom||r?a=i+e.width/2-n.width/2:(this.left||this.right)&&(a=i+(this.right?e.width:-n.width)+(this.right?10:-10)),this.nudgeLeft&&(a-=parseInt(this.nudgeLeft)),this.nudgeRight&&(a+=parseInt(this.nudgeRight)),this.calcXOverflow(a,this.dimensions.content.width)+"px"},calculatedTop:function(){var t=this.dimensions,e=t.activator,n=t.content,r=!1!==this.attach?e.offsetTop:e.top,i=0;return this.top||this.bottom?i=r+(this.bottom?e.height:-n.height)+(this.bottom?10:-10):(this.left||this.right)&&(i=r+e.height/2-n.height/2),this.nudgeTop&&(i-=parseInt(this.nudgeTop)),this.nudgeBottom&&(i+=parseInt(this.nudgeBottom)),!1===this.attach&&(i+=this.pageYOffset),this.calcYOverflow(i)+"px"},classes:function(){return{"v-tooltip--top":this.top,"v-tooltip--right":this.right,"v-tooltip--bottom":this.bottom,"v-tooltip--left":this.left,"v-tooltip--attached":""===this.attach||!0===this.attach||"attach"===this.attach}},computedTransition:function(){return this.transition?this.transition:this.isActive?"scale-transition":"fade-transition"},offsetY:function(){return this.top||this.bottom},offsetX:function(){return this.left||this.right},styles:function(){return{left:this.calculatedLeft,maxWidth:Object(l["convertToUnit"])(this.maxWidth),minWidth:Object(l["convertToUnit"])(this.minWidth),top:this.calculatedTop,zIndex:this.zIndex||this.activeZIndex}}},beforeMount:function(){var t=this;this.$nextTick((function(){t.value&&t.callActivate()}))},mounted:function(){"v-slot"===Object(l["getSlotType"])(this,"activator",!0)&&Object(c["consoleError"])("v-tooltip's activator slot must be bound, try ' {{ timeline.name }} + + + diff --git a/timesketch/frontend-ng/src/components/Analyzer/TimelineSearch.vue b/timesketch/frontend-ng/src/components/Analyzer/TimelineSearch.vue index f0786bf321..a6f08a4040 100644 --- a/timesketch/frontend-ng/src/components/Analyzer/TimelineSearch.vue +++ b/timesketch/frontend-ng/src/components/Analyzer/TimelineSearch.vue @@ -63,7 +63,7 @@ export default { components:{ TsAnalyzerTimelineChip, }, - props: ['analyzerTimelineId', 'componentName'], + props: ['analyzerTimelineId', 'componentName', 'includeProcessingTimelines'], data() { return { selectedTimelines: [], @@ -75,8 +75,9 @@ export default { }, allReadyTimelines() { // Sort alphabetically based on timeline name. - const timelines = this.sketch.timelines.filter( - tl => tl.status[0].status === 'ready' + const timelines = this.sketch.timelines.filter(tl => + tl.status[0].status === 'ready' || + (this.includeProcessingTimelines && tl.status[0].status === 'processing') ); timelines.sort((a, b) => a.name.localeCompare(b.name)) return timelines; diff --git a/timesketch/frontend-ng/src/components/Explore/AggregateDialog.vue b/timesketch/frontend-ng/src/components/Explore/AggregateDialog.vue index 667eaf0533..b5d858cb20 100644 --- a/timesketch/frontend-ng/src/components/Explore/AggregateDialog.vue +++ b/timesketch/frontend-ng/src/components/Explore/AggregateDialog.vue @@ -313,11 +313,14 @@ export default { } }, computed: { + settings() { + return this.$store.state.settings + }, sketch() { return this.$store.state.sketch }, eventDateTime() { - return new Date(this.eventTimestamp).toISOString() + return new Date(this.eventTimestamp/1000).toISOString() }, selectedDistributionInterval() { return this.distributionIntervals[this.selectedDistributionIntervalIndex] @@ -555,8 +558,9 @@ export default { aggregator_name: 'field_summary', aggregator_parameters: { field: this.eventKey, - field_query_string: String(this.eventValue) - } + field_query_string: this.eventValue + }, + include_processing_timelines: !!this.settings.showProcessingTimelineEvents, }).then((response) => { this.stats = response.data.objects[0].field_summary.buckets[0] this.statsReady = true @@ -570,7 +574,8 @@ export default { aggregator_parameters: { field: this.eventKey, date_interval: this.selectedDistributionInterval - } + }, + include_processing_timelines: !!this.settings.showProcessingTimelineEvents, }).then((response) => { this.eventDistributionData = response.data.objects[0].datefield_summary.buckets[0] this.eventDistributionReady = true @@ -620,11 +625,12 @@ export default { aggregator_name: 'date_histogram', aggregator_parameters: { field: this.eventKey, - field_query_string: String(this.eventValue), + field_query_string: this.eventValue, supported_intervals: supportedIntervals, start_time: startTime.toISOString().slice(0, -1), end_time: endTime.toISOString().slice(0, -1), - } + }, + include_processing_timelines: !!this.settings.showProcessingTimelineEvents, }).then((response) => { this.data = response.data.objects[0].date_histogram.buckets[0] this.recentHistogramSeries = [{ diff --git a/timesketch/frontend-ng/src/components/Explore/EventActionMenu.vue b/timesketch/frontend-ng/src/components/Explore/EventActionMenu.vue index 26e33e5fe8..699c36e632 100644 --- a/timesketch/frontend-ng/src/components/Explore/EventActionMenu.vue +++ b/timesketch/frontend-ng/src/components/Explore/EventActionMenu.vue @@ -59,13 +59,16 @@ export default { sketch() { return this.$store.state.sketch }, + settings() { + return this.$store.state.settings + }, }, methods: { showContextWindow() { EventBus.$emit('showContextWindow', this.event) }, copyEventAsJSON() { - ApiClient.getEvent(this.sketch.id, this.event._index, this.event._id) + ApiClient.getEvent(this.sketch.id, this.event._index, this.event._id, !!this.settings.showProcessingTimelineEvents) .then((response) => { let fullEvent = response.data.objects let eventJSON = JSON.stringify(fullEvent, null, 3) diff --git a/timesketch/frontend-ng/src/components/Explore/EventDetail.vue b/timesketch/frontend-ng/src/components/Explore/EventDetail.vue index 6ca18444e0..d3d792c40b 100644 --- a/timesketch/frontend-ng/src/components/Explore/EventDetail.vue +++ b/timesketch/frontend-ng/src/components/Explore/EventDetail.vue @@ -246,16 +246,20 @@ export default { contextLinkConf() { return this.$store.state.contextLinkConf }, + settings() { + return this.$store.state.settings + }, }, methods: { getEvent: function () { let searchindexId = this.event._index let eventId = this.event._id - ApiClient.getEvent(this.sketch.id, searchindexId, eventId) + let includeProcessingTimelines = !!this.settings.showProcessingTimelineEvents + ApiClient.getEvent(this.sketch.id, searchindexId, eventId, includeProcessingTimelines) .then((response) => { this.fullEvent = response.data.objects this.comments = response.data.meta.comments - this.eventTimestamp = new Date(response.data.objects.datetime).getTime() + this.eventTimestamp = response.data.objects.timestamp this.eventTimestampDesc = response.data.objects.timestamp_desc if (this.comments.length > 0) { this.event.showComments = true diff --git a/timesketch/frontend-ng/src/components/Explore/EventList.vue b/timesketch/frontend-ng/src/components/Explore/EventList.vue index 2754d1d93a..f3980615e1 100644 --- a/timesketch/frontend-ng/src/components/Explore/EventList.vue +++ b/timesketch/frontend-ng/src/components/Explore/EventList.vue @@ -1,5 +1,5 @@