From 4d863bb894b318cda17cca42d8e572562de74516 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Sun, 3 Sep 2023 12:08:35 +0100 Subject: [PATCH 01/12] First commit --- client/src/atc/unitdatatable.ts | 2 +- client/src/index.ts | 27 +++++++ client/src/indexapp.ts | 78 +++++++++++++++++++ client/src/map/map.ts | 4 +- client/src/olympusapp.ts | 67 ++++++++++++++++ client/src/other/eventsmanager.ts | 10 +++ client/src/other/manager.ts | 52 +++++++++++++ client/src/panels/connectionstatuspanel.ts | 2 +- client/src/panels/hotgrouppanel.ts | 2 +- client/src/panels/logpanel.ts | 2 +- client/src/panels/mouseinfopanel.ts | 2 +- client/src/panels/panel.ts | 31 ++++++-- client/src/panels/paneleventsmanager.ts | 50 ++++++++++++ client/src/panels/panelsmanager.ts | 17 ++++ client/src/panels/serverstatuspanel.ts | 2 +- client/src/panels/unitcontrolpanel.ts | 2 +- client/src/panels/unitinfopanel.ts | 4 +- client/src/plugin/plugin.ts | 32 ++++++++ client/src/plugin/pluginmanager.ts | 13 ++++ client/src/plugins/helloworld/plugin.json | 6 ++ .../plugins/helloworld/pluginhelloworld.ts | 29 +++++++ client/src/popups/popup.ts | 5 ++ 22 files changed, 421 insertions(+), 18 deletions(-) create mode 100644 client/src/indexapp.ts create mode 100644 client/src/olympusapp.ts create mode 100644 client/src/other/eventsmanager.ts create mode 100644 client/src/other/manager.ts create mode 100644 client/src/panels/paneleventsmanager.ts create mode 100644 client/src/panels/panelsmanager.ts create mode 100644 client/src/plugin/plugin.ts create mode 100644 client/src/plugin/pluginmanager.ts create mode 100644 client/src/plugins/helloworld/plugin.json create mode 100644 client/src/plugins/helloworld/pluginhelloworld.ts diff --git a/client/src/atc/unitdatatable.ts b/client/src/atc/unitdatatable.ts index ea28c44e..7ad9d34d 100644 --- a/client/src/atc/unitdatatable.ts +++ b/client/src/atc/unitdatatable.ts @@ -4,7 +4,7 @@ import { Unit } from "../unit/unit"; export class UnitDataTable extends Panel { constructor(id: string) { - super(id); + super( id ); this.hide(); } diff --git a/client/src/index.ts b/client/src/index.ts index e16f8562..3a925873 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -19,6 +19,7 @@ import { SVGInjector } from "@tanem/svg-injector"; import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants"; import { ServerStatusPanel } from "./panels/serverstatuspanel"; import { WeaponsManager } from "./weapon/weaponsmanager"; +import { IndexApp } from "./indexapp"; var map: Map; @@ -90,6 +91,32 @@ function setup() { /* Load the config file */ getConfig(readConfig); + + /* + This is done like this for now as a way to make it work in the new and old world. + Over time/at some point, we'll need to start migrating the pre-existing code to an "app" format + */ + + const indexApp = new IndexApp({ + "featureSwitches": featureSwitches, + "map": map, + "missionHandler": missionHandler, + "panels": { + "connectionStatus": connectionStatusPanel, + "hotgroup": hotgroupPanel, + "infoPopup": infoPopup, + "log": logPanel, + "mouseInfo": mouseInfoPanel, + "serverStatus": serverStatusPanel, + "unitControl": unitControlPanel, + "unitInfo": unitInfoPanel + }, + "unitDataTable": unitDataTable, + "unitsManager": unitsManager + }); + + indexApp.start(); + } function readConfig(config: any) { diff --git a/client/src/indexapp.ts b/client/src/indexapp.ts new file mode 100644 index 00000000..30c20287 --- /dev/null +++ b/client/src/indexapp.ts @@ -0,0 +1,78 @@ +import { FeatureSwitches } from "./features/featureswitches"; +import { Map } from "./map/map"; +import { MissionHandler } from "./mission/missionhandler"; +import { IOlympusApp, OlympusApp } from "./olympusapp"; +import { ConnectionStatusPanel } from "./panels/connectionstatuspanel"; +import { HotgroupPanel } from "./panels/hotgrouppanel"; +import { LogPanel } from "./panels/logpanel"; +import { MouseInfoPanel } from "./panels/mouseinfopanel"; +import { Panel } from "./panels/panel"; +import { ServerStatusPanel } from "./panels/serverstatuspanel"; +import { UnitControlPanel } from "./panels/unitcontrolpanel"; +import { UnitInfoPanel } from "./panels/unitinfopanel"; +import { PluginManager } from "./plugin/pluginmanager"; +import { PluginHelloWorld } from "./plugins/helloworld/pluginhelloworld"; +import { Popup } from "./popups/popup"; +import { UnitsManager } from "./unit/unitsmanager"; + +export interface IIndexApp extends IOlympusApp { + "featureSwitches": FeatureSwitches, + "map": Map, + "missionHandler": MissionHandler, + "panels": IIndexAppPanels, + "unitsManager": UnitsManager +} + +export interface IIndexAppPanels { + "connectionStatus": ConnectionStatusPanel, + "hotgroup": HotgroupPanel, + "infoPopup": Popup, + "log": LogPanel, + "mouseInfo": MouseInfoPanel, + "serverStatus": ServerStatusPanel, + "unitControl": UnitControlPanel, + "unitInfo": UnitInfoPanel +} + +export class IndexApp extends OlympusApp { + + #pluginManager!: PluginManager; + + constructor( config:IIndexApp ) { + + super( config ); + + // this.setMap( config.map ); + + // Panels + this.getPanelsManager().add( "connectionStatus", config.panels.connectionStatus ); + this.getPanelsManager().add( "hotgroup", config.panels.hotgroup ); + this.getPanelsManager().add( "log", config.panels.log ); + this.getPanelsManager().add( "mouseInfo", config.panels.mouseInfo ); + this.getPanelsManager().add( "serverStatus", config.panels.serverStatus ); + this.getPanelsManager().add( "unitControl", config.panels.unitControl ); + this.getPanelsManager().add( "unitInfo", config.panels.unitInfo ); + + // Popup + this.getPanelsManager().add( "unitPopup", config.panels.infoPopup ); + + // Retrofitting + Object.values( this.getPanelsManager().getAll() ).forEach( ( panel:Panel ) => { + panel.setOlympusApp( this ); + }); + + // Plugins + this.#pluginManager = new PluginManager( this ); + + // Manual loading for now + this.#pluginManager.add( "helloWorld", new PluginHelloWorld( this ) ); + } + + + start() { + + super.start(); + + } + +} \ No newline at end of file diff --git a/client/src/map/map.ts b/client/src/map/map.ts index f809a388..c496e6a8 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./destinationpreviewmarker"; import { TemporaryUnitMarker } from "./temporaryunitmarker"; import { ClickableMiniMap } from "./clickableminimap"; import { SVGInjector } from '@tanem/svg-injector' -import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTootlips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants"; +import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants"; import { TargetMarker } from "./targetmarker"; import { CoalitionArea } from "./coalitionarea"; import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu"; @@ -20,7 +20,7 @@ import { DrawingCursor } from "./drawingcursor"; L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect); -// TODO would be nice to convert to ts +// TODO would be nice to convert to ts - yes require("../../public/javascripts/leaflet.nauticscale.js") require("../../public/javascripts/L.Path.Drag.js") diff --git a/client/src/olympusapp.ts b/client/src/olympusapp.ts new file mode 100644 index 00000000..aa031d7f --- /dev/null +++ b/client/src/olympusapp.ts @@ -0,0 +1,67 @@ +import { UnitDataTable } from "./atc/unitdatatable"; +import { FeatureSwitches } from "./features/featureswitches"; +import { Map } from "./map/map"; +import { MissionHandler } from "./mission/missionhandler"; +import { PanelsManager } from "./panels/panelsmanager"; +import { UnitsManager } from "./unit/unitsmanager"; + +export interface IOlympusApp { + featureSwitches: FeatureSwitches; + missionHandler: MissionHandler; + unitDataTable: UnitDataTable; + unitsManager: UnitsManager; +} + +export abstract class OlympusApp { + + #featureSwitches: FeatureSwitches; + #map!: Map; + #missionHandler: MissionHandler; + #panelsManager: PanelsManager = new PanelsManager( this ); + #unitDataTable: UnitDataTable; + #unitsManager: UnitsManager; + + constructor( config:IOlympusApp ) { + + this.#featureSwitches = config.featureSwitches; + this.#missionHandler = config.missionHandler; + this.#unitDataTable = config.unitDataTable; + this.#unitsManager = config.unitsManager; + + } + + getFeatureSwitches() { + return this.#featureSwitches; + } + + getMap() { + return this.#map; + } + + getPanelsManager() { + return this.#panelsManager; + } + + getUnitDataTable() { + return this.#unitDataTable; + } + + getUnitsManager() { + return this.#unitsManager; + } + + getWeaponsManager() { + return this.getWeaponsManager; + } + + setMap( map:Map ) { + this.#map = map; + } + + start() { + + // Start the app + + } + +} \ No newline at end of file diff --git a/client/src/other/eventsmanager.ts b/client/src/other/eventsmanager.ts new file mode 100644 index 00000000..6bdc504c --- /dev/null +++ b/client/src/other/eventsmanager.ts @@ -0,0 +1,10 @@ +import { OlympusApp } from "../olympusapp"; +import { Manager } from "./manager"; + +export abstract class EventsManager extends Manager { + + constructor( olympusApp:OlympusApp ) { + super( olympusApp ); + } + +} \ No newline at end of file diff --git a/client/src/other/manager.ts b/client/src/other/manager.ts new file mode 100644 index 00000000..80d2bddd --- /dev/null +++ b/client/src/other/manager.ts @@ -0,0 +1,52 @@ +import { OlympusApp } from "../olympusapp"; + +export interface IManager { + add:CallableFunction; +} + +export abstract class Manager { + + #items: {[key:string]: any } = {}; + #olympusApp: OlympusApp; + + constructor( olympusApp:OlympusApp ) { + + this.#olympusApp = olympusApp; + + } + + add( name:string, item:any ) { + + const regex = new RegExp( "^[a-z][a-z0-9]{2,}$", "i" ); + + if ( regex.test( name ) === false ) { + throw new Error( `Item name "${name}" does not match regex: ${regex.toString()}.` ); + } + + if ( this.#items.hasOwnProperty( name ) ) { + throw new Error( `Item with name "${name}" already exists.` ); + } + + this.#items[ name ] = item; + + } + + get( name:string ) { + + if ( this.#items.hasOwnProperty( name ) ) { + return this.#items[ name ]; + } else { + return false; + } + + } + + getAll() { + return this.#items; + } + + getOlympusApp() { + return this.#olympusApp; + } + +} \ No newline at end of file diff --git a/client/src/panels/connectionstatuspanel.ts b/client/src/panels/connectionstatuspanel.ts index 54a3f7f6..73fad262 100644 --- a/client/src/panels/connectionstatuspanel.ts +++ b/client/src/panels/connectionstatuspanel.ts @@ -2,7 +2,7 @@ import { Panel } from "./panel"; export class ConnectionStatusPanel extends Panel { constructor(ID: string) { - super(ID); + super( ID ); } update(connected: boolean) { diff --git a/client/src/panels/hotgrouppanel.ts b/client/src/panels/hotgrouppanel.ts index 5af828e6..120899bc 100644 --- a/client/src/panels/hotgrouppanel.ts +++ b/client/src/panels/hotgrouppanel.ts @@ -4,7 +4,7 @@ import { Panel } from "./panel"; export class HotgroupPanel extends Panel { constructor(ID: string) { - super(ID); + super( ID ); document.addEventListener("unitDeath", () => this.refreshHotgroups()); } diff --git a/client/src/panels/logpanel.ts b/client/src/panels/logpanel.ts index 92fbb702..68b2ea6d 100644 --- a/client/src/panels/logpanel.ts +++ b/client/src/panels/logpanel.ts @@ -8,7 +8,7 @@ export class LogPanel extends Panel { #logs: {[key: string]: string} = {}; constructor(ID: string) { - super(ID); + super( ID ); document.addEventListener("toggleLogPanel", () => { this.getElement().classList.toggle("open"); diff --git a/client/src/panels/mouseinfopanel.ts b/client/src/panels/mouseinfopanel.ts index 923cca9e..682384d0 100644 --- a/client/src/panels/mouseinfopanel.ts +++ b/client/src/panels/mouseinfopanel.ts @@ -13,7 +13,7 @@ export class MouseInfoPanel extends Panel { #measureBox: HTMLElement; constructor(ID: string) { - super(ID); + super( ID ); this.#measureIcon = new Icon({ iconUrl: 'resources/theme/images/icons/pin.svg', iconAnchor: [16, 32] }); this.#measureMarker = new Marker([0, 0], { icon: this.#measureIcon, interactive: false }); diff --git a/client/src/panels/panel.ts b/client/src/panels/panel.ts index df0a2f48..47ac9c3d 100644 --- a/client/src/panels/panel.ts +++ b/client/src/panels/panel.ts @@ -1,6 +1,11 @@ -export class Panel { +import { OlympusApp } from "../olympusapp"; +import { PanelEventsManager } from "./paneleventsmanager"; + +export abstract class Panel { + #element: HTMLElement - #visible: boolean = true; + #eventsManager!: PanelEventsManager; + #olympusApp!: OlympusApp; constructor(ID: string) { this.#element = document.getElementById(ID); @@ -8,17 +13,17 @@ export class Panel { show() { this.#element.classList.toggle("hide", false); - this.#visible = true; + this.getEventsManager()?.trigger( "show", {} ); } hide() { this.#element.classList.toggle("hide", true); - this.#visible = false; + this.getEventsManager()?.trigger( "hide", {} ); } toggle() { // Simple way to track if currently visible - if (this.#visible) + if (this.getVisible()) this.hide(); else this.show(); @@ -29,6 +34,20 @@ export class Panel { } getVisible(){ - return this.#visible; + return (!this.getElement().classList.contains( "hide" ) ); } + + getEventsManager() { + return this.#eventsManager; + } + + getOlympusApp() { + return this.#olympusApp; + } + + setOlympusApp( olympusApp:OlympusApp ) { + this.#olympusApp = olympusApp; + this.#eventsManager = new PanelEventsManager( this.getOlympusApp() ); + } + } \ No newline at end of file diff --git a/client/src/panels/paneleventsmanager.ts b/client/src/panels/paneleventsmanager.ts new file mode 100644 index 00000000..d98cf10a --- /dev/null +++ b/client/src/panels/paneleventsmanager.ts @@ -0,0 +1,50 @@ +import { OlympusApp } from "../olympusapp"; +import { EventsManager } from "../other/eventsmanager"; + +interface IListener { + callback: CallableFunction; + name?: string +} + +export class PanelEventsManager extends EventsManager { + + constructor( olympusApp:OlympusApp ) { + + super( olympusApp ); + + this.add( "hide", [] ); + this.add( "show", [] ); + + } + + on( eventName:string, listener:IListener ) { + + const event = this.get( eventName ); + + if ( !event ) { + throw new Error( `Event name "${eventName}" is not valid.` ); + } + + this.get( eventName ).push({ + "callback": listener.callback + }); + + } + + trigger( eventName:string, contextData:object ) { + + const listeners = this.get( eventName ); + + if ( listeners ) { + + listeners.forEach( ( listener:IListener ) => { + + listener.callback( contextData ); + + }); + + } + + } + +} \ No newline at end of file diff --git a/client/src/panels/panelsmanager.ts b/client/src/panels/panelsmanager.ts new file mode 100644 index 00000000..9153753b --- /dev/null +++ b/client/src/panels/panelsmanager.ts @@ -0,0 +1,17 @@ +import { OlympusApp } from "../olympusapp"; +import { Manager } from "../other/manager"; +import { Panel } from "./panel"; + +export class PanelsManager extends Manager { + + #panels: { [key:string]: Panel } = {} + + constructor( olympusApp:OlympusApp ) { + super( olympusApp ); + } + + get( name:string ): Panel { + return super.get( name ); + } + +} \ No newline at end of file diff --git a/client/src/panels/serverstatuspanel.ts b/client/src/panels/serverstatuspanel.ts index 33cb1b7a..74a87a3f 100644 --- a/client/src/panels/serverstatuspanel.ts +++ b/client/src/panels/serverstatuspanel.ts @@ -2,7 +2,7 @@ import { Panel } from "./panel"; export class ServerStatusPanel extends Panel { constructor(ID: string) { - super(ID); + super( ID ); } update(frameRate: number, load: number) { diff --git a/client/src/panels/unitcontrolpanel.ts b/client/src/panels/unitcontrolpanel.ts index 0f276367..3e2ff92a 100644 --- a/client/src/panels/unitcontrolpanel.ts +++ b/client/src/panels/unitcontrolpanel.ts @@ -26,7 +26,7 @@ export class UnitControlPanel extends Panel { #selectedUnitsTypes: string[] = []; constructor(ID: string) { - super(ID); + super( ID ); /* Unit control sliders */ this.#altitudeSlider = new Slider("altitude-slider", 0, 100, "ft", (value: number) => { getUnitsManager().selectedUnitsSetAltitude(ftToM(value)); }); diff --git a/client/src/panels/unitinfopanel.ts b/client/src/panels/unitinfopanel.ts index 2672bce2..aa39de2a 100644 --- a/client/src/panels/unitinfopanel.ts +++ b/client/src/panels/unitinfopanel.ts @@ -1,6 +1,4 @@ -import { getUnitsManager } from ".."; import { Ammo } from "../@types/unit"; -import { ConvertDDToDMS, rad2deg } from "../other/utils"; import { aircraftDatabase } from "../unit/aircraftdatabase"; import { Unit } from "../unit/unit"; import { Panel } from "./panel"; @@ -23,7 +21,7 @@ export class UnitInfoPanel extends Panel { #unitName: HTMLElement; constructor(ID: string) { - super(ID); + super( ID ); this.#altitude = (this.getElement().querySelector("#altitude")) as HTMLElement; this.#currentTask = (this.getElement().querySelector("#current-task")) as HTMLElement; diff --git a/client/src/plugin/plugin.ts b/client/src/plugin/plugin.ts new file mode 100644 index 00000000..130ade43 --- /dev/null +++ b/client/src/plugin/plugin.ts @@ -0,0 +1,32 @@ +import { OlympusApp } from "../olympusapp"; + +export interface PluginInterface { +} + +export abstract class Plugin { + + #olympusApp!:OlympusApp; + protected name = ""; + + constructor( olympusApp:OlympusApp, pluginName:string ) { + + const regex = "^[a-zA-Z][a-zA-Z\d]{4,}" + + if ( new RegExp( regex ).test( pluginName ) === false ) { + throw new Error( `Plugin names must match regex: ${regex}` ); + } + + this.name = pluginName; + this.#olympusApp = olympusApp; + + } + + getName() { + return this.name; + } + + getOlympusApp() { + return this.#olympusApp; + } + +} \ No newline at end of file diff --git a/client/src/plugin/pluginmanager.ts b/client/src/plugin/pluginmanager.ts new file mode 100644 index 00000000..7e017d5a --- /dev/null +++ b/client/src/plugin/pluginmanager.ts @@ -0,0 +1,13 @@ +import { OlympusApp } from "../olympusapp"; +import { Manager } from "../other/manager"; + + +export class PluginManager extends Manager { + + constructor( olympusApp:OlympusApp ) { + + super( olympusApp ); + + } + +} \ No newline at end of file diff --git a/client/src/plugins/helloworld/plugin.json b/client/src/plugins/helloworld/plugin.json new file mode 100644 index 00000000..c9024809 --- /dev/null +++ b/client/src/plugins/helloworld/plugin.json @@ -0,0 +1,6 @@ +{ + "author": "J. R. Hartley", + "exportedClassName": "PluginHelloWorld", + "name": "Hello World", + "version": "1.2.3" +} \ No newline at end of file diff --git a/client/src/plugins/helloworld/pluginhelloworld.ts b/client/src/plugins/helloworld/pluginhelloworld.ts new file mode 100644 index 00000000..a7126650 --- /dev/null +++ b/client/src/plugins/helloworld/pluginhelloworld.ts @@ -0,0 +1,29 @@ +import { OlympusApp } from "../../olympusapp"; +import { Plugin, PluginInterface } from "../../plugin/plugin"; + + +export class PluginHelloWorld extends Plugin implements PluginInterface { + + constructor( olympusApp:OlympusApp ) { + + super( olympusApp, "HelloWorld" ); + + const panel = this.getOlympusApp().getPanelsManager().get( "unitControl" ); + const em = panel.getEventsManager(); + + em.on( "show", { + "callback": () => { + console.log( "Showing unit control panel" ); + } + }); + + em.on( "hide", { + "callback": () => { + console.log( "Hiding unit control panel" ); + } + }); + + //const tpl = new ejs + + } +} \ No newline at end of file diff --git a/client/src/popups/popup.ts b/client/src/popups/popup.ts index 55f828ac..37af5df8 100644 --- a/client/src/popups/popup.ts +++ b/client/src/popups/popup.ts @@ -1,6 +1,11 @@ import { Panel } from "../panels/panel"; export class Popup extends Panel { + + constructor( elementId:string ) { + super( elementId ); + } + #fadeTime: number = 2000; // Milliseconds #hideTimer: number | undefined = undefined; #visibilityTimer: number | undefined = undefined; From a08eb418a661791d2767743859e8ffad5defbbbd Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Mon, 4 Sep 2023 22:54:01 +0100 Subject: [PATCH 02/12] Stash commit to open a new branch. --- client/package-lock.json | 36 ++++---- client/package.json | 4 +- client/src/index.ts | 92 ++++++++++++------- client/src/indexapp.ts | 15 +-- client/src/olympusapp.ts | 10 ++ client/src/other/manager.ts | 2 + client/src/plugin/plugin.ts | 14 ++- .../plugins/helloworld/pluginhelloworld.ts | 12 ++- client/src/shortcut/shortcut.ts | 70 ++++++++++++++ client/src/shortcut/shortcutmanager.ts | 18 ++++ 10 files changed, 203 insertions(+), 70 deletions(-) create mode 100644 client/src/shortcut/shortcut.ts create mode 100644 client/src/shortcut/shortcutmanager.ts diff --git a/client/package-lock.json b/client/package-lock.json index 44c2fe56..95dcb9ea 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -6179,9 +6179,9 @@ "dev": true }, "node_modules/nodemon": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", - "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", "dev": true, "dependencies": { "chokidar": "^3.5.2", @@ -6231,9 +6231,9 @@ "dev": true }, "node_modules/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -6840,9 +6840,9 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -12508,9 +12508,9 @@ "dev": true }, "nodemon": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", - "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", "dev": true, "requires": { "chokidar": "^3.5.2", @@ -12547,9 +12547,9 @@ "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true }, "supports-color": { @@ -13058,9 +13058,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "send": { diff --git a/client/package.json b/client/package.json index e199321e..d3df3e95 100644 --- a/client/package.json +++ b/client/package.json @@ -14,9 +14,9 @@ "debug": "~2.6.9", "ejs": "^3.1.8", "express": "~4.16.1", + "express-basic-auth": "^1.2.1", "morgan": "~1.9.1", - "save": "^2.9.0", - "express-basic-auth": "^1.2.1" + "save": "^2.9.0" }, "devDependencies": { "@babel/preset-env": "^7.21.4", diff --git a/client/src/index.ts b/client/src/index.ts index 3a925873..aabfedcf 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -20,6 +20,9 @@ import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constant import { ServerStatusPanel } from "./panels/serverstatuspanel"; import { WeaponsManager } from "./weapon/weaponsmanager"; import { IndexApp } from "./indexapp"; +import { ShortcutKeyboard } from "./shortcut/shortcut"; +import { ShortcutManager } from "./shortcut/shortcutmanager"; +import { OlympusApp } from "./olympusapp"; var map: Map; @@ -86,9 +89,6 @@ function setup() { atc.startUpdates(); } - /* Setup event handlers */ - setupEvents(); - /* Load the config file */ getConfig(readConfig); @@ -114,8 +114,9 @@ function setup() { "unitDataTable": unitDataTable, "unitsManager": unitsManager }); - - indexApp.start(); + + /* Setup event handlers */ + setupEvents( indexApp ); } @@ -131,7 +132,7 @@ function readConfig(config: any) { } } -function setupEvents() { +function setupEvents( indexApp:OlympusApp ) { /* Generic clicks */ document.addEventListener("click", (ev) => { @@ -158,48 +159,69 @@ function setupEvents() { } }); - /* Keyup events */ - document.addEventListener("keyup", ev => { - if (keyEventWasInInput(ev)) { - return; - } - switch (ev.code) { - case "KeyT": + + const shortcutManager = indexApp.getShortcutManager(); + + shortcutManager .add( "toggleDemo", new ShortcutKeyboard({ + "callback": () => { toggleDemoEnabled(); - break; - case "Quote": + }, + "code": "KeyT" + }) + ) + .add( "toggleUnitDataTable", new ShortcutKeyboard({ + "callback": () => { unitDataTable.toggle(); - break - case "Space": + }, + "code": "Quote" + }) + ) + .add( "togglePause", new ShortcutKeyboard({ + "callback": () => { setPaused(!getPaused()); - break; - case "KeyW": case "KeyA": case "KeyS": case "KeyD": - case "ArrowLeft": case "ArrowRight": case "ArrowUp": case "ArrowDown": + }, + "code": "space" + }) + ); + + [ "KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown" ].forEach( code => { + shortcutManager.add( `pan${code}keydown`, new ShortcutKeyboard({ + "callback": ( ev:KeyboardEvent ) => { getMap().handleMapPanning(ev); - break; - case "Digit1": case "Digit2": case "Digit3": case "Digit4": case "Digit5": case "Digit6": case "Digit7": case "Digit8": case "Digit9": - // Using the substring because the key will be invalid when pressing the Shift key + }, + "code": code, + "event": "keydown" + })); + }); + + [ "KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown" ].forEach( code => { + shortcutManager.add( `pan${code}keyup`, new ShortcutKeyboard({ + "callback": ( ev:KeyboardEvent ) => { + getMap().handleMapPanning(ev); + }, + "code": code + })); + }); + + [ "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9" ].forEach( code => { + shortcutManager.add( `hotgroup${code}`, new ShortcutKeyboard({ + "callback": ( ev:KeyboardEvent ) => { if (ev.ctrlKey && ev.shiftKey) getUnitsManager().selectedUnitsAddToHotgroup(parseInt(ev.code.substring(5))); else if (ev.ctrlKey && !ev.shiftKey) getUnitsManager().selectedUnitsSetHotgroup(parseInt(ev.code.substring(5))); else getUnitsManager().selectUnitsByHotgroup(parseInt(ev.code.substring(5))); - break; - } + }, + "code": code + })); }); + /* Keyup events */ + + /* Keydown events */ - document.addEventListener("keydown", ev => { - if (keyEventWasInInput(ev)) { - return; - } - switch (ev.code) { - case "KeyW": case "KeyA": case "KeyS": case "KeyD": case "ArrowLeft": case "ArrowRight": case "ArrowUp": case "ArrowDown": - getMap().handleMapPanning(ev); - break; - } - }); + document.addEventListener("closeDialog", (ev: CustomEventInit) => { ev.detail._element.closest(".ol-dialog").classList.add("hide"); diff --git a/client/src/indexapp.ts b/client/src/indexapp.ts index 30c20287..3f567586 100644 --- a/client/src/indexapp.ts +++ b/client/src/indexapp.ts @@ -45,13 +45,14 @@ export class IndexApp extends OlympusApp { // this.setMap( config.map ); // Panels - this.getPanelsManager().add( "connectionStatus", config.panels.connectionStatus ); - this.getPanelsManager().add( "hotgroup", config.panels.hotgroup ); - this.getPanelsManager().add( "log", config.panels.log ); - this.getPanelsManager().add( "mouseInfo", config.panels.mouseInfo ); - this.getPanelsManager().add( "serverStatus", config.panels.serverStatus ); - this.getPanelsManager().add( "unitControl", config.panels.unitControl ); - this.getPanelsManager().add( "unitInfo", config.panels.unitInfo ); + this.getPanelsManager() + .add( "connectionStatus", config.panels.connectionStatus ) + .add( "hotgroup", config.panels.hotgroup ) + .add( "log", config.panels.log ) + .add( "mouseInfo", config.panels.mouseInfo ) + .add( "serverStatus", config.panels.serverStatus ) + .add( "unitControl", config.panels.unitControl ) + .add( "unitInfo", config.panels.unitInfo ); // Popup this.getPanelsManager().add( "unitPopup", config.panels.infoPopup ); diff --git a/client/src/olympusapp.ts b/client/src/olympusapp.ts index aa031d7f..6d344161 100644 --- a/client/src/olympusapp.ts +++ b/client/src/olympusapp.ts @@ -3,6 +3,7 @@ import { FeatureSwitches } from "./features/featureswitches"; import { Map } from "./map/map"; import { MissionHandler } from "./mission/missionhandler"; import { PanelsManager } from "./panels/panelsmanager"; +import { ShortcutManager } from "./shortcut/shortcutmanager"; import { UnitsManager } from "./unit/unitsmanager"; export interface IOlympusApp { @@ -18,6 +19,7 @@ export abstract class OlympusApp { #map!: Map; #missionHandler: MissionHandler; #panelsManager: PanelsManager = new PanelsManager( this ); + #shortcutManager: ShortcutManager = new ShortcutManager( this ); #unitDataTable: UnitDataTable; #unitsManager: UnitsManager; @@ -38,10 +40,18 @@ export abstract class OlympusApp { return this.#map; } + getMissionHandler() { + return this.#missionHandler; + } + getPanelsManager() { return this.#panelsManager; } + getShortcutManager() { + return this.#shortcutManager; + } + getUnitDataTable() { return this.#unitDataTable; } diff --git a/client/src/other/manager.ts b/client/src/other/manager.ts index 80d2bddd..92bfd949 100644 --- a/client/src/other/manager.ts +++ b/client/src/other/manager.ts @@ -29,6 +29,8 @@ export abstract class Manager { this.#items[ name ] = item; + return this; + } get( name:string ) { diff --git a/client/src/plugin/plugin.ts b/client/src/plugin/plugin.ts index 130ade43..97204563 100644 --- a/client/src/plugin/plugin.ts +++ b/client/src/plugin/plugin.ts @@ -1,12 +1,11 @@ import { OlympusApp } from "../olympusapp"; - -export interface PluginInterface { -} +const templateParser = require( "ejs" ); export abstract class Plugin { #olympusApp!:OlympusApp; protected name = ""; + #templateParser:any; constructor( olympusApp:OlympusApp, pluginName:string ) { @@ -16,8 +15,9 @@ export abstract class Plugin { throw new Error( `Plugin names must match regex: ${regex}` ); } - this.name = pluginName; - this.#olympusApp = olympusApp; + this.name = pluginName; + this.#olympusApp = olympusApp; + this.#templateParser = templateParser; } @@ -29,4 +29,8 @@ export abstract class Plugin { return this.#olympusApp; } + getTemplateParser() { + return this.#templateParser; + } + } \ No newline at end of file diff --git a/client/src/plugins/helloworld/pluginhelloworld.ts b/client/src/plugins/helloworld/pluginhelloworld.ts index a7126650..398fee6f 100644 --- a/client/src/plugins/helloworld/pluginhelloworld.ts +++ b/client/src/plugins/helloworld/pluginhelloworld.ts @@ -1,8 +1,8 @@ import { OlympusApp } from "../../olympusapp"; -import { Plugin, PluginInterface } from "../../plugin/plugin"; +import { Plugin } from "../../plugin/plugin"; -export class PluginHelloWorld extends Plugin implements PluginInterface { +export class PluginHelloWorld extends Plugin { constructor( olympusApp:OlympusApp ) { @@ -23,7 +23,13 @@ export class PluginHelloWorld extends Plugin implements PluginInterface { } }); - //const tpl = new ejs + const tpl = ` +
+ Hello world! +
+ `; + + panel.getElement().innerHTML = this.getTemplateParser().render( tpl ); } } \ No newline at end of file diff --git a/client/src/shortcut/shortcut.ts b/client/src/shortcut/shortcut.ts new file mode 100644 index 00000000..a2b9bac0 --- /dev/null +++ b/client/src/shortcut/shortcut.ts @@ -0,0 +1,70 @@ +import { keyEventWasInInput } from "../other/utils"; + +interface IShortcut { + altKey?:boolean; + callback:CallableFunction; + ctrlKey?:boolean; + name?:string; + shiftKey?:boolean; +} + +interface IShortcutKeyboard extends IShortcut { + code:string; + event?:"keydown"|"keyup"; +} + +interface IShortcutMouse extends IShortcut { + button:number; + event:"mousedown"|"mouseup"; +} + +export abstract class Shortcut { + + #config:IShortcut + + constructor( config:IShortcut ) { + this.#config = config; + } + + getConfig() { + return this.#config; + } + +} + +export class ShortcutKeyboard extends Shortcut { + + constructor( config:IShortcutKeyboard ) { + + config.event = config.event || "keyup"; + + super( config ); + + document.addEventListener( config.event, ( ev:any ) => { + + if ( ev instanceof KeyboardEvent === false || keyEventWasInInput( ev )) { + return; + } + + if ( config.code !== ev.code ) { + return; + } + + if ( ( ( typeof config.altKey !== "boolean" ) || ( typeof config.altKey === "boolean" && ev.altKey === config.altKey ) ) + && ( ( typeof config.ctrlKey !== "boolean" ) || ( typeof config.ctrlKey === "boolean" && ev.ctrlKey === config.ctrlKey ) ) + && ( ( typeof config.shiftKey !== "boolean" ) || ( typeof config.shiftKey === "boolean" && ev.shiftKey === config.shiftKey ) ) ) { + config.callback( ev ); + } + }); + + } + +} + +export class ShortcutMouse extends Shortcut { + + constructor( config:IShortcutMouse ) { + super( config ); + } + +} \ No newline at end of file diff --git a/client/src/shortcut/shortcutmanager.ts b/client/src/shortcut/shortcutmanager.ts new file mode 100644 index 00000000..af35324a --- /dev/null +++ b/client/src/shortcut/shortcutmanager.ts @@ -0,0 +1,18 @@ +import { OlympusApp } from "../olympusapp"; +import { Manager } from "../other/manager"; +import { Shortcut } from "./shortcut"; + +export class ShortcutManager extends Manager { + + constructor( olympusApp:OlympusApp ) { + + super( olympusApp ); + + } + + add( name:string, shortcut:Shortcut ) { + super.add( name, shortcut ); + return this; + } + +} \ No newline at end of file From a99b85e646b97d21e4d9727835bebadb26eb8a30 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Mon, 4 Sep 2023 23:56:48 +0100 Subject: [PATCH 03/12] More plugin design --- client/src/index.ts | 7 +--- client/src/indexapp.ts | 7 ++-- client/src/map/map.ts | 2 +- client/src/olympusapp.ts | 8 ++-- .../plugins/helloworld/pluginhelloworld.ts | 37 ++++++++----------- 5 files changed, 25 insertions(+), 36 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index aabfedcf..2d011179 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -162,7 +162,8 @@ function setupEvents( indexApp:OlympusApp ) { const shortcutManager = indexApp.getShortcutManager(); - shortcutManager .add( "toggleDemo", new ShortcutKeyboard({ + + shortcutManager.add( "toggleDemo", new ShortcutKeyboard({ "callback": () => { toggleDemoEnabled(); }, @@ -217,10 +218,6 @@ function setupEvents( indexApp:OlympusApp ) { })); }); - /* Keyup events */ - - - /* Keydown events */ document.addEventListener("closeDialog", (ev: CustomEventInit) => { diff --git a/client/src/indexapp.ts b/client/src/indexapp.ts index 3f567586..55c589b9 100644 --- a/client/src/indexapp.ts +++ b/client/src/indexapp.ts @@ -17,7 +17,6 @@ import { UnitsManager } from "./unit/unitsmanager"; export interface IIndexApp extends IOlympusApp { "featureSwitches": FeatureSwitches, - "map": Map, "missionHandler": MissionHandler, "panels": IIndexAppPanels, "unitsManager": UnitsManager @@ -42,8 +41,6 @@ export class IndexApp extends OlympusApp { super( config ); - // this.setMap( config.map ); - // Panels this.getPanelsManager() .add( "connectionStatus", config.panels.connectionStatus ) @@ -66,7 +63,9 @@ export class IndexApp extends OlympusApp { this.#pluginManager = new PluginManager( this ); // Manual loading for now - this.#pluginManager.add( "helloWorld", new PluginHelloWorld( this ) ); + this.getMap().whenReady( () => { + this.#pluginManager.add( "helloWorld", new PluginHelloWorld( this ) ); + }); } diff --git a/client/src/map/map.ts b/client/src/map/map.ts index c496e6a8..a9afafda 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -157,7 +157,7 @@ export class Map extends L.Map { /* Pan interval */ this.#panInterval = window.setInterval(() => { - if (this.#panLeft || this.#panDown || this.#panRight || this.#panLeft) + if (this.#panUp || this.#panDown || this.#panRight || this.#panLeft) this.panBy(new L.Point(((this.#panLeft ? -1 : 0) + (this.#panRight ? 1 : 0)) * this.#deafultPanDelta, ((this.#panUp ? -1 : 0) + (this.#panDown ? 1 : 0)) * this.#deafultPanDelta)); }, 20); diff --git a/client/src/olympusapp.ts b/client/src/olympusapp.ts index 6d344161..7665fd7b 100644 --- a/client/src/olympusapp.ts +++ b/client/src/olympusapp.ts @@ -8,6 +8,7 @@ import { UnitsManager } from "./unit/unitsmanager"; export interface IOlympusApp { featureSwitches: FeatureSwitches; + map: Map, missionHandler: MissionHandler; unitDataTable: UnitDataTable; unitsManager: UnitsManager; @@ -16,7 +17,7 @@ export interface IOlympusApp { export abstract class OlympusApp { #featureSwitches: FeatureSwitches; - #map!: Map; + #map: Map; #missionHandler: MissionHandler; #panelsManager: PanelsManager = new PanelsManager( this ); #shortcutManager: ShortcutManager = new ShortcutManager( this ); @@ -26,6 +27,7 @@ export abstract class OlympusApp { constructor( config:IOlympusApp ) { this.#featureSwitches = config.featureSwitches; + this.#map = config.map; this.#missionHandler = config.missionHandler; this.#unitDataTable = config.unitDataTable; this.#unitsManager = config.unitsManager; @@ -64,10 +66,6 @@ export abstract class OlympusApp { return this.getWeaponsManager; } - setMap( map:Map ) { - this.#map = map; - } - start() { // Start the app diff --git a/client/src/plugins/helloworld/pluginhelloworld.ts b/client/src/plugins/helloworld/pluginhelloworld.ts index 398fee6f..b024cd16 100644 --- a/client/src/plugins/helloworld/pluginhelloworld.ts +++ b/client/src/plugins/helloworld/pluginhelloworld.ts @@ -1,3 +1,4 @@ +import { IndexApp } from "../../indexapp"; import { OlympusApp } from "../../olympusapp"; import { Plugin } from "../../plugin/plugin"; @@ -8,28 +9,22 @@ export class PluginHelloWorld extends Plugin { super( olympusApp, "HelloWorld" ); - const panel = this.getOlympusApp().getPanelsManager().get( "unitControl" ); - const em = panel.getEventsManager(); + const templates = { + bar: `
CTRL: Pin tool | SHIFT: box select tool
` + } - em.on( "show", { - "callback": () => { - console.log( "Showing unit control panel" ); - } - }); - - em.on( "hide", { - "callback": () => { - console.log( "Hiding unit control panel" ); - } - }); - - const tpl = ` -
- Hello world! -
- `; - - panel.getElement().innerHTML = this.getTemplateParser().render( tpl ); + document.body.insertAdjacentHTML( "beforeend", templates.bar ); } } \ No newline at end of file From 803f9a7fd6ffa40f66a0ec989802dbc54dbdba72 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Tue, 5 Sep 2023 09:43:36 +0100 Subject: [PATCH 04/12] Started working on shurtcuts plugin --- client/src/index.ts | 2 + .../plugins/helloworld/pluginhelloworld.ts | 65 ++++++++++++++++++- client/src/shortcut/shortcutmanager.ts | 28 ++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index 2d011179..347bab58 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -187,10 +187,12 @@ function setupEvents( indexApp:OlympusApp ) { [ "KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown" ].forEach( code => { shortcutManager.add( `pan${code}keydown`, new ShortcutKeyboard({ + "altKey": false, "callback": ( ev:KeyboardEvent ) => { getMap().handleMapPanning(ev); }, "code": code, + "ctrlKey": false, "event": "keydown" })); }); diff --git a/client/src/plugins/helloworld/pluginhelloworld.ts b/client/src/plugins/helloworld/pluginhelloworld.ts index b024cd16..f01cbb9f 100644 --- a/client/src/plugins/helloworld/pluginhelloworld.ts +++ b/client/src/plugins/helloworld/pluginhelloworld.ts @@ -1,10 +1,13 @@ -import { IndexApp } from "../../indexapp"; import { OlympusApp } from "../../olympusapp"; import { Plugin } from "../../plugin/plugin"; +import { ShortcutManager } from "../../shortcut/shortcutmanager"; export class PluginHelloWorld extends Plugin { + #element:HTMLElement; + #shortcutManager:ShortcutManager; + constructor( olympusApp:OlympusApp ) { super( olympusApp, "HelloWorld" ); @@ -13,18 +16,74 @@ export class PluginHelloWorld extends Plugin { bar: `
CTRL: Pin tool | SHIFT: box select tool
` + z-index:999;">` } document.body.insertAdjacentHTML( "beforeend", templates.bar ); + this.#element = document.getElementById( "shortcut-bar" ); + + this.#shortcutManager = this.getOlympusApp().getShortcutManager(); + + this.#shortcutManager.onKeyDown( () => { + this.#updateText() + }); + + this.#shortcutManager.onKeyUp( () => { + this.#updateText() + }); + + this.#updateText(); + } + + #matches( combo:string[], heldKeys:string[] ) { + + if ( combo.length !== heldKeys.length ) { + return false; + } + + return combo.every( key => heldKeys.indexOf( key ) > -1 ); + + } + + #updateText() { + + const heldKeys = this.#shortcutManager.getKeysBeingHeld(); + + const combos:Array = [ + { + "keys": [], + "text": `[CTRL]: Pin tool | [SHIFT]: box select tool
[Mouse1+drag]: Move map | [Mouse2]: Spawn menu ` + }, + { + "keys": [ "ControlLeft" ], + "text": "Mouse1: drop pin" + }, + { + "keys": [ "ShiftLeft" ], + "text": "Mouse1+drag: select units" + } + ]; + + const currentCombo:any = combos.find( (combo:any) => this.#matches( combo.keys, heldKeys ) ); + + if ( currentCombo ) { + this.#element.innerHTML = currentCombo.text; + this.#element.classList.remove( "hide" ); + } else { + this.#element.classList.add( "hide" ); + } + + } + } \ No newline at end of file diff --git a/client/src/shortcut/shortcutmanager.ts b/client/src/shortcut/shortcutmanager.ts index af35324a..9e20f5b4 100644 --- a/client/src/shortcut/shortcutmanager.ts +++ b/client/src/shortcut/shortcutmanager.ts @@ -4,10 +4,26 @@ import { Shortcut } from "./shortcut"; export class ShortcutManager extends Manager { + #keysBeingHeld:string[] = []; + #keyDownCallbacks:CallableFunction[] = []; + #keyUpCallbacks:CallableFunction[] = []; + constructor( olympusApp:OlympusApp ) { super( olympusApp ); + document.addEventListener( "keydown", ( ev:KeyboardEvent ) => { + if ( this.#keysBeingHeld.indexOf( ev.code ) < 0 ) { + this.#keysBeingHeld.push( ev.code ) + } + this.#keyDownCallbacks.forEach( callback => callback( ev ) ); + }); + + document.addEventListener( "keyup", ( ev:KeyboardEvent ) => { + this.#keysBeingHeld = this.#keysBeingHeld.filter( held => held !== ev.code ); + this.#keyUpCallbacks.forEach( callback => callback( ev ) ); + }); + } add( name:string, shortcut:Shortcut ) { @@ -15,4 +31,16 @@ export class ShortcutManager extends Manager { return this; } + getKeysBeingHeld() { + return this.#keysBeingHeld; + } + + onKeyDown( callback:CallableFunction ) { + this.#keyDownCallbacks.push( callback ); + } + + onKeyUp( callback:CallableFunction ) { + this.#keyUpCallbacks.push( callback ); + } + } \ No newline at end of file From 6aaffe20d9bf3fbc76c046ad72722f77b6ea9384 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Tue, 12 Sep 2023 19:04:52 +0100 Subject: [PATCH 05/12] Plugin (not) work. --- client/app.js | 4 ++++ client/package-lock.json | 20 ++++++++++++++++++++ client/package.json | 1 + client/src/index.ts | 5 +++-- client/src/indexapp.ts | 13 ------------- client/src/olympusapp.ts | 1 + 6 files changed, 29 insertions(+), 15 deletions(-) diff --git a/client/app.js b/client/app.js index 651c2b73..1631c683 100644 --- a/client/app.js +++ b/client/app.js @@ -19,6 +19,10 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); +if ( !fs.existsSync( "./src/_importedplugins" ) ) { + fs.mkdirSync( "./src/_importedplugins" ); +} + app.use('/', indexRouter); app.use('/api/atc', atcRouter); app.use('/api/airbases', airbasesRouter); diff --git a/client/package-lock.json b/client/package-lock.json index 95dcb9ea..c137234a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -38,6 +38,7 @@ "leaflet-path-drag": "*", "leaflet.nauticscale": "^1.1.0", "nodemon": "^2.0.20", + "requirejs": "^2.3.6", "sortablejs": "^1.15.0", "tsify": "^5.0.4", "typescript": "^4.9.4", @@ -6776,6 +6777,19 @@ "node": ">=0.10.0" } }, + "node_modules/requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true, + "bin": { + "r_js": "bin/r.js", + "r.js": "bin/r.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -13000,6 +13014,12 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", diff --git a/client/package.json b/client/package.json index d3df3e95..fcf651cc 100644 --- a/client/package.json +++ b/client/package.json @@ -40,6 +40,7 @@ "leaflet-path-drag": "*", "leaflet.nauticscale": "^1.1.0", "nodemon": "^2.0.20", + "requirejs": "^2.3.6", "sortablejs": "^1.15.0", "tsify": "^5.0.4", "typescript": "^4.9.4", diff --git a/client/src/index.ts b/client/src/index.ts index 347bab58..865cf2ef 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -11,7 +11,6 @@ import { FeatureSwitches } from "./features/featureswitches"; import { LogPanel } from "./panels/logpanel"; import { getConfig, getPaused, setAddress, setCredentials, setPaused, startUpdate, toggleDemoEnabled } from "./server/server"; import { UnitDataTable } from "./atc/unitdatatable"; -import { keyEventWasInInput } from "./other/utils"; import { Popup } from "./popups/popup"; import { Dropdown } from "./controls/dropdown"; import { HotgroupPanel } from "./panels/hotgrouppanel"; @@ -21,9 +20,9 @@ import { ServerStatusPanel } from "./panels/serverstatuspanel"; import { WeaponsManager } from "./weapon/weaponsmanager"; import { IndexApp } from "./indexapp"; import { ShortcutKeyboard } from "./shortcut/shortcut"; -import { ShortcutManager } from "./shortcut/shortcutmanager"; import { OlympusApp } from "./olympusapp"; + var map: Map; var unitsManager: UnitsManager; @@ -118,6 +117,8 @@ function setup() { /* Setup event handlers */ setupEvents( indexApp ); + indexApp.start(); + } function readConfig(config: any) { diff --git a/client/src/indexapp.ts b/client/src/indexapp.ts index 55c589b9..d6779b2c 100644 --- a/client/src/indexapp.ts +++ b/client/src/indexapp.ts @@ -1,5 +1,4 @@ import { FeatureSwitches } from "./features/featureswitches"; -import { Map } from "./map/map"; import { MissionHandler } from "./mission/missionhandler"; import { IOlympusApp, OlympusApp } from "./olympusapp"; import { ConnectionStatusPanel } from "./panels/connectionstatuspanel"; @@ -10,8 +9,6 @@ import { Panel } from "./panels/panel"; import { ServerStatusPanel } from "./panels/serverstatuspanel"; import { UnitControlPanel } from "./panels/unitcontrolpanel"; import { UnitInfoPanel } from "./panels/unitinfopanel"; -import { PluginManager } from "./plugin/pluginmanager"; -import { PluginHelloWorld } from "./plugins/helloworld/pluginhelloworld"; import { Popup } from "./popups/popup"; import { UnitsManager } from "./unit/unitsmanager"; @@ -35,8 +32,6 @@ export interface IIndexAppPanels { export class IndexApp extends OlympusApp { - #pluginManager!: PluginManager; - constructor( config:IIndexApp ) { super( config ); @@ -58,14 +53,6 @@ export class IndexApp extends OlympusApp { Object.values( this.getPanelsManager().getAll() ).forEach( ( panel:Panel ) => { panel.setOlympusApp( this ); }); - - // Plugins - this.#pluginManager = new PluginManager( this ); - - // Manual loading for now - this.getMap().whenReady( () => { - this.#pluginManager.add( "helloWorld", new PluginHelloWorld( this ) ); - }); } diff --git a/client/src/olympusapp.ts b/client/src/olympusapp.ts index 7665fd7b..d444cceb 100644 --- a/client/src/olympusapp.ts +++ b/client/src/olympusapp.ts @@ -6,6 +6,7 @@ import { PanelsManager } from "./panels/panelsmanager"; import { ShortcutManager } from "./shortcut/shortcutmanager"; import { UnitsManager } from "./unit/unitsmanager"; + export interface IOlympusApp { featureSwitches: FeatureSwitches; map: Map, From d2e162edbf4a0e401a68fa1a5c2af90ed5d54118 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Tue, 12 Sep 2023 19:07:36 +0100 Subject: [PATCH 06/12] Removed directory creation. --- client/app.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/app.js b/client/app.js index 1631c683..651c2b73 100644 --- a/client/app.js +++ b/client/app.js @@ -19,10 +19,6 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); -if ( !fs.existsSync( "./src/_importedplugins" ) ) { - fs.mkdirSync( "./src/_importedplugins" ); -} - app.use('/', indexRouter); app.use('/api/atc', atcRouter); app.use('/api/airbases', airbasesRouter); From 798856c649b0d2699075780df51ab6b179c6a5b3 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Thu, 14 Sep 2023 17:55:01 +0100 Subject: [PATCH 07/12] Nearly final commit of control tips' v1 --- client/package-lock.json | 8407 +++-------------- client/package.json | 1 + client/public/stylesheets/leaflet/leaflet.css | 7 +- client/public/stylesheets/olympus.css | 1 + .../public/stylesheets/other/controltips.css | 33 + client/src/constants/constants.ts | 1 + client/src/features/featureswitches.ts | 23 +- client/src/index.ts | 4 +- client/src/indexapp.ts | 3 + client/src/map/map.ts | 31 +- client/src/olympusapp.ts | 10 + client/src/panels/panel.ts | 8 +- client/src/plugins/helloworld/plugin.json | 6 - .../plugins/helloworld/pluginhelloworld.ts | 89 - client/src/shortcut/controltips.ts | 193 + client/src/shortcut/shortcutmanager.ts | 12 + client/src/unit/unit.ts | 21 +- client/views/index.ejs | 2 + client/views/other/controltips.ejs | 1 + client/views/toolbars/primary.ejs | 3 +- 20 files changed, 1612 insertions(+), 7244 deletions(-) create mode 100644 client/public/stylesheets/other/controltips.css delete mode 100644 client/src/plugins/helloworld/plugin.json delete mode 100644 client/src/plugins/helloworld/pluginhelloworld.ts create mode 100644 client/src/shortcut/controltips.ts create mode 100644 client/views/other/controltips.ejs diff --git a/client/package-lock.json b/client/package-lock.json index c137234a..c5936a66 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,7 +1,7 @@ { "name": "DCSOlympus", "version": "v0.4.3-alpha", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -41,6 +41,7 @@ "requirejs": "^2.3.6", "sortablejs": "^1.15.0", "tsify": "^5.0.4", + "tslib": "latest", "typescript": "^4.9.4", "watchify": "^4.0.0" } @@ -59,47 +60,48 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.17.tgz", + "integrity": "sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.22.17", + "@babel/helpers": "^7.22.15", + "@babel/parser": "^7.22.16", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.17", + "@babel/types": "^7.22.17", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -109,12 +111,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, "node_modules/@babel/core/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -139,12 +135,12 @@ "dev": true }, "node_modules/@babel/generator": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", - "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", + "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", "dev": true, "dependencies": { - "@babel/types": "^7.21.4", + "@babel/types": "^7.22.15", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -154,63 +150,60 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", "dev": true, "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", - "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-member-expression-to-functions": "^7.21.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -220,13 +213,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz", - "integrity": "sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.3.1" + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -236,20 +230,19 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", + "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.4.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { @@ -276,125 +269,112 @@ "dev": true }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "dev": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", - "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz", + "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==", "dev": true, "dependencies": { - "@babel/types": "^7.21.0" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz", + "integrity": "sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.15" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.17.tgz", + "integrity": "sha512-bxH77R5gjH3Nkde6/LuncQoLaP16THYPscurp1S8z7S9ZgezCyV3G8Hc+TZiCmY8pz4fp8CvKSgtJMW0FkLAxA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.17" }, "engines": { "node": ">=6.9.0" @@ -404,194 +384,131 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", - "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", + "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.20.7", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, "dependencies": { - "@babel/types": "^7.20.0" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.17.tgz", + "integrity": "sha512-nAhoheCMlrqU41tAojw9GpVEKDlTS8r3lzFmF0lP52LwblCPbuFSO7nGIZoIcoU5NIm1ABrna0cJExE4Ay6l2Q==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.17" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", + "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -601,12 +518,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", + "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -616,14 +533,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", - "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", + "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-proposal-optional-chaining": "^7.20.7" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -632,232 +549,11 @@ "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", - "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", - "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", - "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", - "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", - "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, "engines": { "node": ">=6.9.0" }, @@ -865,22 +561,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -945,12 +625,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -959,6 +639,33 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -1073,13 +780,47 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", - "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz", + "integrity": "sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { "node": ">=6.9.0" @@ -1089,14 +830,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", - "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9" + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1106,12 +847,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1121,12 +862,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", - "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz", + "integrity": "sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1135,20 +876,53 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", - "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", + "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, "engines": { @@ -1159,13 +933,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", - "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/template": "^7.20.7" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1175,12 +949,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", - "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.15.tgz", + "integrity": "sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1190,13 +964,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1206,12 +980,28 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1221,13 +1011,29 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1237,12 +1043,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", - "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", + "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1252,14 +1058,30 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1269,12 +1091,28 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -1284,12 +1122,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1299,13 +1137,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", - "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", + "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1315,14 +1153,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", - "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz", + "integrity": "sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-simple-access": "^7.20.2" + "@babel/helper-module-transforms": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1332,15 +1170,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", - "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz", + "integrity": "sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1350,13 +1188,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1366,13 +1204,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1382,12 +1220,63 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", + "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1397,13 +1286,46 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.15.tgz", + "integrity": "sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1413,12 +1335,46 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", - "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", + "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1428,12 +1384,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1443,13 +1399,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz", + "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "regenerator-transform": "^0.15.1" + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1459,12 +1415,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1474,12 +1430,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1489,13 +1445,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", - "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1505,12 +1461,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1520,12 +1476,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1535,12 +1491,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1550,12 +1506,28 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", + "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1565,13 +1537,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1580,39 +1552,43 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", - "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", - "@babel/plugin-proposal-async-generator-functions": "^7.20.7", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.21.0", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.7", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.21.0", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.21.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.15.tgz", + "integrity": "sha512-tZFHr54GBkHk6hQuVA8w4Fmq+MSPsfvMG0vPnOYyTnJpyfMqybL8/MbNCPRT9zc2KBO2pe4tq15g6Uno4Jpoag==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1622,45 +1598,62 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.20.7", - "@babel/plugin-transform-async-to-generator": "^7.20.7", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.21.0", - "@babel/plugin-transform-classes": "^7.21.0", - "@babel/plugin-transform-computed-properties": "^7.20.7", - "@babel/plugin-transform-destructuring": "^7.21.3", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.21.0", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.20.11", - "@babel/plugin-transform-modules-commonjs": "^7.21.2", - "@babel/plugin-transform-modules-systemjs": "^7.20.11", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.21.3", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.20.5", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.20.7", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.21.4", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.15", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.15", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.11", + "@babel/plugin-transform-classes": "^7.22.15", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.15", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-for-of": "^7.22.15", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.15", + "@babel/plugin-transform-modules-systemjs": "^7.22.11", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.15", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.22.15", + "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.10", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.10", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "@babel/types": "^7.22.15", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1670,19 +1663,17 @@ } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/regjsgen": { @@ -1692,45 +1683,45 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", "dev": true, "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", - "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", + "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.16", + "@babel/types": "^7.22.17", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1762,13 +1753,13 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.15", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1790,9 +1781,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1814,30 +1805,24 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@tanem/svg-injector": { - "version": "10.1.55", - "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-10.1.55.tgz", - "integrity": "sha512-xh8ejdvjDaH1eddZC0CdI45eeid4BIU2ppjNEhiTiWMYcLGT19KWjbES/ttDS4mq9gIAQfXx57g5zimEVohqYA==", + "version": "10.1.62", + "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-10.1.62.tgz", + "integrity": "sha512-74/VTSpUfbdPstcIqzLKLcSp/DXfsrFpzxnh/FGGQFEqQZ59IqgFqjB2TALGwZihmepiC5JobKRA+hRnrjmzFA==", "dev": true, "dependencies": { - "@babel/runtime": "^7.21.5", + "@babel/runtime": "^7.22.6", "content-type": "^1.0.5", - "tslib": "^2.5.0" + "tslib": "^2.6.1" } }, "node_modules/@turf/along": { @@ -3530,24 +3515,24 @@ "dev": true }, "node_modules/@types/leaflet": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.0.tgz", - "integrity": "sha512-7LeOSj7EloC5UcyOMo+1kc3S1UT3MjJxwqsMT1d2PTyvQz53w0Y0oSSk9nwZnOZubCmBvpSNGceucxiq+ZPEUw==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-kfwgQf4eOxoe/tD9CaKQrBKHbc7VpyfJOG5sxsQtkH+ML9xYa8hUC3UMa0wU1pKfciJtO0pU9g9XbWhPo7iBCA==", "dev": true, "dependencies": { "@types/geojson": "*" } }, "node_modules/@types/node": { - "version": "18.16.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz", - "integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==", + "version": "18.17.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.15.tgz", + "integrity": "sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==", "dev": true }, "node_modules/@types/sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-qrhtM7M41EhH4tZQTNw2/RJkxllBx3reiJpTbgWCM2Dx0U1sZ6LwKp9lfNln9uqE26ZMKUaPEYaD4rzvOWYtZw==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.2.tgz", + "integrity": "sha512-mOIv/EnPMzAZAVbuh9uGjOZ1BBdimP9Y6IPGntsvQJtko5yapSDKB7GwB3AOlF5N3bkpk4sBwQRpS3aEkiUbaA==", "dev": true }, "node_modules/@types/svg-injector": { @@ -3616,17 +3601,15 @@ } }, "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=4" } }, "node_modules/any-promise": { @@ -3672,28 +3655,28 @@ "dev": true }, "node_modules/assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", + "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", "dev": true, "dependencies": { - "object-assign": "^4.1.1", - "util": "0.10.3" + "object.assign": "^4.1.4", + "util": "^0.10.4" } }, "node_modules/assert/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", "dev": true }, "node_modules/assert/node_modules/util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "dev": true, "dependencies": { - "inherits": "2.0.1" + "inherits": "2.0.3" } }, "node_modules/async": { @@ -3804,42 +3787,42 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", + "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz", + "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.4.2", + "core-js-compat": "^3.31.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", + "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.4.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-runtime": { @@ -3975,6 +3958,11 @@ "node": ">= 0.8" } }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -4189,16 +4177,10 @@ "safe-buffer": "^5.2.0" } }, - "node_modules/browserify-sign/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -4209,26 +4191,6 @@ "node": ">= 6" } }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", @@ -4239,9 +4201,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -4251,13 +4213,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" }, "bin": { "browserslist": "cli.js" @@ -4322,9 +4288,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001481", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", - "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", + "version": "1.0.30001534", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz", + "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==", "dev": true, "funding": [ { @@ -4342,18 +4308,17 @@ ] }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=4" } }, "node_modules/chokidar": { @@ -4408,20 +4373,19 @@ } }, "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/combine-source-map": { "version": "0.8.0", @@ -4435,6 +4399,12 @@ "source-map": "~0.5.3" } }, + "node_modules/combine-source-map/node_modules/convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", + "dev": true + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -4515,6 +4485,76 @@ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/concurrently/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/concurrently/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4559,9 +4599,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, "node_modules/cookie": { @@ -4598,12 +4638,12 @@ "hasInstallScript": true }, "node_modules/core-js-compat": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.1.tgz", - "integrity": "sha512-d690npR7MC6P0gq4npTl5n2VQeNAmUrJ90n+MHiKS7W2+xno4o3F5GDEuylSdi6EJ3VssibSGXOa1r3YXD3Mhw==", + "version": "3.32.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz", + "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==", "dev": true, "dependencies": { - "browserslist": "^4.21.5" + "browserslist": "^4.21.10" }, "funding": { "type": "opencollective", @@ -4715,10 +4755,13 @@ "dev": true }, "node_modules/date-fns": { - "version": "2.29.3", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", - "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, "engines": { "node": ">=0.11" }, @@ -4752,12 +4795,27 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "node_modules/define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", "dev": true, "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -4807,9 +4865,9 @@ } }, "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", "dev": true, "dependencies": { "inherits": "^2.0.1", @@ -4891,9 +4949,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", "dependencies": { "jake": "^10.8.5" }, @@ -4905,9 +4963,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.371", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.371.tgz", - "integrity": "sha512-jlBzY4tFcJaiUjzhRTCWAqRvTO/fWzjA3Bls0mykzGZ7zvcMP7h05W6UcgzfT9Ca1SW2xyKDOFRyI0pQeRNZGw==", + "version": "1.4.520", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.520.tgz", + "integrity": "sha512-Frfus2VpYADsrh1lB3v/ft/WVFlVzOIm+Q0p7U7VqHI6qr7NWHYKe+Wif3W50n7JAFoBsWVsoU0+qDks6WQ60g==", "dev": true }, "node_modules/elliptic": { @@ -4931,12 +4989,6 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/elliptic/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5107,6 +5159,11 @@ "node": ">= 0.6" } }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", @@ -5130,9 +5187,9 @@ } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5212,9 +5269,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -5308,13 +5365,14 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" }, "funding": { @@ -5408,11 +5466,12 @@ } }, "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/has-property-descriptors": { @@ -5427,6 +5486,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -5468,16 +5539,10 @@ "node": ">=4" } }, - "node_modules/hash-base/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -5488,26 +5553,6 @@ "node": ">= 6" } }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -5552,6 +5597,11 @@ "node": ">= 0.6" } }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -5606,9 +5656,10 @@ } }, "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/inline-source-map": { "version": "0.6.2", @@ -5710,9 +5761,9 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -5807,16 +5858,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -5838,14 +5885,14 @@ "dev": true }, "node_modules/jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" + "filelist": "^1.0.4", + "minimatch": "^3.1.2" }, "bin": { "jake": "bin/cli.js" @@ -5854,6 +5901,70 @@ "node": ">=10" } }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5920,9 +6031,9 @@ } }, "node_modules/leaflet": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz", - "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", "dev": true }, "node_modules/leaflet-control-mini-map": { @@ -6074,9 +6185,9 @@ } }, "node_modules/mingo": { - "version": "6.2.7", - "resolved": "https://registry.npmjs.org/mingo/-/mingo-6.2.7.tgz", - "integrity": "sha512-r+yKmrZ+6SjwGxSot+/3S8sP9+LCxWNueR6xppMx7BzV60OegjbeklWAf/UveyQi8PDW8g/mwrQSHZVY/5jBJQ==" + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/mingo/-/mingo-6.4.4.tgz", + "integrity": "sha512-GtgwqyBVLxKf8tSvN26TjbK+XAUW5HlWR3D7qBsBh9urQyZznqG2BOx90t3MXklpSxawjvaANiWFUCIxd9xa7w==" }, "node_modules/minimalistic-assert": { "version": "1.0.1", @@ -6102,9 +6213,9 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6174,9 +6285,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, "node_modules/nodemon": { @@ -6216,15 +6327,6 @@ "ms": "^2.1.1" } }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/nodemon/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -6240,18 +6342,6 @@ "semver": "bin/semver" } }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -6285,6 +6375,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-is": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", @@ -6310,6 +6409,24 @@ "node": ">= 0.4" } }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -6560,16 +6677,6 @@ "node": ">=0.6" } }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", @@ -6645,9 +6752,9 @@ } }, "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", @@ -6659,6 +6766,12 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/readable-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -6699,29 +6812,29 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", "dev": true }, "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "set-function-name": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -6791,12 +6904,12 @@ } }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "dev": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -6824,18 +6937,33 @@ "dev": true }, "node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -6899,6 +7027,20 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -6927,14 +7069,28 @@ } }, "node_modules/shell-quote": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", - "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -7038,16 +7194,10 @@ "readable-stream": "^3.5.0" } }, - "node_modules/stream-browserify/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -7089,16 +7239,10 @@ "xtend": "^4.0.2" } }, - "node_modules/stream-http/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/stream-http/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -7128,26 +7272,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7205,14 +7329,15 @@ } }, "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -7371,9 +7496,9 @@ } }, "node_modules/tslib": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", - "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, "node_modules/tty-browserify": { @@ -7407,9 +7532,9 @@ "dev": true }, "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7529,20 +7654,29 @@ } }, "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.2.tgz", + "integrity": "sha512-7yIgNnrST44S7PJ5+jXbdIupfU1nWUdQJBFBeJRclPXiWgCvrSq5Frw8lr/i//n5sqDfzoKmBymMS81l4U/7cg==", "dev": true, "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" + "punycode": "^1.4.1", + "qs": "^6.11.2" } }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true + "node_modules/url/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/util": { "version": "0.12.5", @@ -7607,9 +7741,9 @@ } }, "node_modules/watchify/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -7630,17 +7764,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -7666,6 +7799,39 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -7697,9 +7863,9 @@ "dev": true }, "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { "cliui": "^8.0.1", @@ -7723,6036 +7889,5 @@ "node": ">=12" } } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", - "dev": true - }, - "@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", - "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", - "dev": true, - "requires": { - "@babel/types": "^7.21.4", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", - "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-member-expression-to-functions": "^7.21.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz", - "integrity": "sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.3.1" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", - "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", - "dev": true, - "requires": { - "@babel/types": "^7.21.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.21.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-replace-supers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", - "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.20.7", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" - } - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "requires": { - "@babel/types": "^7.20.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - } - }, - "@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", - "dev": true - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", - "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-proposal-optional-chaining": "^7.20.7" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", - "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", - "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", - "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", - "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.7" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", - "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", - "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", - "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", - "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", - "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", - "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/template": "^7.20.7" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", - "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", - "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", - "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", - "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-simple-access": "^7.20.2" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", - "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-identifier": "^7.19.1" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", - "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "regenerator-transform": "^0.15.1" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", - "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/preset-env": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", - "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", - "@babel/plugin-proposal-async-generator-functions": "^7.20.7", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.21.0", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.7", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.21.0", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.21.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.20.7", - "@babel/plugin-transform-async-to-generator": "^7.20.7", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.21.0", - "@babel/plugin-transform-classes": "^7.21.0", - "@babel/plugin-transform-computed-properties": "^7.20.7", - "@babel/plugin-transform-destructuring": "^7.21.3", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.21.0", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.20.11", - "@babel/plugin-transform-modules-commonjs": "^7.21.2", - "@babel/plugin-transform-modules-systemjs": "^7.20.11", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.21.3", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.20.5", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.20.7", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.21.4", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, - "@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.11" - } - }, - "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - } - }, - "@babel/traverse": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", - "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - } - } - }, - "@tanem/svg-injector": { - "version": "10.1.55", - "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-10.1.55.tgz", - "integrity": "sha512-xh8ejdvjDaH1eddZC0CdI45eeid4BIU2ppjNEhiTiWMYcLGT19KWjbES/ttDS4mq9gIAQfXx57g5zimEVohqYA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.21.5", - "content-type": "^1.0.5", - "tslib": "^2.5.0" - } - }, - "@turf/along": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/along/-/along-6.5.0.tgz", - "integrity": "sha512-LLyWQ0AARqJCmMcIEAXF4GEu8usmd4Kbz3qk1Oy5HoRNpZX47+i5exQtmIWKdqJ1MMhW26fCTXgpsEs5zgJ5gw==", - "dev": true, - "requires": { - "@turf/bearing": "^6.5.0", - "@turf/destination": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/angle": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/angle/-/angle-6.5.0.tgz", - "integrity": "sha512-4pXMbWhFofJJAOvTMCns6N4C8CMd5Ih4O2jSAG9b3dDHakj3O4yN1+Zbm+NUei+eVEZ9gFeVp9svE3aMDenIkw==", - "dev": true, - "requires": { - "@turf/bearing": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/rhumb-bearing": "^6.5.0" - } - }, - "@turf/area": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/area/-/area-6.5.0.tgz", - "integrity": "sha512-xCZdiuojokLbQ+29qR6qoMD89hv+JAgWjLrwSEWL+3JV8IXKeNFl6XkEJz9HGkVpnXvQKJoRz4/liT+8ZZ5Jyg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/bbox": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-6.5.0.tgz", - "integrity": "sha512-RBbLaao5hXTYyyg577iuMtDB8ehxMlUqHEJiMs8jT1GHkFhr6sYre3lmLsPeYEi/ZKj5TP5tt7fkzNdJ4GIVyw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/bbox-clip": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/bbox-clip/-/bbox-clip-6.5.0.tgz", - "integrity": "sha512-F6PaIRF8WMp8EmgU/Ke5B1Y6/pia14UAYB5TiBC668w5rVVjy5L8rTm/m2lEkkDMHlzoP9vNY4pxpNthE7rLcQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/bbox-polygon": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/bbox-polygon/-/bbox-polygon-6.5.0.tgz", - "integrity": "sha512-+/r0NyL1lOG3zKZmmf6L8ommU07HliP4dgYToMoTxqzsWzyLjaj/OzgQ8rBmv703WJX+aS6yCmLuIhYqyufyuw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/bearing": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-6.5.0.tgz", - "integrity": "sha512-dxINYhIEMzgDOztyMZc20I7ssYVNEpSv04VbMo5YPQsqa80KO3TFvbuCahMsCAW5z8Tncc8dwBlEFrmRjJG33A==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/bezier-spline": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/bezier-spline/-/bezier-spline-6.5.0.tgz", - "integrity": "sha512-vokPaurTd4PF96rRgGVm6zYYC5r1u98ZsG+wZEv9y3kJTuJRX/O3xIY2QnTGTdbVmAJN1ouOsD0RoZYaVoXORQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/boolean-clockwise": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-6.5.0.tgz", - "integrity": "sha512-45+C7LC5RMbRWrxh3Z0Eihsc8db1VGBO5d9BLTOAwU4jR6SgsunTfRWR16X7JUwIDYlCVEmnjcXJNi/kIU3VIw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/boolean-contains": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-contains/-/boolean-contains-6.5.0.tgz", - "integrity": "sha512-4m8cJpbw+YQcKVGi8y0cHhBUnYT+QRfx6wzM4GI1IdtYH3p4oh/DOBJKrepQyiDzFDaNIjxuWXBh0ai1zVwOQQ==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/boolean-point-on-line": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/boolean-crosses": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-crosses/-/boolean-crosses-6.5.0.tgz", - "integrity": "sha512-gvshbTPhAHporTlQwBJqyfW+2yV8q/mOTxG6PzRVl6ARsqNoqYQWkd4MLug7OmAqVyBzLK3201uAeBjxbGw0Ng==", - "dev": true, - "requires": { - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/line-intersect": "^6.5.0", - "@turf/polygon-to-line": "^6.5.0" - } - }, - "@turf/boolean-disjoint": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-disjoint/-/boolean-disjoint-6.5.0.tgz", - "integrity": "sha512-rZ2ozlrRLIAGo2bjQ/ZUu4oZ/+ZjGvLkN5CKXSKBcu6xFO6k2bgqeM8a1836tAW+Pqp/ZFsTA5fZHsJZvP2D5g==", - "dev": true, - "requires": { - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/line-intersect": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/polygon-to-line": "^6.5.0" - } - }, - "@turf/boolean-equal": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-equal/-/boolean-equal-6.5.0.tgz", - "integrity": "sha512-cY0M3yoLC26mhAnjv1gyYNQjn7wxIXmL2hBmI/qs8g5uKuC2hRWi13ydufE3k4x0aNRjFGlg41fjoYLwaVF+9Q==", - "dev": true, - "requires": { - "@turf/clean-coords": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "geojson-equality": "0.1.6" - } - }, - "@turf/boolean-intersects": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-intersects/-/boolean-intersects-6.5.0.tgz", - "integrity": "sha512-nIxkizjRdjKCYFQMnml6cjPsDOBCThrt+nkqtSEcxkKMhAQj5OO7o2CecioNTaX8EayqwMGVKcsz27oP4mKPTw==", - "dev": true, - "requires": { - "@turf/boolean-disjoint": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/boolean-overlap": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-overlap/-/boolean-overlap-6.5.0.tgz", - "integrity": "sha512-8btMIdnbXVWUa1M7D4shyaSGxLRw6NjMcqKBcsTXcZdnaixl22k7ar7BvIzkaRYN3SFECk9VGXfLncNS3ckQUw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/line-intersect": "^6.5.0", - "@turf/line-overlap": "^6.5.0", - "@turf/meta": "^6.5.0", - "geojson-equality": "0.1.6" - } - }, - "@turf/boolean-parallel": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-parallel/-/boolean-parallel-6.5.0.tgz", - "integrity": "sha512-aSHJsr1nq9e5TthZGZ9CZYeXklJyRgR5kCLm5X4urz7+MotMOp/LsGOsvKvK9NeUl9+8OUmfMn8EFTT8LkcvIQ==", - "dev": true, - "requires": { - "@turf/clean-coords": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/line-segment": "^6.5.0", - "@turf/rhumb-bearing": "^6.5.0" - } - }, - "@turf/boolean-point-in-polygon": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-6.5.0.tgz", - "integrity": "sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/boolean-point-on-line": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-point-on-line/-/boolean-point-on-line-6.5.0.tgz", - "integrity": "sha512-A1BbuQ0LceLHvq7F/P7w3QvfpmZqbmViIUPHdNLvZimFNLo4e6IQunmzbe+8aSStH9QRZm3VOflyvNeXvvpZEQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/boolean-within": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-within/-/boolean-within-6.5.0.tgz", - "integrity": "sha512-YQB3oU18Inx35C/LU930D36RAVe7LDXk1kWsQ8mLmuqYn9YdPsDQTMTkLJMhoQ8EbN7QTdy333xRQ4MYgToteQ==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/boolean-point-on-line": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/buffer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/buffer/-/buffer-6.5.0.tgz", - "integrity": "sha512-qeX4N6+PPWbKqp1AVkBVWFerGjMYMUyencwfnkCesoznU6qvfugFHNAngNqIBVnJjZ5n8IFyOf+akcxnrt9sNg==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/center": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/projection": "^6.5.0", - "d3-geo": "1.7.1", - "turf-jsts": "*" - } - }, - "@turf/center": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/center/-/center-6.5.0.tgz", - "integrity": "sha512-T8KtMTfSATWcAX088rEDKjyvQCBkUsLnK/Txb6/8WUXIeOZyHu42G7MkdkHRoHtwieLdduDdmPLFyTdG5/e7ZQ==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/center-mean": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/center-mean/-/center-mean-6.5.0.tgz", - "integrity": "sha512-AAX6f4bVn12pTVrMUiB9KrnV94BgeBKpyg3YpfnEbBpkN/znfVhL8dG8IxMAxAoSZ61Zt9WLY34HfENveuOZ7Q==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/center-median": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/center-median/-/center-median-6.5.0.tgz", - "integrity": "sha512-dT8Ndu5CiZkPrj15PBvslpuf01ky41DEYEPxS01LOxp5HOUHXp1oJxsPxvc+i/wK4BwccPNzU1vzJ0S4emd1KQ==", - "dev": true, - "requires": { - "@turf/center-mean": "^6.5.0", - "@turf/centroid": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/center-of-mass": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/center-of-mass/-/center-of-mass-6.5.0.tgz", - "integrity": "sha512-EWrriU6LraOfPN7m1jZi+1NLTKNkuIsGLZc2+Y8zbGruvUW+QV7K0nhf7iZWutlxHXTBqEXHbKue/o79IumAsQ==", - "dev": true, - "requires": { - "@turf/centroid": "^6.5.0", - "@turf/convex": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/centroid": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/centroid/-/centroid-6.5.0.tgz", - "integrity": "sha512-MwE1oq5E3isewPprEClbfU5pXljIK/GUOMbn22UM3IFPDJX0KeoyLNwghszkdmFp/qMGL/M13MMWvU+GNLXP/A==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/circle": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/circle/-/circle-6.5.0.tgz", - "integrity": "sha512-oU1+Kq9DgRnoSbWFHKnnUdTmtcRUMmHoV9DjTXu9vOLNV5OWtAAh1VZ+mzsioGGzoDNT/V5igbFOkMfBQc0B6A==", - "dev": true, - "requires": { - "@turf/destination": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/clean-coords": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/clean-coords/-/clean-coords-6.5.0.tgz", - "integrity": "sha512-EMX7gyZz0WTH/ET7xV8MyrExywfm9qUi0/MY89yNffzGIEHuFfqwhcCqZ8O00rZIPZHUTxpmsxQSTfzJJA1CPw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/clone": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-6.5.0.tgz", - "integrity": "sha512-mzVtTFj/QycXOn6ig+annKrM6ZlimreKYz6f/GSERytOpgzodbQyOgkfwru100O1KQhhjSudKK4DsQ0oyi9cTw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/clusters": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/clusters/-/clusters-6.5.0.tgz", - "integrity": "sha512-Y6gfnTJzQ1hdLfCsyd5zApNbfLIxYEpmDibHUqR5z03Lpe02pa78JtgrgUNt1seeO/aJ4TG1NLN8V5gOrHk04g==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/clusters-dbscan": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/clusters-dbscan/-/clusters-dbscan-6.5.0.tgz", - "integrity": "sha512-SxZEE4kADU9DqLRiT53QZBBhu8EP9skviSyl+FGj08Y01xfICM/RR9ACUdM0aEQimhpu+ZpRVcUK+2jtiCGrYQ==", - "dev": true, - "requires": { - "@turf/clone": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0", - "density-clustering": "1.3.0" - } - }, - "@turf/clusters-kmeans": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/clusters-kmeans/-/clusters-kmeans-6.5.0.tgz", - "integrity": "sha512-DwacD5+YO8kwDPKaXwT9DV46tMBVNsbi1IzdajZu1JDSWoN7yc7N9Qt88oi+p30583O0UPVkAK+A10WAQv4mUw==", - "dev": true, - "requires": { - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "skmeans": "0.9.7" - } - }, - "@turf/collect": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/collect/-/collect-6.5.0.tgz", - "integrity": "sha512-4dN/T6LNnRg099m97BJeOcTA5fSI8cu87Ydgfibewd2KQwBexO69AnjEFqfPX3Wj+Zvisj1uAVIZbPmSSrZkjg==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/helpers": "^6.5.0", - "rbush": "2.x" - } - }, - "@turf/combine": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/combine/-/combine-6.5.0.tgz", - "integrity": "sha512-Q8EIC4OtAcHiJB3C4R+FpB4LANiT90t17uOd851qkM2/o6m39bfN5Mv0PWqMZIHWrrosZqRqoY9dJnzz/rJxYQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/concave": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/concave/-/concave-6.5.0.tgz", - "integrity": "sha512-I/sUmUC8TC5h/E2vPwxVht+nRt+TnXIPRoztDFvS8/Y0+cBDple9inLSo9nnPXMXidrBlGXZ9vQx/BjZUJgsRQ==", - "dev": true, - "requires": { - "@turf/clone": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/tin": "^6.5.0", - "topojson-client": "3.x", - "topojson-server": "3.x" - } - }, - "@turf/convex": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/convex/-/convex-6.5.0.tgz", - "integrity": "sha512-x7ZwC5z7PJB0SBwNh7JCeCNx7Iu+QSrH7fYgK0RhhNop13TqUlvHMirMLRgf2db1DqUetrAO2qHJeIuasquUWg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0", - "concaveman": "*" - } - }, - "@turf/destination": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/destination/-/destination-6.5.0.tgz", - "integrity": "sha512-4cnWQlNC8d1tItOz9B4pmJdWpXqS0vEvv65bI/Pj/genJnsL7evI0/Xw42RvEGROS481MPiU80xzvwxEvhQiMQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/difference": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/difference/-/difference-6.5.0.tgz", - "integrity": "sha512-l8iR5uJqvI+5Fs6leNbhPY5t/a3vipUF/3AeVLpwPQcgmedNXyheYuy07PcMGH5Jdpi5gItOiTqwiU/bUH4b3A==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "polygon-clipping": "^0.15.3" - } - }, - "@turf/dissolve": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/dissolve/-/dissolve-6.5.0.tgz", - "integrity": "sha512-WBVbpm9zLTp0Bl9CE35NomTaOL1c4TQCtEoO43YaAhNEWJOOIhZMFJyr8mbvYruKl817KinT3x7aYjjCMjTAsQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "polygon-clipping": "^0.15.3" - } - }, - "@turf/distance": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-6.5.0.tgz", - "integrity": "sha512-xzykSLfoURec5qvQJcfifw/1mJa+5UwByZZ5TZ8iaqjGYN0vomhV9aiSLeYdUGtYRESZ+DYC/OzY+4RclZYgMg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/distance-weight": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/distance-weight/-/distance-weight-6.5.0.tgz", - "integrity": "sha512-a8qBKkgVNvPKBfZfEJZnC3DV7dfIsC3UIdpRci/iap/wZLH41EmS90nM+BokAJflUHYy8PqE44wySGWHN1FXrQ==", - "dev": true, - "requires": { - "@turf/centroid": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/ellipse": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/ellipse/-/ellipse-6.5.0.tgz", - "integrity": "sha512-kuXtwFviw/JqnyJXF1mrR/cb496zDTSbGKtSiolWMNImYzGGkbsAsFTjwJYgD7+4FixHjp0uQPzo70KDf3AIBw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/rhumb-destination": "^6.5.0", - "@turf/transform-rotate": "^6.5.0" - } - }, - "@turf/envelope": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/envelope/-/envelope-6.5.0.tgz", - "integrity": "sha512-9Z+FnBWvOGOU4X+fMZxYFs1HjFlkKqsddLuMknRaqcJd6t+NIv5DWvPtDL8ATD2GEExYDiFLwMdckfr1yqJgHA==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/bbox-polygon": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/explode": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/explode/-/explode-6.5.0.tgz", - "integrity": "sha512-6cSvMrnHm2qAsace6pw9cDmK2buAlw8+tjeJVXMfMyY+w7ZUi1rprWMsY92J7s2Dar63Bv09n56/1V7+tcj52Q==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/flatten": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/flatten/-/flatten-6.5.0.tgz", - "integrity": "sha512-IBZVwoNLVNT6U/bcUUllubgElzpMsNoCw8tLqBw6dfYg9ObGmpEjf9BIYLr7a2Yn5ZR4l7YIj2T7kD5uJjZADQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/flip": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/flip/-/flip-6.5.0.tgz", - "integrity": "sha512-oyikJFNjt2LmIXQqgOGLvt70RgE2lyzPMloYWM7OR5oIFGRiBvqVD2hA6MNw6JewIm30fWZ8DQJw1NHXJTJPbg==", - "dev": true, - "requires": { - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/great-circle": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/great-circle/-/great-circle-6.5.0.tgz", - "integrity": "sha512-7ovyi3HaKOXdFyN7yy1yOMa8IyOvV46RC1QOQTT+RYUN8ke10eyqExwBpL9RFUPvlpoTzoYbM/+lWPogQlFncg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/helpers": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", - "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", - "dev": true - }, - "@turf/hex-grid": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/hex-grid/-/hex-grid-6.5.0.tgz", - "integrity": "sha512-Ln3tc2tgZT8etDOldgc6e741Smg1CsMKAz1/Mlel+MEL5Ynv2mhx3m0q4J9IB1F3a4MNjDeVvm8drAaf9SF33g==", - "dev": true, - "requires": { - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/intersect": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/interpolate": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/interpolate/-/interpolate-6.5.0.tgz", - "integrity": "sha512-LSH5fMeiGyuDZ4WrDJNgh81d2DnNDUVJtuFryJFup8PV8jbs46lQGfI3r1DJ2p1IlEJIz3pmAZYeTfMMoeeohw==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/centroid": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/hex-grid": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/point-grid": "^6.5.0", - "@turf/square-grid": "^6.5.0", - "@turf/triangle-grid": "^6.5.0" - } - }, - "@turf/intersect": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/intersect/-/intersect-6.5.0.tgz", - "integrity": "sha512-2legGJeKrfFkzntcd4GouPugoqPUjexPZnOvfez+3SfIMrHvulw8qV8u7pfVyn2Yqs53yoVCEjS5sEpvQ5YRQg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "polygon-clipping": "^0.15.3" - } - }, - "@turf/invariant": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", - "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/isobands": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/isobands/-/isobands-6.5.0.tgz", - "integrity": "sha512-4h6sjBPhRwMVuFaVBv70YB7eGz+iw0bhPRnp+8JBdX1UPJSXhoi/ZF2rACemRUr0HkdVB/a1r9gC32vn5IAEkw==", - "dev": true, - "requires": { - "@turf/area": "^6.5.0", - "@turf/bbox": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/explode": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "object-assign": "*" - } - }, - "@turf/isolines": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/isolines/-/isolines-6.5.0.tgz", - "integrity": "sha512-6ElhiLCopxWlv4tPoxiCzASWt/jMRvmp6mRYrpzOm3EUl75OhHKa/Pu6Y9nWtCMmVC/RcWtiiweUocbPLZLm0A==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "object-assign": "*" - } - }, - "@turf/kinks": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/kinks/-/kinks-6.5.0.tgz", - "integrity": "sha512-ViCngdPt1eEL7hYUHR2eHR662GvCgTc35ZJFaNR6kRtr6D8plLaDju0FILeFFWSc+o8e3fwxZEJKmFj9IzPiIQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/length": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/length/-/length-6.5.0.tgz", - "integrity": "sha512-5pL5/pnw52fck3oRsHDcSGrj9HibvtlrZ0QNy2OcW8qBFDNgZ4jtl6U7eATVoyWPKBHszW3dWETW+iLV7UARig==", - "dev": true, - "requires": { - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/line-arc": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-arc/-/line-arc-6.5.0.tgz", - "integrity": "sha512-I6c+V6mIyEwbtg9P9zSFF89T7QPe1DPTG3MJJ6Cm1MrAY0MdejwQKOpsvNl8LDU2ekHOlz2kHpPVR7VJsoMllA==", - "dev": true, - "requires": { - "@turf/circle": "^6.5.0", - "@turf/destination": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/line-chunk": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-chunk/-/line-chunk-6.5.0.tgz", - "integrity": "sha512-i1FGE6YJaaYa+IJesTfyRRQZP31QouS+wh/pa6O3CC0q4T7LtHigyBSYjrbjSLfn2EVPYGlPCMFEqNWCOkC6zg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/length": "^6.5.0", - "@turf/line-slice-along": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/line-intersect": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-intersect/-/line-intersect-6.5.0.tgz", - "integrity": "sha512-CS6R1tZvVQD390G9Ea4pmpM6mJGPWoL82jD46y0q1KSor9s6HupMIo1kY4Ny+AEYQl9jd21V3Scz20eldpbTVA==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/line-segment": "^6.5.0", - "@turf/meta": "^6.5.0", - "geojson-rbush": "3.x" - } - }, - "@turf/line-offset": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-offset/-/line-offset-6.5.0.tgz", - "integrity": "sha512-CEXZbKgyz8r72qRvPchK0dxqsq8IQBdH275FE6o4MrBkzMcoZsfSjghtXzKaz9vvro+HfIXal0sTk2mqV1lQTw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/line-overlap": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-overlap/-/line-overlap-6.5.0.tgz", - "integrity": "sha512-xHOaWLd0hkaC/1OLcStCpfq55lPHpPNadZySDXYiYjEz5HXr1oKmtMYpn0wGizsLwrOixRdEp+j7bL8dPt4ojQ==", - "dev": true, - "requires": { - "@turf/boolean-point-on-line": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/line-segment": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/nearest-point-on-line": "^6.5.0", - "deep-equal": "1.x", - "geojson-rbush": "3.x" - } - }, - "@turf/line-segment": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-segment/-/line-segment-6.5.0.tgz", - "integrity": "sha512-jI625Ho4jSuJESNq66Mmi290ZJ5pPZiQZruPVpmHkUw257Pew0alMmb6YrqYNnLUuiVVONxAAKXUVeeUGtycfw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/line-slice": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-slice/-/line-slice-6.5.0.tgz", - "integrity": "sha512-vDqJxve9tBHhOaVVFXqVjF5qDzGtKWviyjbyi2QnSnxyFAmLlLnBfMX8TLQCAf2GxHibB95RO5FBE6I2KVPRuw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/nearest-point-on-line": "^6.5.0" - } - }, - "@turf/line-slice-along": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-slice-along/-/line-slice-along-6.5.0.tgz", - "integrity": "sha512-KHJRU6KpHrAj+BTgTNqby6VCTnDzG6a1sJx/I3hNvqMBLvWVA2IrkR9L9DtsQsVY63IBwVdQDqiwCuZLDQh4Ng==", - "dev": true, - "requires": { - "@turf/bearing": "^6.5.0", - "@turf/destination": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/line-split": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-split/-/line-split-6.5.0.tgz", - "integrity": "sha512-/rwUMVr9OI2ccJjw7/6eTN53URtGThNSD5I0GgxyFXMtxWiloRJ9MTff8jBbtPWrRka/Sh2GkwucVRAEakx9Sw==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/line-intersect": "^6.5.0", - "@turf/line-segment": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/nearest-point-on-line": "^6.5.0", - "@turf/square": "^6.5.0", - "@turf/truncate": "^6.5.0", - "geojson-rbush": "3.x" - } - }, - "@turf/line-to-polygon": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/line-to-polygon/-/line-to-polygon-6.5.0.tgz", - "integrity": "sha512-qYBuRCJJL8Gx27OwCD1TMijM/9XjRgXH/m/TyuND4OXedBpIWlK5VbTIO2gJ8OCfznBBddpjiObLBrkuxTpN4Q==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/mask": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/mask/-/mask-6.5.0.tgz", - "integrity": "sha512-RQha4aU8LpBrmrkH8CPaaoAfk0Egj5OuXtv6HuCQnHeGNOQt3TQVibTA3Sh4iduq4EPxnZfDjgsOeKtrCA19lg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "polygon-clipping": "^0.15.3" - } - }, - "@turf/meta": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-6.5.0.tgz", - "integrity": "sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/midpoint": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/midpoint/-/midpoint-6.5.0.tgz", - "integrity": "sha512-MyTzV44IwmVI6ec9fB2OgZ53JGNlgOpaYl9ArKoF49rXpL84F9rNATndbe0+MQIhdkw8IlzA6xVP4lZzfMNVCw==", - "dev": true, - "requires": { - "@turf/bearing": "^6.5.0", - "@turf/destination": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/moran-index": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/moran-index/-/moran-index-6.5.0.tgz", - "integrity": "sha512-ItsnhrU2XYtTtTudrM8so4afBCYWNaB0Mfy28NZwLjB5jWuAsvyV+YW+J88+neK/ougKMTawkmjQqodNJaBeLQ==", - "dev": true, - "requires": { - "@turf/distance-weight": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/nearest-point": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/nearest-point/-/nearest-point-6.5.0.tgz", - "integrity": "sha512-fguV09QxilZv/p94s8SMsXILIAMiaXI5PATq9d7YWijLxWUj6Q/r43kxyoi78Zmwwh1Zfqz9w+bCYUAxZ5+euA==", - "dev": true, - "requires": { - "@turf/clone": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/nearest-point-on-line": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/nearest-point-on-line/-/nearest-point-on-line-6.5.0.tgz", - "integrity": "sha512-WthrvddddvmymnC+Vf7BrkHGbDOUu6Z3/6bFYUGv1kxw8tiZ6n83/VG6kHz4poHOfS0RaNflzXSkmCi64fLBlg==", - "dev": true, - "requires": { - "@turf/bearing": "^6.5.0", - "@turf/destination": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/line-intersect": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/nearest-point-to-line": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/nearest-point-to-line/-/nearest-point-to-line-6.5.0.tgz", - "integrity": "sha512-PXV7cN0BVzUZdjj6oeb/ESnzXSfWmEMrsfZSDRgqyZ9ytdiIj/eRsnOXLR13LkTdXVOJYDBuf7xt1mLhM4p6+Q==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/point-to-line-distance": "^6.5.0", - "object-assign": "*" - } - }, - "@turf/planepoint": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/planepoint/-/planepoint-6.5.0.tgz", - "integrity": "sha512-R3AahA6DUvtFbka1kcJHqZ7DMHmPXDEQpbU5WaglNn7NaCQg9HB0XM0ZfqWcd5u92YXV+Gg8QhC8x5XojfcM4Q==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/point-grid": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/point-grid/-/point-grid-6.5.0.tgz", - "integrity": "sha512-Iq38lFokNNtQJnOj/RBKmyt6dlof0yhaHEDELaWHuECm1lIZLY3ZbVMwbs+nXkwTAHjKfS/OtMheUBkw+ee49w==", - "dev": true, - "requires": { - "@turf/boolean-within": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/point-on-feature": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/point-on-feature/-/point-on-feature-6.5.0.tgz", - "integrity": "sha512-bDpuIlvugJhfcF/0awAQ+QI6Om1Y1FFYE8Y/YdxGRongivix850dTeXCo0mDylFdWFPGDo7Mmh9Vo4VxNwW/TA==", - "dev": true, - "requires": { - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/center": "^6.5.0", - "@turf/explode": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/nearest-point": "^6.5.0" - } - }, - "@turf/point-to-line-distance": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/point-to-line-distance/-/point-to-line-distance-6.5.0.tgz", - "integrity": "sha512-opHVQ4vjUhNBly1bob6RWy+F+hsZDH9SA0UW36pIRzfpu27qipU18xup0XXEePfY6+wvhF6yL/WgCO2IbrLqEA==", - "dev": true, - "requires": { - "@turf/bearing": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/projection": "^6.5.0", - "@turf/rhumb-bearing": "^6.5.0", - "@turf/rhumb-distance": "^6.5.0" - } - }, - "@turf/points-within-polygon": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/points-within-polygon/-/points-within-polygon-6.5.0.tgz", - "integrity": "sha512-YyuheKqjliDsBDt3Ho73QVZk1VXX1+zIA2gwWvuz8bR1HXOkcuwk/1J76HuFMOQI3WK78wyAi+xbkx268PkQzQ==", - "dev": true, - "requires": { - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/polygon-smooth": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/polygon-smooth/-/polygon-smooth-6.5.0.tgz", - "integrity": "sha512-LO/X/5hfh/Rk4EfkDBpLlVwt3i6IXdtQccDT9rMjXEP32tRgy0VMFmdkNaXoGlSSKf/1mGqLl4y4wHd86DqKbg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/polygon-tangents": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/polygon-tangents/-/polygon-tangents-6.5.0.tgz", - "integrity": "sha512-sB4/IUqJMYRQH9jVBwqS/XDitkEfbyqRy+EH/cMRJURTg78eHunvJ708x5r6umXsbiUyQU4eqgPzEylWEQiunw==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/boolean-within": "^6.5.0", - "@turf/explode": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/nearest-point": "^6.5.0" - } - }, - "@turf/polygon-to-line": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/polygon-to-line/-/polygon-to-line-6.5.0.tgz", - "integrity": "sha512-5p4n/ij97EIttAq+ewSnKt0ruvuM+LIDzuczSzuHTpq4oS7Oq8yqg5TQ4nzMVuK41r/tALCk7nAoBuw3Su4Gcw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/polygonize": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/polygonize/-/polygonize-6.5.0.tgz", - "integrity": "sha512-a/3GzHRaCyzg7tVYHo43QUChCspa99oK4yPqooVIwTC61npFzdrmnywMv0S+WZjHZwK37BrFJGFrZGf6ocmY5w==", - "dev": true, - "requires": { - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/envelope": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/projection": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/projection/-/projection-6.5.0.tgz", - "integrity": "sha512-/Pgh9mDvQWWu8HRxqpM+tKz8OzgauV+DiOcr3FCjD6ubDnrrmMJlsf6fFJmggw93mtVPrZRL6yyi9aYCQBOIvg==", - "dev": true, - "requires": { - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/random": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/random/-/random-6.5.0.tgz", - "integrity": "sha512-8Q25gQ/XbA7HJAe+eXp4UhcXM9aOOJFaxZ02+XSNwMvY8gtWSCBLVqRcW4OhqilgZ8PeuQDWgBxeo+BIqqFWFQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/rectangle-grid": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/rectangle-grid/-/rectangle-grid-6.5.0.tgz", - "integrity": "sha512-yQZ/1vbW68O2KsSB3OZYK+72aWz/Adnf7m2CMKcC+aq6TwjxZjAvlbCOsNUnMAuldRUVN1ph6RXMG4e9KEvKvg==", - "dev": true, - "requires": { - "@turf/boolean-intersects": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/rewind": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-6.5.0.tgz", - "integrity": "sha512-IoUAMcHWotBWYwSYuYypw/LlqZmO+wcBpn8ysrBNbazkFNkLf3btSDZMkKJO/bvOzl55imr/Xj4fi3DdsLsbzQ==", - "dev": true, - "requires": { - "@turf/boolean-clockwise": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/rhumb-bearing": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/rhumb-bearing/-/rhumb-bearing-6.5.0.tgz", - "integrity": "sha512-jMyqiMRK4hzREjQmnLXmkJ+VTNTx1ii8vuqRwJPcTlKbNWfjDz/5JqJlb5NaFDcdMpftWovkW5GevfnuzHnOYA==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/rhumb-destination": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/rhumb-destination/-/rhumb-destination-6.5.0.tgz", - "integrity": "sha512-RHNP1Oy+7xTTdRrTt375jOZeHceFbjwohPHlr9Hf68VdHHPMAWgAKqiX2YgSWDcvECVmiGaBKWus1Df+N7eE4Q==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/rhumb-distance": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/rhumb-distance/-/rhumb-distance-6.5.0.tgz", - "integrity": "sha512-oKp8KFE8E4huC2Z1a1KNcFwjVOqa99isxNOwfo4g3SUABQ6NezjKDDrnvC4yI5YZ3/huDjULLBvhed45xdCrzg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - } - }, - "@turf/sample": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/sample/-/sample-6.5.0.tgz", - "integrity": "sha512-kSdCwY7el15xQjnXYW520heKUrHwRvnzx8ka4eYxX9NFeOxaFITLW2G7UtXb6LJK8mmPXI8Aexv23F2ERqzGFg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/sector": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/sector/-/sector-6.5.0.tgz", - "integrity": "sha512-cYUOkgCTWqa23SOJBqxoFAc/yGCUsPRdn/ovbRTn1zNTm/Spmk6hVB84LCKOgHqvSF25i0d2kWqpZDzLDdAPbw==", - "dev": true, - "requires": { - "@turf/circle": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/line-arc": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/shortest-path": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/shortest-path/-/shortest-path-6.5.0.tgz", - "integrity": "sha512-4de5+G7+P4hgSoPwn+SO9QSi9HY5NEV/xRJ+cmoFVRwv2CDsuOPDheHKeuIAhKyeKDvPvPt04XYWbac4insJMg==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/bbox-polygon": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/clean-coords": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/transform-scale": "^6.5.0" - } - }, - "@turf/simplify": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/simplify/-/simplify-6.5.0.tgz", - "integrity": "sha512-USas3QqffPHUY184dwQdP8qsvcVH/PWBYdXY5am7YTBACaQOMAlf6AKJs9FT8jiO6fQpxfgxuEtwmox+pBtlOg==", - "dev": true, - "requires": { - "@turf/clean-coords": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/square": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/square/-/square-6.5.0.tgz", - "integrity": "sha512-BM2UyWDmiuHCadVhHXKIx5CQQbNCpOxB6S/aCNOCLbhCeypKX5Q0Aosc5YcmCJgkwO5BERCC6Ee7NMbNB2vHmQ==", - "dev": true, - "requires": { - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0" - } - }, - "@turf/square-grid": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/square-grid/-/square-grid-6.5.0.tgz", - "integrity": "sha512-mlR0ayUdA+L4c9h7p4k3pX6gPWHNGuZkt2c5II1TJRmhLkW2557d6b/Vjfd1z9OVaajb1HinIs1FMSAPXuuUrA==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/rectangle-grid": "^6.5.0" - } - }, - "@turf/standard-deviational-ellipse": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/standard-deviational-ellipse/-/standard-deviational-ellipse-6.5.0.tgz", - "integrity": "sha512-02CAlz8POvGPFK2BKK8uHGUk/LXb0MK459JVjKxLC2yJYieOBTqEbjP0qaWhiBhGzIxSMaqe8WxZ0KvqdnstHA==", - "dev": true, - "requires": { - "@turf/center-mean": "^6.5.0", - "@turf/ellipse": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/points-within-polygon": "^6.5.0" - } - }, - "@turf/tag": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/tag/-/tag-6.5.0.tgz", - "integrity": "sha512-XwlBvrOV38CQsrNfrxvBaAPBQgXMljeU0DV8ExOyGM7/hvuGHJw3y8kKnQ4lmEQcmcrycjDQhP7JqoRv8vFssg==", - "dev": true, - "requires": { - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/tesselate": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/tesselate/-/tesselate-6.5.0.tgz", - "integrity": "sha512-M1HXuyZFCfEIIKkglh/r5L9H3c5QTEsnMBoZOFQiRnGPGmJWcaBissGb7mTFX2+DKE7FNWXh4TDnZlaLABB0dQ==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "earcut": "^2.0.0" - } - }, - "@turf/tin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/tin/-/tin-6.5.0.tgz", - "integrity": "sha512-YLYikRzKisfwj7+F+Tmyy/LE3d2H7D4kajajIfc9mlik2+esG7IolsX/+oUz1biguDYsG0DUA8kVYXDkobukfg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0" - } - }, - "@turf/transform-rotate": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/transform-rotate/-/transform-rotate-6.5.0.tgz", - "integrity": "sha512-A2Ip1v4246ZmpssxpcL0hhiVBEf4L8lGnSPWTgSv5bWBEoya2fa/0SnFX9xJgP40rMP+ZzRaCN37vLHbv1Guag==", - "dev": true, - "requires": { - "@turf/centroid": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/rhumb-bearing": "^6.5.0", - "@turf/rhumb-destination": "^6.5.0", - "@turf/rhumb-distance": "^6.5.0" - } - }, - "@turf/transform-scale": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/transform-scale/-/transform-scale-6.5.0.tgz", - "integrity": "sha512-VsATGXC9rYM8qTjbQJ/P7BswKWXHdnSJ35JlV4OsZyHBMxJQHftvmZJsFbOqVtQnIQIzf2OAly6rfzVV9QLr7g==", - "dev": true, - "requires": { - "@turf/bbox": "^6.5.0", - "@turf/center": "^6.5.0", - "@turf/centroid": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/rhumb-bearing": "^6.5.0", - "@turf/rhumb-destination": "^6.5.0", - "@turf/rhumb-distance": "^6.5.0" - } - }, - "@turf/transform-translate": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/transform-translate/-/transform-translate-6.5.0.tgz", - "integrity": "sha512-NABLw5VdtJt/9vSstChp93pc6oel4qXEos56RBMsPlYB8hzNTEKYtC146XJvyF4twJeeYS8RVe1u7KhoFwEM5w==", - "dev": true, - "requires": { - "@turf/clone": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/rhumb-destination": "^6.5.0" - } - }, - "@turf/triangle-grid": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/triangle-grid/-/triangle-grid-6.5.0.tgz", - "integrity": "sha512-2jToUSAS1R1htq4TyLQYPTIsoy6wg3e3BQXjm2rANzw4wPQCXGOxrur1Fy9RtzwqwljlC7DF4tg0OnWr8RjmfA==", - "dev": true, - "requires": { - "@turf/distance": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/intersect": "^6.5.0" - } - }, - "@turf/truncate": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/truncate/-/truncate-6.5.0.tgz", - "integrity": "sha512-pFxg71pLk+eJj134Z9yUoRhIi8vqnnKvCYwdT4x/DQl/19RVdq1tV3yqOT3gcTQNfniteylL5qV1uTBDV5sgrg==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - } - }, - "@turf/turf": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/turf/-/turf-6.5.0.tgz", - "integrity": "sha512-ipMCPnhu59bh92MNt8+pr1VZQhHVuTMHklciQURo54heoxRzt1neNYZOBR6jdL+hNsbDGAECMuIpAutX+a3Y+w==", - "dev": true, - "requires": { - "@turf/along": "^6.5.0", - "@turf/angle": "^6.5.0", - "@turf/area": "^6.5.0", - "@turf/bbox": "^6.5.0", - "@turf/bbox-clip": "^6.5.0", - "@turf/bbox-polygon": "^6.5.0", - "@turf/bearing": "^6.5.0", - "@turf/bezier-spline": "^6.5.0", - "@turf/boolean-clockwise": "^6.5.0", - "@turf/boolean-contains": "^6.5.0", - "@turf/boolean-crosses": "^6.5.0", - "@turf/boolean-disjoint": "^6.5.0", - "@turf/boolean-equal": "^6.5.0", - "@turf/boolean-intersects": "^6.5.0", - "@turf/boolean-overlap": "^6.5.0", - "@turf/boolean-parallel": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/boolean-point-on-line": "^6.5.0", - "@turf/boolean-within": "^6.5.0", - "@turf/buffer": "^6.5.0", - "@turf/center": "^6.5.0", - "@turf/center-mean": "^6.5.0", - "@turf/center-median": "^6.5.0", - "@turf/center-of-mass": "^6.5.0", - "@turf/centroid": "^6.5.0", - "@turf/circle": "^6.5.0", - "@turf/clean-coords": "^6.5.0", - "@turf/clone": "^6.5.0", - "@turf/clusters": "^6.5.0", - "@turf/clusters-dbscan": "^6.5.0", - "@turf/clusters-kmeans": "^6.5.0", - "@turf/collect": "^6.5.0", - "@turf/combine": "^6.5.0", - "@turf/concave": "^6.5.0", - "@turf/convex": "^6.5.0", - "@turf/destination": "^6.5.0", - "@turf/difference": "^6.5.0", - "@turf/dissolve": "^6.5.0", - "@turf/distance": "^6.5.0", - "@turf/distance-weight": "^6.5.0", - "@turf/ellipse": "^6.5.0", - "@turf/envelope": "^6.5.0", - "@turf/explode": "^6.5.0", - "@turf/flatten": "^6.5.0", - "@turf/flip": "^6.5.0", - "@turf/great-circle": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/hex-grid": "^6.5.0", - "@turf/interpolate": "^6.5.0", - "@turf/intersect": "^6.5.0", - "@turf/invariant": "^6.5.0", - "@turf/isobands": "^6.5.0", - "@turf/isolines": "^6.5.0", - "@turf/kinks": "^6.5.0", - "@turf/length": "^6.5.0", - "@turf/line-arc": "^6.5.0", - "@turf/line-chunk": "^6.5.0", - "@turf/line-intersect": "^6.5.0", - "@turf/line-offset": "^6.5.0", - "@turf/line-overlap": "^6.5.0", - "@turf/line-segment": "^6.5.0", - "@turf/line-slice": "^6.5.0", - "@turf/line-slice-along": "^6.5.0", - "@turf/line-split": "^6.5.0", - "@turf/line-to-polygon": "^6.5.0", - "@turf/mask": "^6.5.0", - "@turf/meta": "^6.5.0", - "@turf/midpoint": "^6.5.0", - "@turf/moran-index": "^6.5.0", - "@turf/nearest-point": "^6.5.0", - "@turf/nearest-point-on-line": "^6.5.0", - "@turf/nearest-point-to-line": "^6.5.0", - "@turf/planepoint": "^6.5.0", - "@turf/point-grid": "^6.5.0", - "@turf/point-on-feature": "^6.5.0", - "@turf/point-to-line-distance": "^6.5.0", - "@turf/points-within-polygon": "^6.5.0", - "@turf/polygon-smooth": "^6.5.0", - "@turf/polygon-tangents": "^6.5.0", - "@turf/polygon-to-line": "^6.5.0", - "@turf/polygonize": "^6.5.0", - "@turf/projection": "^6.5.0", - "@turf/random": "^6.5.0", - "@turf/rewind": "^6.5.0", - "@turf/rhumb-bearing": "^6.5.0", - "@turf/rhumb-destination": "^6.5.0", - "@turf/rhumb-distance": "^6.5.0", - "@turf/sample": "^6.5.0", - "@turf/sector": "^6.5.0", - "@turf/shortest-path": "^6.5.0", - "@turf/simplify": "^6.5.0", - "@turf/square": "^6.5.0", - "@turf/square-grid": "^6.5.0", - "@turf/standard-deviational-ellipse": "^6.5.0", - "@turf/tag": "^6.5.0", - "@turf/tesselate": "^6.5.0", - "@turf/tin": "^6.5.0", - "@turf/transform-rotate": "^6.5.0", - "@turf/transform-scale": "^6.5.0", - "@turf/transform-translate": "^6.5.0", - "@turf/triangle-grid": "^6.5.0", - "@turf/truncate": "^6.5.0", - "@turf/union": "^6.5.0", - "@turf/unkink-polygon": "^6.5.0", - "@turf/voronoi": "^6.5.0" - } - }, - "@turf/union": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/union/-/union-6.5.0.tgz", - "integrity": "sha512-igYWCwP/f0RFHIlC2c0SKDuM/ObBaqSljI3IdV/x71805QbIvY/BYGcJdyNcgEA6cylIGl/0VSlIbpJHZ9ldhw==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "polygon-clipping": "^0.15.3" - } - }, - "@turf/unkink-polygon": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/unkink-polygon/-/unkink-polygon-6.5.0.tgz", - "integrity": "sha512-8QswkzC0UqKmN1DT6HpA9upfa1HdAA5n6bbuzHy8NJOX8oVizVAqfEPY0wqqTgboDjmBR4yyImsdPGUl3gZ8JQ==", - "dev": true, - "requires": { - "@turf/area": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0", - "rbush": "^2.0.1" - } - }, - "@turf/voronoi": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/voronoi/-/voronoi-6.5.0.tgz", - "integrity": "sha512-C/xUsywYX+7h1UyNqnydHXiun4UPjK88VDghtoRypR9cLlb7qozkiLRphQxxsCM0KxyxpVPHBVQXdAL3+Yurow==", - "dev": true, - "requires": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0", - "d3-voronoi": "1.1.2" - } - }, - "@types/formatcoords": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/formatcoords/-/formatcoords-1.1.0.tgz", - "integrity": "sha512-T20OHYACraNS/xCoBEmvtUYLc/eYjXaGGDpPFVAyuwarE9KHSGX8DVb3KNBKZ5RQz7fB7qXazZj13520eDSODw==", - "dev": true - }, - "@types/geojson": { - "version": "7946.0.10", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", - "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", - "dev": true - }, - "@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", - "dev": true - }, - "@types/leaflet": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.0.tgz", - "integrity": "sha512-7LeOSj7EloC5UcyOMo+1kc3S1UT3MjJxwqsMT1d2PTyvQz53w0Y0oSSk9nwZnOZubCmBvpSNGceucxiq+ZPEUw==", - "dev": true, - "requires": { - "@types/geojson": "*" - } - }, - "@types/node": { - "version": "18.16.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz", - "integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==", - "dev": true - }, - "@types/sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-qrhtM7M41EhH4tZQTNw2/RJkxllBx3reiJpTbgWCM2Dx0U1sZ6LwKp9lfNln9uqE26ZMKUaPEYaD4rzvOWYtZw==", - "dev": true - }, - "@types/svg-injector": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/svg-injector/-/svg-injector-0.0.29.tgz", - "integrity": "sha512-tNvoN0Xk2si6IfxQI/PqInipOuCyXkDZhCh9Vc4aFv/l1DhIBfTFbXRXYUHBAGXaUNMOCHEtg9475O9J+4NXOg==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "dev": true, - "requires": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - } - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-import-to-require": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-import-to-require/-/babel-plugin-import-to-require-1.0.0.tgz", - "integrity": "sha512-dc843CwrFivjO8AVgxcHvxl0cb7J7Ed8ZGFP8+PjH3X1CnyzYtAU1WL1349m9Wc/+oqk4ETx2+cIEO2jlp3XyQ==", - "dev": true, - "requires": { - "babel-template": "^6.26.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - } - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", - "dev": true - } - } - }, - "babelify": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz", - "integrity": "sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg==", - "dev": true, - "requires": {} - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha512-YQyoqQG3sO8iCmf8+hyVpgHHOv0/hCEFiS4zTGUwTA1HjAFX66wRcNQrVCeJq9pgESMRvUAOvSil5MJlmccuKQ==", - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "browser-pack": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", - "dev": true, - "requires": { - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "JSONStream": "^1.0.3", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" - } - }, - "browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "dev": true, - "requires": { - "resolve": "^1.17.0" - } - }, - "browserify": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.0.tgz", - "integrity": "sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==", - "dev": true, - "requires": { - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "~0.2.0", - "buffer": "~5.2.1", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.1", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^3.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.2.1", - "JSONStream": "^1.0.3", - "labeled-stream-splicer": "^2.0.0", - "mkdirp-classic": "^0.5.2", - "module-deps": "^6.2.3", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "^1.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum-object": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^3.0.0", - "stream-http": "^3.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", - "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.12.0", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - } - }, - "buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" - }, - "cached-path-relative": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", - "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caniuse-lite": { - "version": "1.0.30001481", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", - "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", - "dev": true, - "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "concaveman": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz", - "integrity": "sha512-PwZYKaM/ckQSa8peP5JpVr7IMJ4Nn/MHIaWUjP4be+KoZ7Botgs8seAZGpmaOM+UZXawcdYRao/px9ycrCihHw==", - "dev": true, - "requires": { - "point-in-polygon": "^1.1.0", - "rbush": "^3.0.1", - "robust-predicates": "^2.0.4", - "tinyqueue": "^2.0.3" - }, - "dependencies": { - "quickselect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", - "dev": true - }, - "rbush": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", - "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", - "dev": true, - "requires": { - "quickselect": "^2.0.0" - } - } - } - }, - "concurrently": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.6.0.tgz", - "integrity": "sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "date-fns": "^2.29.1", - "lodash": "^4.17.21", - "rxjs": "^7.0.0", - "shell-quote": "^1.7.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^17.3.1" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==" - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "dev": true - }, - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" - }, - "cookie-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", - "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", - "requires": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6" - } - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "dev": true - }, - "core-js-compat": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.1.tgz", - "integrity": "sha512-d690npR7MC6P0gq4npTl5n2VQeNAmUrJ90n+MHiKS7W2+xno4o3F5GDEuylSdi6EJ3VssibSGXOa1r3YXD3Mhw==", - "dev": true, - "requires": { - "browserslist": "^4.21.5" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "cp": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/cp/-/cp-0.2.0.tgz", - "integrity": "sha512-4ftCvShHjIZG/zzomHyunNpBof3sOFTTmU6s6q9DdqAL/ANqrKV3pr6Z6kVfBI4hjn59DFLImrBqn7GuuMqSZA==", - "dev": true - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "d3-array": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", - "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==", - "dev": true - }, - "d3-geo": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.7.1.tgz", - "integrity": "sha512-O4AempWAr+P5qbk2bC2FuN/sDW4z+dN2wDf9QV3bxQt4M5HfOEeXLgJ/UKQW0+o1Dj8BE+L5kiDbdWUMjsmQpw==", - "dev": true, - "requires": { - "d3-array": "1" - } - }, - "d3-voronoi": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", - "integrity": "sha512-RhGS1u2vavcO7ay7ZNAPo4xeDh/VYeGof3x5ZLJBQgYhLegxr3s5IykvWmJ94FTU6mcbtp4sloqZ54mP6R4Utw==", - "dev": true - }, - "dash-ast": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", - "dev": true - }, - "date-fns": { - "version": "2.29.3", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", - "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "dev": true - }, - "density-clustering": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/density-clustering/-/density-clustering-1.3.0.tgz", - "integrity": "sha512-icpmBubVTwLnsaor9qH/4tG5+7+f61VcqMN3V3pm9sxxSCt2Jcs0zWOgwZW9ARJYaKD3FumIgHiMOcIMRRAzFQ==", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" - }, - "deps-sort": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", - "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "shasum-object": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" - }, - "detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "dev": true, - "requires": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "earcut": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", - "requires": { - "jake": "^10.8.5" - } - }, - "electron-to-chromium": { - "version": "1.4.371", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.371.tgz", - "integrity": "sha512-jlBzY4tFcJaiUjzhRTCWAqRvTO/fWzjA3Bls0mykzGZ7zvcMP7h05W6UcgzfT9Ca1SW2xyKDOFRyI0pQeRNZGw==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "esmify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/esmify/-/esmify-2.1.1.tgz", - "integrity": "sha512-GyOVgjG7sNyYB5Mbo15Ll4aGrcXZzZ3LI22rbLOjCI7L/wYelzQpBHRZkZkqbPNZ/QIRilcaHqzgNCLcEsi1lQ==", - "dev": true, - "requires": { - "@babel/core": "^7.2.2", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", - "babel-plugin-import-to-require": "^1.0.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "^1.6.2", - "duplexer2": "^0.1.4", - "through2": "^2.0.5" - } - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "event-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", - "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", - "requires": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", - "requires": { - "accepts": "~1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", - "content-type": "~1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.1.1", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", - "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" - } - } - }, - "express-basic-auth": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/express-basic-auth/-/express-basic-auth-1.2.1.tgz", - "integrity": "sha512-L6YQ1wQ/mNjVLAmK3AG1RK6VkokA1BIY6wmiH304Xtt/cLTps40EusZsU1Uop+v9lTDPxdtzbFmdXfFO3KEnwA==", - "requires": { - "basic-auth": "^2.0.1" - } - }, - "fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true - }, - "filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "requires": { - "minimatch": "^5.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "formatcoords": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/formatcoords/-/formatcoords-1.1.3.tgz", - "integrity": "sha512-Ittg5/AsYFCOtcFGPLSmVpP56a8Ionmv4Ys69UmCAdvBnqVzvVVbkZMnjWEmXrZvnmoGQE8YI3RhnxbMQFdYSw==", - "dev": true - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "geojson-equality": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/geojson-equality/-/geojson-equality-0.1.6.tgz", - "integrity": "sha512-TqG8YbqizP3EfwP5Uw4aLu6pKkg6JQK9uq/XZ1lXQntvTHD1BBKJWhNpJ2M0ax6TuWMP3oyx6Oq7FCIfznrgpQ==", - "dev": true, - "requires": { - "deep-equal": "^1.0.0" - } - }, - "geojson-rbush": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/geojson-rbush/-/geojson-rbush-3.2.0.tgz", - "integrity": "sha512-oVltQTXolxvsz1sZnutlSuLDEcQAKYC/uXt9zDzJJ6bu0W+baTI8LZBaTup5afzibEH4N3jlq2p+a152wlBJ7w==", - "dev": true, - "requires": { - "@turf/bbox": "*", - "@turf/helpers": "6.x", - "@turf/meta": "6.x", - "@types/geojson": "7946.0.8", - "rbush": "^3.0.1" - }, - "dependencies": { - "@types/geojson": { - "version": "7946.0.8", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", - "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", - "dev": true - }, - "quickselect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", - "dev": true - }, - "rbush": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", - "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", - "dev": true, - "requires": { - "quickselect": "^2.0.0" - } - } - } - }, - "get-assigned-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - } - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", - "dev": true, - "requires": { - "source-map": "~0.5.3" - } - }, - "insert-module-globals": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", - "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", - "dev": true, - "requires": { - "acorn-node": "^1.5.2", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "JSONStream": "^1.0.3", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "undeclared-identifiers": "^1.1.2", - "xtend": "^4.0.0" - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "labeled-stream-splicer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", - "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "stream-splicer": "^2.0.0" - } - }, - "leaflet": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz", - "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==", - "dev": true - }, - "leaflet-control-mini-map": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/leaflet-control-mini-map/-/leaflet-control-mini-map-0.4.0.tgz", - "integrity": "sha512-qnetYIYFqlrAbX7MaGsAkBsuA2fg3Z4xDRlEXJN1wSrnhNsIhQUzXt7Z3vapdEzx4r7VUqWTaqHYd7eY5C6Gfw==", - "dev": true, - "requires": {} - }, - "leaflet-path-drag": { - "version": "1.8.0-beta.3", - "resolved": "https://registry.npmjs.org/leaflet-path-drag/-/leaflet-path-drag-1.8.0-beta.3.tgz", - "integrity": "sha512-kpZ6sPOKlR+m+VChIzZZ7XFH4C+VGTrAxgnM4UN5iYl7lJ00iDOxS+r717bDf/xFFHB6n2jpUp9vvzjjteMpeQ==", - "dev": true - }, - "leaflet.nauticscale": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/leaflet.nauticscale/-/leaflet.nauticscale-1.1.0.tgz", - "integrity": "sha512-kJqOVuY0bk3CjSWb1CUYsjXiM+W1K0TrlJmMjl/wVubKK2y0PZ+XxkIyD6cxVsKQGlJvLGMvrSqaYdj5LW1O1Q==", - "dev": true - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mingo": { - "version": "6.2.7", - "resolved": "https://registry.npmjs.org/mingo/-/mingo-6.2.7.tgz", - "integrity": "sha512-r+yKmrZ+6SjwGxSot+/3S8sP9+LCxWNueR6xppMx7BzV60OegjbeklWAf/UveyQi8PDW8g/mwrQSHZVY/5jBJQ==" - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "module-deps": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", - "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", - "dev": true, - "requires": { - "browser-resolve": "^2.0.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.2.0", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "JSONStream": "^1.0.3", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "morgan": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", - "requires": { - "basic-auth": "~2.0.0", - "debug": "2.6.9", - "depd": "~1.1.2", - "on-finished": "~2.3.0", - "on-headers": "~1.0.1" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", - "dev": true - }, - "nodemon": { - "version": "2.0.22", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", - "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", - "dev": true, - "requires": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, - "outpipe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", - "integrity": "sha512-BnNY/RwnDrkmQdUa9U+OfN/Y7AWmKuUPCCd+hbRclZnnANvYpO72zp/a6Q4n829hPbdqEac31XCcsvlEvb+rtA==", - "dev": true, - "requires": { - "shell-quote": "^1.4.2" - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", - "dev": true, - "requires": { - "path-platform": "~0.11.15" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "requires": { - "through": "~2.3" - } - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "point-in-polygon": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", - "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==", - "dev": true - }, - "polygon-clipping": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/polygon-clipping/-/polygon-clipping-0.15.3.tgz", - "integrity": "sha512-ho0Xx5DLkgxRx/+n4O74XyJ67DcyN3Tu9bGYKsnTukGAW6ssnuak6Mwcyb1wHy9MZc9xsUWqIoiazkZB5weECg==", - "dev": true, - "requires": { - "splaytree": "^3.1.0" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true - }, - "quickselect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-1.1.1.tgz", - "integrity": "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } - }, - "rbush": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/rbush/-/rbush-2.0.2.tgz", - "integrity": "sha512-XBOuALcTm+O/H8G90b6pzu6nX6v2zCKiFG4BJho8a+bY6AER6t8uQUZdi5bomQc0AprCWhEGa7ncAbbRap0bRA==", - "dev": true, - "requires": { - "quickselect": "^1.0.1" - } - }, - "read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - } - }, - "regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dev": true, - "requires": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - } - }, - "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "requirejs": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", - "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "robust-predicates": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", - "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==", - "dev": true - }, - "rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "save": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/save/-/save-2.9.0.tgz", - "integrity": "sha512-eg8+g8CjvehE/2C6EbLdtK1pINVD27pcJLj4M9PjWWhoeha/y5bWf4dp/0RF+OzbKTcG1bae9qi3PAqiR8CJTg==", - "requires": { - "async": "^3.2.2", - "event-stream": "^4.0.1", - "lodash.assign": "^4.2.0", - "mingo": "^6.1.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shasum-object": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", - "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", - "dev": true, - "requires": { - "fast-safe-stringify": "^2.0.7" - } - }, - "shell-quote": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", - "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", - "dev": true - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true - }, - "simple-update-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", - "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", - "dev": true, - "requires": { - "semver": "~7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, - "skmeans": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz", - "integrity": "sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg==", - "dev": true - }, - "sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", - "dev": true - }, - "splaytree": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-3.1.2.tgz", - "integrity": "sha512-4OM2BJgC5UzrhVnnJA4BkHKGtjXNzzUfpQjCO8I05xYPsfS/VuQDwjCGGMi8rYQilHEV4j8NBqTFbls/PZEE7A==", - "dev": true - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { - "through": "2" - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "stream-combiner": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", - "requires": { - "duplexer": "~0.1.1", - "through": "~2.3.4" - } - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "dev": true, - "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", - "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", - "dev": true, - "requires": { - "minimist": "^1.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "syntax-error": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", - "dev": true, - "requires": { - "acorn-node": "^1.2.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", - "dev": true, - "requires": { - "process": "~0.11.0" - } - }, - "tinyqueue": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", - "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "topojson-client": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", - "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", - "dev": true, - "requires": { - "commander": "2" - } - }, - "topojson-server": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/topojson-server/-/topojson-server-3.0.1.tgz", - "integrity": "sha512-/VS9j/ffKr2XAOjlZ9CgyyeLmgJ9dMwq6Y0YEON8O7p/tGGk+dCWnrE03zEdu7i4L7YsFZLEPZPzCvcB7lEEXw==", - "dev": true, - "requires": { - "commander": "2" - } - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "requires": { - "nopt": "~1.0.10" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true - }, - "tsconfig": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-5.0.3.tgz", - "integrity": "sha512-Cq65A3kVp6BbsUgg9DRHafaGmbMb9EhAc7fjWvudNWKjkbWrt43FnrtZt6awshH1R0ocfF2Z0uxock3lVqEgOg==", - "dev": true, - "requires": { - "any-promise": "^1.3.0", - "parse-json": "^2.2.0", - "strip-bom": "^2.0.0", - "strip-json-comments": "^2.0.0" - } - }, - "tsify": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/tsify/-/tsify-5.0.4.tgz", - "integrity": "sha512-XAZtQ5OMPsJFclkZ9xMZWkSNyMhMxEPsz3D2zu79yoKorH9j/DT4xCloJeXk5+cDhosEibu4bseMVjyPOAyLJA==", - "dev": true, - "requires": { - "convert-source-map": "^1.1.0", - "fs.realpath": "^1.0.0", - "object-assign": "^4.1.0", - "semver": "^6.1.0", - "through2": "^2.0.0", - "tsconfig": "^5.0.3" - } - }, - "tslib": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", - "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==", - "dev": true - }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, - "turf-jsts": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/turf-jsts/-/turf-jsts-1.2.3.tgz", - "integrity": "sha512-Ja03QIJlPuHt4IQ2FfGex4F4JAr8m3jpaHbFbQrgwr7s7L6U8ocrHiF3J1+wf9jzhGKxvDeaCAnGDot8OjGFyA==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true - }, - "umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "dev": true - }, - "undeclared-identifiers": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", - "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", - "dev": true, - "requires": { - "acorn-node": "^1.3.0", - "dash-ast": "^1.0.0", - "get-assigned-identifiers": "^1.2.0", - "simple-concat": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - } - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "watchify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/watchify/-/watchify-4.0.0.tgz", - "integrity": "sha512-2Z04dxwoOeNxa11qzWumBTgSAohTC0+ScuY7XMenPnH+W2lhTcpEOJP4g2EIG/SWeLadPk47x++Yh+8BqPM/lA==", - "dev": true, - "requires": { - "anymatch": "^3.1.0", - "browserify": "^17.0.0", - "chokidar": "^3.4.0", - "defined": "^1.0.0", - "outpipe": "^1.1.0", - "through2": "^4.0.2", - "xtend": "^4.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - } - } - } - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } } } diff --git a/client/package.json b/client/package.json index fcf651cc..9485a1db 100644 --- a/client/package.json +++ b/client/package.json @@ -43,6 +43,7 @@ "requirejs": "^2.3.6", "sortablejs": "^1.15.0", "tsify": "^5.0.4", + "tslib": "latest", "typescript": "^4.9.4", "watchify": "^4.0.0" } diff --git a/client/public/stylesheets/leaflet/leaflet.css b/client/public/stylesheets/leaflet/leaflet.css index 1981009f..9ade8dc4 100644 --- a/client/public/stylesheets/leaflet/leaflet.css +++ b/client/public/stylesheets/leaflet/leaflet.css @@ -60,6 +60,11 @@ padding: 0; } +.leaflet-container img.leaflet-tile { + /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */ + mix-blend-mode: plus-lighter; +} + .leaflet-container.leaflet-touch-zoom { -ms-touch-action: pan-x pan-y; touch-action: pan-x pan-y; @@ -646,7 +651,7 @@ svg.leaflet-image-layer.leaflet-interactive path { } /* Printing */ - + @media print { /* Prevent printers from removing background-images of controls. */ .leaflet-control { diff --git a/client/public/stylesheets/olympus.css b/client/public/stylesheets/olympus.css index 9c40b7f1..4a25f54c 100644 --- a/client/public/stylesheets/olympus.css +++ b/client/public/stylesheets/olympus.css @@ -2,6 +2,7 @@ @import url("atc/atc.css"); @import url("atc/unitdatatable.css"); @import url("aic/aic.css"); +@import url("other/controltips.css"); @import url("panels/connectionstatus.css"); @import url("panels/serverstatus.css"); @import url("panels/mouseinfo.css"); diff --git a/client/public/stylesheets/other/controltips.css b/client/public/stylesheets/other/controltips.css new file mode 100644 index 00000000..38d59cbc --- /dev/null +++ b/client/public/stylesheets/other/controltips.css @@ -0,0 +1,33 @@ +#control-tips-panel { + align-self: center; + display: flex; + flex-flow: column wrap; + font-size: 13px; + justify-self: flex-end; + position: absolute; + right: 10px; + row-gap: 20px; + text-align: right; + z-index: 999; +} + +#control-tips-panel > * { + align-items: center; + align-self: end; + background-color: var( --background-steel ); + border-radius: var(--border-radius-md); + color: white; + column-gap: 8px; + display:flex; + justify-items: right; + opacity: .85; + padding:5px; + width:fit-content; +} + +#control-tips-panel > * > .key { + background-color: white; + border-radius: var( --border-radius-sm ); + color: var( --background-steel ); + padding:1px 4px; +} \ No newline at end of file diff --git a/client/src/constants/constants.ts b/client/src/constants/constants.ts index 1013f6e3..f45f8279 100644 --- a/client/src/constants/constants.ts +++ b/client/src/constants/constants.ts @@ -145,6 +145,7 @@ export const IADSDensities: {[key: string]: number}= {"AAA": 0.8, "MANPADS": 0.3 export const SHOW_CONTACT_LINES = "Show unit contact lines"; export const HIDE_GROUP_MEMBERS = "Hide group members when zoomed out"; +export const SHOW_CONTROL_TIPS = "Show control tips"; export const SHOW_UNIT_LABELS = "Show unit labels"; export const SHOW_UNIT_PATHS = "Show unit paths"; export const SHOW_UNIT_TARGETS = "Show unit targets"; diff --git a/client/src/features/featureswitches.ts b/client/src/features/featureswitches.ts index a7cf1c30..bb78b64c 100644 --- a/client/src/features/featureswitches.ts +++ b/client/src/features/featureswitches.ts @@ -45,7 +45,7 @@ class FeatureSwitch { } - isEnabled() { + isEnabled():boolean { if ( this.forceState === 0 ) { return false; @@ -81,11 +81,18 @@ export class FeatureSwitches { new FeatureSwitch({ "defaultEnabled": false, - "forceState": 1, + "forceState": -1, "label": "ATC", "name": "atc" }), + new FeatureSwitch({ + "defaultEnabled": false, + "forceState": -1, + "label": "Control tips", + "name": "controlTips" + }), + new FeatureSwitch({ "defaultEnabled": false, "forceState": -1, @@ -150,4 +157,16 @@ export class FeatureSwitches { } + savePreference( featureSwitchName:string, value:boolean ) { + + const preferences = JSON.parse( localStorage.getItem( "featureSwitches" ) || "{}" ); + + if ( preferences.hasOwnProperty( featureSwitchName ) ) { + preferences[ featureSwitchName ] = value; + } + + localStorage.setItem("featureSwitches", JSON.stringify(preferences)); + + } + } \ No newline at end of file diff --git a/client/src/index.ts b/client/src/index.ts index 865cf2ef..5e584101 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -179,10 +179,12 @@ function setupEvents( indexApp:OlympusApp ) { }) ) .add( "togglePause", new ShortcutKeyboard({ + "altKey": false, "callback": () => { setPaused(!getPaused()); }, - "code": "space" + "code": "Space", + "ctrlKey": false }) ); diff --git a/client/src/indexapp.ts b/client/src/indexapp.ts index d6779b2c..5208f22a 100644 --- a/client/src/indexapp.ts +++ b/client/src/indexapp.ts @@ -10,6 +10,7 @@ import { ServerStatusPanel } from "./panels/serverstatuspanel"; import { UnitControlPanel } from "./panels/unitcontrolpanel"; import { UnitInfoPanel } from "./panels/unitinfopanel"; import { Popup } from "./popups/popup"; +import { ControlTips } from "./shortcut/controltips"; import { UnitsManager } from "./unit/unitsmanager"; export interface IIndexApp extends IOlympusApp { @@ -60,6 +61,8 @@ export class IndexApp extends OlympusApp { super.start(); + new ControlTips( "control-tips-panel", this ); + } } \ No newline at end of file diff --git a/client/src/map/map.ts b/client/src/map/map.ts index a9afafda..c5b12e84 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -12,11 +12,12 @@ import { DestinationPreviewMarker } from "./destinationpreviewmarker"; import { TemporaryUnitMarker } from "./temporaryunitmarker"; import { ClickableMiniMap } from "./clickableminimap"; import { SVGInjector } from '@tanem/svg-injector' -import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants"; +import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS, SHOW_CONTROL_TIPS } from "../constants/constants"; import { TargetMarker } from "./targetmarker"; import { CoalitionArea } from "./coalitionarea"; import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu"; import { DrawingCursor } from "./drawingcursor"; +import { OlympusApp } from "../olympusapp"; L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect); @@ -67,6 +68,8 @@ export class Map extends L.Map { #optionButtons: { [key: string]: HTMLButtonElement[] } = {} #visibilityOptions: { [key: string]: boolean } = {} + #olympusApp!:OlympusApp; + constructor(ID: string) { /* Init the leaflet map */ //@ts-ignore Needed because the boxSelect option is non-standard @@ -153,6 +156,7 @@ export class Map extends L.Map { document.addEventListener("mapVisibilityOptionsChanged", () => { this.getContainer().toggleAttribute("data-hide-labels", !this.getVisibilityOptions()[SHOW_UNIT_LABELS]); + this.getOlympusApp().getControlTips().toggle( !this.getVisibilityOptions()[SHOW_CONTROL_TIPS] ); }); /* Pan interval */ @@ -176,6 +180,10 @@ export class Map extends L.Map { this.#visibilityOptions[SHOW_UNIT_PATHS] = true; this.#visibilityOptions[SHOW_UNIT_TARGETS] = true; this.#visibilityOptions[SHOW_UNIT_LABELS] = true; + + // Manual until we use the OlympusApp approach + this.#visibilityOptions[SHOW_CONTROL_TIPS] = JSON.parse( localStorage.getItem( "featureSwitches" ) || "{}" )?.controlTips || true; + this.#mapVisibilityOptionsDropdown.setOptionsElements(Object.keys(this.#visibilityOptions).map((option: string) => { return createCheckboxOption(option, option, this.#visibilityOptions[option], (ev: any) => { this.#setVisibilityOption(option, ev); @@ -776,5 +784,26 @@ export class Map extends L.Map { this.#visibilityOptions[option] = ev.currentTarget.checked; document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged")); } + + getOlympusApp() { + return this.#olympusApp; + } + + setOlympusApp( olympusApp:OlympusApp ) { + + this.#olympusApp = olympusApp; + + + // Bit crappy until we move to a more structured set of code + + let controlTipsBoolean = this.getOlympusApp().getFeatureSwitches().getSwitch( "controlTips" )?.isEnabled(); + + controlTipsBoolean = ( typeof controlTipsBoolean === "boolean" ) ? controlTipsBoolean : true; + + this.#visibilityOptions[SHOW_CONTROL_TIPS] = controlTipsBoolean; + + document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged")); + + } } diff --git a/client/src/olympusapp.ts b/client/src/olympusapp.ts index d444cceb..30b038c3 100644 --- a/client/src/olympusapp.ts +++ b/client/src/olympusapp.ts @@ -3,6 +3,7 @@ import { FeatureSwitches } from "./features/featureswitches"; import { Map } from "./map/map"; import { MissionHandler } from "./mission/missionhandler"; import { PanelsManager } from "./panels/panelsmanager"; +import { ControlTips } from "./shortcut/controltips"; import { ShortcutManager } from "./shortcut/shortcutmanager"; import { UnitsManager } from "./unit/unitsmanager"; @@ -17,6 +18,7 @@ export interface IOlympusApp { export abstract class OlympusApp { + #controlTips: ControlTips; #featureSwitches: FeatureSwitches; #map: Map; #missionHandler: MissionHandler; @@ -27,12 +29,19 @@ export abstract class OlympusApp { constructor( config:IOlympusApp ) { + this.#controlTips = new ControlTips( "control-tips-panel", this ); this.#featureSwitches = config.featureSwitches; this.#map = config.map; this.#missionHandler = config.missionHandler; this.#unitDataTable = config.unitDataTable; this.#unitsManager = config.unitsManager; + this.getMap().setOlympusApp( this ); + + } + + getControlTips() { + return this.#controlTips; } getFeatureSwitches() { @@ -71,6 +80,7 @@ export abstract class OlympusApp { // Start the app + } } \ No newline at end of file diff --git a/client/src/panels/panel.ts b/client/src/panels/panel.ts index 47ac9c3d..8899ac7e 100644 --- a/client/src/panels/panel.ts +++ b/client/src/panels/panel.ts @@ -7,8 +7,12 @@ export abstract class Panel { #eventsManager!: PanelEventsManager; #olympusApp!: OlympusApp; - constructor(ID: string) { + constructor(ID: string, olympusApp?:OlympusApp ) { this.#element = document.getElementById(ID); + + if ( olympusApp ) { + this.setOlympusApp( olympusApp ); + } } show() { @@ -46,7 +50,7 @@ export abstract class Panel { } setOlympusApp( olympusApp:OlympusApp ) { - this.#olympusApp = olympusApp; + this.#olympusApp = olympusApp; this.#eventsManager = new PanelEventsManager( this.getOlympusApp() ); } diff --git a/client/src/plugins/helloworld/plugin.json b/client/src/plugins/helloworld/plugin.json deleted file mode 100644 index c9024809..00000000 --- a/client/src/plugins/helloworld/plugin.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "author": "J. R. Hartley", - "exportedClassName": "PluginHelloWorld", - "name": "Hello World", - "version": "1.2.3" -} \ No newline at end of file diff --git a/client/src/plugins/helloworld/pluginhelloworld.ts b/client/src/plugins/helloworld/pluginhelloworld.ts deleted file mode 100644 index f01cbb9f..00000000 --- a/client/src/plugins/helloworld/pluginhelloworld.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { OlympusApp } from "../../olympusapp"; -import { Plugin } from "../../plugin/plugin"; -import { ShortcutManager } from "../../shortcut/shortcutmanager"; - - -export class PluginHelloWorld extends Plugin { - - #element:HTMLElement; - #shortcutManager:ShortcutManager; - - constructor( olympusApp:OlympusApp ) { - - super( olympusApp, "HelloWorld" ); - - const templates = { - bar: `
` - } - - document.body.insertAdjacentHTML( "beforeend", templates.bar ); - - this.#element = document.getElementById( "shortcut-bar" ); - - this.#shortcutManager = this.getOlympusApp().getShortcutManager(); - - this.#shortcutManager.onKeyDown( () => { - this.#updateText() - }); - - this.#shortcutManager.onKeyUp( () => { - this.#updateText() - }); - - this.#updateText(); - - } - - #matches( combo:string[], heldKeys:string[] ) { - - if ( combo.length !== heldKeys.length ) { - return false; - } - - return combo.every( key => heldKeys.indexOf( key ) > -1 ); - - } - - #updateText() { - - const heldKeys = this.#shortcutManager.getKeysBeingHeld(); - - const combos:Array = [ - { - "keys": [], - "text": `[CTRL]: Pin tool | [SHIFT]: box select tool
[Mouse1+drag]: Move map | [Mouse2]: Spawn menu ` - }, - { - "keys": [ "ControlLeft" ], - "text": "Mouse1: drop pin" - }, - { - "keys": [ "ShiftLeft" ], - "text": "Mouse1+drag: select units" - } - ]; - - const currentCombo:any = combos.find( (combo:any) => this.#matches( combo.keys, heldKeys ) ); - - if ( currentCombo ) { - this.#element.innerHTML = currentCombo.text; - this.#element.classList.remove( "hide" ); - } else { - this.#element.classList.add( "hide" ); - } - - } - -} \ No newline at end of file diff --git a/client/src/shortcut/controltips.ts b/client/src/shortcut/controltips.ts new file mode 100644 index 00000000..26d93d49 --- /dev/null +++ b/client/src/shortcut/controltips.ts @@ -0,0 +1,193 @@ +import { OlympusApp } from "../olympusapp"; +import { ShortcutManager } from "../shortcut/shortcutmanager"; +import { Unit } from "../unit/unit"; + + +export class ControlTips { + + #element:HTMLElement; + #cursorIsHoveringOverUnit:boolean = false; + #olympusApp:OlympusApp; + #shortcutManager:ShortcutManager; + + constructor( ID:string, olympusApp:OlympusApp ) { + + this.#element = document.getElementById( ID ); + + this.#olympusApp = olympusApp; + + this.#shortcutManager = this.#olympusApp.getShortcutManager(); + + this.#shortcutManager.onKeyDown( () => { + this.#updateTips() + }); + + this.#shortcutManager.onKeyUp( () => { + this.#updateTips() + }); + + document.addEventListener( "unitDeselection", ( ev:CustomEvent ) => { + this.#updateTips(); + }); + + document.addEventListener( "unitMouseover", ( ev:CustomEventInit ) => { + this.#cursorIsHoveringOverUnit = true; + this.#updateTips(); + }); + + document.addEventListener( "unitMouseout", ( ev:CustomEventInit ) => { + this.#cursorIsHoveringOverUnit = false; + this.#updateTips(); + }); + + document.addEventListener( "unitSelection", ( ev:CustomEvent ) => { + this.#updateTips() + }); + + this.#updateTips(); + + } + + getElement() { + return this.#element; + } + + #getOlympusApp() { + return this.#olympusApp; + } + + toggle( bool?:boolean ) { + this.getElement().classList.toggle( "hide", bool ); + this.#olympusApp.getFeatureSwitches().savePreference( "controlTips", !this.getElement().classList.contains( "hide" ) ); + } + + #updateTips() { + + const combos:Array = [ + { + "keys": [], + "tips": [ + { + "key": `W/A/S/D`, + "action": `Pan map`, + "showIfUnitSelected": false + }, + { + "key": `SHIFT`, + "action": `Box select`, + "showIfUnitSelected": false + }, + { + "key": `Mouse1`, + "action": `Deselect`, + "showIfUnitSelected": true + }, + { + "key": `Mouse1+drag`, + "action": `Move map`, + "showIfUnitSelected": false + }, + { + "key": `Mouse2`, + "action": `Spawn menu`, + "showIfUnitSelected": false + }, + { + "key": `Mouse2`, + "action": `Set first waypoint`, + "showIfUnitSelected": true, + "unitsMustBeControlled": true + }, + { + "key": `Delete`, + "action": `Delete unit`, + "showIfUnitSelected": true + }, + { + "key": "CTRL", + "action": " (more...)" + } + ] + }, + { + "keys": [ "ControlLeft" ], + "tips": [ + { + "key": `Mouse1`, + "action": "Toggle pin", + "showIfUnitSelected": false, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse1`, + "action": "Toggle selection", + "showIfUnitSelected": true, + "showIfHoveringOverUnit": true + }, + { + "key": `Mouse2`, + "action": `Add waypoint`, + "showIfUnitSelected": true + } + ] + }, + { + "keys": [ "ShiftLeft" ], + "tips": [ + { + "key": `mouse1+drag`, + "action": "Box select" + } + ] + } + ]; + + const currentCombo:any = combos.find( (combo:any) => this.#shortcutManager.keyComboMatches( combo.keys ) ) || combos[0]; + + const element = this.getElement(); + + element.innerHTML = ""; + + const a = this.#getOlympusApp(); + + let numSelectedUnits = 0; + let unitSelectionContainsControlled = false; + + if ( this.#getOlympusApp().getUnitsManager() ) { + let selectedUnits = Object.values( this.#getOlympusApp().getUnitsManager().getSelectedUnits() ); + numSelectedUnits = selectedUnits.length; + unitSelectionContainsControlled = selectedUnits.some( (unit:Unit) => unit.getControlled() ); + } + + + currentCombo.tips.forEach( ( tip:any ) => { + + if ( numSelectedUnits > 0 ) { + if ( tip.showIfUnitSelected === false ) { + return; + } + + if ( tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false ) { + return; + } + } + + if ( numSelectedUnits === 0 && tip.showIfUnitSelected === true ) { + return; + } + + // console.log( tip.action, "state:", this.#cursorIsHoveringOverUnit, "typeof", typeof tip.showIfHoveringOverUnit, "logic", tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit ); + + if ( typeof tip.showIfHoveringOverUnit === "boolean" && tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit ) { + return; + } + + element.innerHTML += `
${tip.key}${tip.action}
` + + }); + + // console.log( "----" ); + + } + +} \ No newline at end of file diff --git a/client/src/shortcut/shortcutmanager.ts b/client/src/shortcut/shortcutmanager.ts index 9e20f5b4..54e6386a 100644 --- a/client/src/shortcut/shortcutmanager.ts +++ b/client/src/shortcut/shortcutmanager.ts @@ -35,6 +35,18 @@ export class ShortcutManager extends Manager { return this.#keysBeingHeld; } + keyComboMatches( combo:string[] ) { + + const heldKeys = this.getKeysBeingHeld(); + + if ( combo.length !== heldKeys.length ) { + return false; + } + + return combo.every( key => heldKeys.indexOf( key ) > -1 ); + + } + onKeyDown( callback:CallableFunction ) { this.#keyDownCallbacks.push( callback ); } diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index 4de688ce..f6575f42 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -154,8 +154,16 @@ export class Unit extends CustomMarker { this.on('click', (e) => this.#onClick(e)); this.on('dblclick', (e) => this.#onDoubleClick(e)); this.on('contextmenu', (e) => this.#onContextMenu(e)); - this.on('mouseover', () => { if (this.belongsToCommandedCoalition()) this.setHighlighted(true); }) - this.on('mouseout', () => { this.setHighlighted(false); }) + this.on('mouseover', () => { + if (this.belongsToCommandedCoalition()) { + this.setHighlighted(true); + document.dispatchEvent(new CustomEvent("unitMouseover", { detail: this })); + } + }); + this.on('mouseout', () => { + this.setHighlighted(false); + document.dispatchEvent(new CustomEvent("unitMouseout", { detail: this })); + }); getMap().on("zoomend", () => { this.#onZoom(); }) /* Deselect units if they are hidden */ @@ -329,11 +337,9 @@ export class Unit extends CustomMarker { this.#selected = selected; if (selected) { - document.dispatchEvent(new CustomEvent("unitSelection", { detail: this })); this.#updateMarker(); } else { - document.dispatchEvent(new CustomEvent("unitDeselection", { detail: this })); this.#clearContacts(); this.#clearPath(); this.#clearTarget(); @@ -347,6 +353,13 @@ export class Unit extends CustomMarker { this.#updateMarker(); } + // Trigger events after all (de-)selecting has been done + if (selected) { + document.dispatchEvent(new CustomEvent("unitSelection", { detail: this })); + } else { + document.dispatchEvent(new CustomEvent("unitDeselection", { detail: this })); + } + } } diff --git a/client/views/index.ejs b/client/views/index.ejs index 2d8bbe35..0459857e 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -20,6 +20,8 @@ <%- include('atc/atc.ejs') %> <%- include('atc/unitdatatable.ejs') %> + <%- include('other/controltips.ejs') %> + <%- include('panels/unitcontrol.ejs') %> <%- include('panels/unitinfo.ejs') %> <%- include('panels/mouseinfo.ejs') %> diff --git a/client/views/other/controltips.ejs b/client/views/other/controltips.ejs new file mode 100644 index 00000000..463b5c1d --- /dev/null +++ b/client/views/other/controltips.ejs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/client/views/toolbars/primary.ejs b/client/views/toolbars/primary.ejs index a66879e3..16641782 100644 --- a/client/views/toolbars/primary.ejs +++ b/client/views/toolbars/primary.ejs @@ -63,7 +63,6 @@ - + \ No newline at end of file From 01b30ccf1241bbd4f5eb8bafc67955eb1f0678ca Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Thu, 14 Sep 2023 20:56:34 +0100 Subject: [PATCH 08/12] Refined the options a bit. --- .../public/stylesheets/other/controltips.css | 6 +- client/src/mission/airbase.ts | 6 ++ client/src/shortcut/controltips.ts | 95 +++++++++++++++---- 3 files changed, 88 insertions(+), 19 deletions(-) diff --git a/client/public/stylesheets/other/controltips.css b/client/public/stylesheets/other/controltips.css index 38d59cbc..6ed26c79 100644 --- a/client/public/stylesheets/other/controltips.css +++ b/client/public/stylesheets/other/controltips.css @@ -20,14 +20,14 @@ column-gap: 8px; display:flex; justify-items: right; - opacity: .85; + opacity: .9; padding:5px; width:fit-content; } #control-tips-panel > * > .key { - background-color: white; + background-color: var( --background-grey ); border-radius: var( --border-radius-sm ); - color: var( --background-steel ); + color: white; padding:1px 4px; } \ No newline at end of file diff --git a/client/src/mission/airbase.ts b/client/src/mission/airbase.ts index 0534803e..6e85a997 100644 --- a/client/src/mission/airbase.ts +++ b/client/src/mission/airbase.ts @@ -66,6 +66,12 @@ export class Airbase extends CustomMarker { img.onload = () => SVGInjector(img); el.appendChild(img); this.getElement()?.appendChild(el); + el.addEventListener( "mouseover", ( ev ) => { + document.dispatchEvent( new CustomEvent( "airbaseMouseover", { detail: this })); + }); + el.addEventListener( "mouseout", ( ev ) => { + document.dispatchEvent( new CustomEvent( "airbaseMouseout", { detail: this })); + }); el.dataset.coalition = this.#coalition; } diff --git a/client/src/shortcut/controltips.ts b/client/src/shortcut/controltips.ts index 26d93d49..25cff7bf 100644 --- a/client/src/shortcut/controltips.ts +++ b/client/src/shortcut/controltips.ts @@ -7,6 +7,7 @@ export class ControlTips { #element:HTMLElement; #cursorIsHoveringOverUnit:boolean = false; + #cursorIsHoveringOverAirbase:boolean = false; #olympusApp:OlympusApp; #shortcutManager:ShortcutManager; @@ -26,6 +27,16 @@ export class ControlTips { this.#updateTips() }); + document.addEventListener( "airbaseMouseover", ( ev:CustomEventInit ) => { + this.#cursorIsHoveringOverAirbase = true; + this.#updateTips(); + }); + + document.addEventListener( "airbaseMouseout", ( ev:CustomEventInit ) => { + this.#cursorIsHoveringOverAirbase = false; + this.#updateTips(); + }); + document.addEventListener( "unitDeselection", ( ev:CustomEvent ) => { this.#updateTips(); }); @@ -67,14 +78,11 @@ export class ControlTips { { "keys": [], "tips": [ - { - "key": `W/A/S/D`, - "action": `Pan map`, - "showIfUnitSelected": false - }, { "key": `SHIFT`, "action": `Box select`, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, "showIfUnitSelected": false }, { @@ -85,27 +93,73 @@ export class ControlTips { { "key": `Mouse1+drag`, "action": `Move map`, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, "showIfUnitSelected": false }, { "key": `Mouse2`, "action": `Spawn menu`, - "showIfUnitSelected": false + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse2`, + "action": `Quick options`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": true + }, + { + "key": `Mouse2`, + "action": `Airbase menu`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": true, + "showIfHoveringOverUnit": false }, { "key": `Mouse2`, "action": `Set first waypoint`, + "showIfHoveringOverAirbase": false, "showIfUnitSelected": true, "unitsMustBeControlled": true }, + { + "key": "CTRL+Mouse2", + "action": "Add waypoint", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "unitsMustBeControlled": true + }, + { + "key": `Mouse2 (hold)`, + "action": `Point operations`, + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "unitsMustBeControlled": true + }, + { + "key": "CTRL", + "action": " Pin tool", + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "unitsMustBeControlled": true + }, + { + "key": "CTRL+Mouse2", + "action": " Airbase menu", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": true, + "unitsMustBeControlled": true + }, { "key": `Delete`, "action": `Delete unit`, + "showIfHoveringOverAirbase": false, "showIfUnitSelected": true - }, - { - "key": "CTRL", - "action": " (more...)" } ] }, @@ -116,18 +170,22 @@ export class ControlTips { "key": `Mouse1`, "action": "Toggle pin", "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, "showIfHoveringOverUnit": false }, { "key": `Mouse1`, "action": "Toggle selection", "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, "showIfHoveringOverUnit": true }, { "key": `Mouse2`, "action": `Add waypoint`, - "showIfUnitSelected": true + "showIfHoveringOverAirbase": false, + "showIfUnitSelected": true, + "unitsMustBeControlled": true } ] }, @@ -176,17 +234,22 @@ export class ControlTips { return; } - // console.log( tip.action, "state:", this.#cursorIsHoveringOverUnit, "typeof", typeof tip.showIfHoveringOverUnit, "logic", tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit ); + if ( typeof tip.showIfHoveringOverAirbase === "boolean" ) { + if ( tip.showIfHoveringOverAirbase !== this.#cursorIsHoveringOverAirbase ) { + return; + } + } - if ( typeof tip.showIfHoveringOverUnit === "boolean" && tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit ) { - return; + if ( typeof tip.showIfHoveringOverUnit === "boolean" ) { + if ( tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit ) { + return; + } } element.innerHTML += `
${tip.key}${tip.action}
` }); - - // console.log( "----" ); + } From ad06117b78426875657518399dab51b095ca6c33 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Thu, 14 Sep 2023 21:10:52 +0100 Subject: [PATCH 09/12] Refined a bit more. --- client/src/map/map.ts | 11 ----------- client/src/shortcut/controltips.ts | 7 +++++++ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/client/src/map/map.ts b/client/src/map/map.ts index 494b9ca7..fd8745f4 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -812,17 +812,6 @@ export class Map extends L.Map { this.#olympusApp = olympusApp; - - // Bit crappy until we move to a more structured set of code - - let controlTipsBoolean = this.getOlympusApp().getFeatureSwitches().getSwitch( "controlTips" )?.isEnabled(); - - controlTipsBoolean = ( typeof controlTipsBoolean === "boolean" ) ? controlTipsBoolean : true; - - this.#visibilityOptions[SHOW_CONTROL_TIPS] = controlTipsBoolean; - - document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged")); - } } diff --git a/client/src/shortcut/controltips.ts b/client/src/shortcut/controltips.ts index 25cff7bf..a31ef77b 100644 --- a/client/src/shortcut/controltips.ts +++ b/client/src/shortcut/controltips.ts @@ -186,6 +186,13 @@ export class ControlTips { "showIfHoveringOverAirbase": false, "showIfUnitSelected": true, "unitsMustBeControlled": true + }, + { + "key": `Mouse2`, + "action": `Airbase menu`, + "showIfHoveringOverAirbase": true, + "showIfUnitSelected": true, + "unitsMustBeControlled": true } ] }, From 588228c0504e4f8ff8fbd70dba641de95bed81b3 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Fri, 15 Sep 2023 17:05:26 +0200 Subject: [PATCH 10/12] Implemented basic Plugin handling --- client/{src => }/@types/dom.d.ts | 15 +- client/@types/olympus.d.ts | 267 ++++++++++++++++++ client/app.js | 2 + client/demo.js | 2 +- client/plugins/controltips/copy.bat | 5 + client/plugins/controltips/index.js | 252 +++++++++++++++++ client/plugins/controltips/package-lock.json | 162 +++++++++++ client/plugins/controltips/package.json | 10 + client/plugins/controltips/plugin.json | 6 + .../controltips/src}/controltips.ts | 112 ++++---- client/plugins/controltips/src/index.ts | 5 + .../controltips/style.css} | 18 +- client/plugins/controltips/tsconfig.json | 104 +++++++ .../public/plugins/controltipsplugin/index.js | 252 +++++++++++++++++ .../plugins/controltipsplugin/plugin.json | 6 + .../plugins/controltipsplugin/style.css | 33 +++ client/public/stylesheets/leaflet/leaflet.css | 7 +- client/routes/api/atc.js | 229 +++++++-------- client/routes/plugins.js | 23 ++ client/routes/resources.js | 1 + client/src/@types/server.d.ts | 52 ---- client/src/@types/unit.d.ts | 104 ------- client/src/@types/unitdatabase.d.ts | 43 --- client/src/app.ts | 151 ++++++++++ client/src/constants/constants.ts | 2 +- client/src/contextmenus/airbasecontextmenu.ts | 16 +- client/src/contextmenus/airbasespawnmenu.ts | 4 +- .../contextmenus/coalitionareacontextmenu.ts | 16 +- client/src/contextmenus/mapcontextmenu.ts | 22 +- client/src/controls/unitspawnmenu.ts | 36 ++- client/src/features/featureswitches.ts | 172 ----------- client/src/features/toggleablefeature.ts | 35 --- client/src/index.ts | 252 +++-------------- client/src/indexapp.ts | 66 ----- client/src/map/coalitionarea/coalitionarea.ts | 28 +- client/src/map/map.ts | 64 ++--- client/src/map/markers/smokemarker.ts | 4 +- client/src/map/markers/temporaryunitmarker.ts | 4 +- client/src/mission/airbase.ts | 24 -- client/src/mission/missionmanager.ts | 13 +- client/src/olympusapp.ts | 70 ----- client/src/other/eventsmanager.ts | 7 +- client/src/other/manager.ts | 47 +-- client/src/other/utils.ts | 1 - client/src/panels/hotgrouppanel.ts | 12 +- client/src/panels/logpanel.ts | 7 +- client/src/panels/mouseinfopanel.ts | 40 +-- client/src/panels/panel.ts | 30 +- client/src/panels/paneleventsmanager.ts | 49 +--- client/src/panels/panelsmanager.ts | 17 -- client/src/panels/unitcontrolpanel.ts | 47 ++- client/src/panels/unitinfopanel.ts | 1 - client/src/plugin/plugin.ts | 36 --- client/src/plugin/pluginmanager.ts | 58 +++- client/src/server/dataextractor.ts | 1 - client/src/server/server.ts | 57 ++-- client/src/shortcut/shortcut.ts | 54 +--- client/src/shortcut/shortcutmanager.ts | 49 ++-- client/src/unit/databases/aircraftdatabase.ts | 4 +- .../src/unit/databases/groundunitdatabase.ts | 4 +- .../src/unit/databases/helicopterdatabase.ts | 4 +- client/src/unit/databases/navyunitdatabase.ts | 4 +- client/src/unit/databases/unitdatabase.ts | 13 +- client/src/unit/unit.ts | 132 +++++---- client/src/unit/unitsmanager.ts | 67 ++--- client/src/weapon/weapon.ts | 23 +- client/src/weapon/weaponsmanager.ts | 5 +- client/tsconfig.json | 12 +- client/views/aic/aic.ejs | 52 ---- client/views/atc/addflight.ejs | 5 - client/views/atc/atc.ejs | 11 - client/views/atc/board.ejs | 22 -- client/views/atc/unitdatatable.ejs | 13 - client/views/index.ejs | 3 - client/views/other/controltips.ejs | 1 - 75 files changed, 1920 insertions(+), 1657 deletions(-) rename client/{src => }/@types/dom.d.ts (89%) create mode 100644 client/@types/olympus.d.ts create mode 100644 client/plugins/controltips/copy.bat create mode 100644 client/plugins/controltips/index.js create mode 100644 client/plugins/controltips/package-lock.json create mode 100644 client/plugins/controltips/package.json create mode 100644 client/plugins/controltips/plugin.json rename client/{src/shortcut => plugins/controltips/src}/controltips.ts (70%) create mode 100644 client/plugins/controltips/src/index.ts rename client/{public/stylesheets/other/controltips.css => plugins/controltips/style.css} (61%) create mode 100644 client/plugins/controltips/tsconfig.json create mode 100644 client/public/plugins/controltipsplugin/index.js create mode 100644 client/public/plugins/controltipsplugin/plugin.json create mode 100644 client/public/plugins/controltipsplugin/style.css create mode 100644 client/routes/plugins.js delete mode 100644 client/src/@types/server.d.ts delete mode 100644 client/src/@types/unit.d.ts delete mode 100644 client/src/@types/unitdatabase.d.ts create mode 100644 client/src/app.ts delete mode 100644 client/src/features/featureswitches.ts delete mode 100644 client/src/features/toggleablefeature.ts delete mode 100644 client/src/indexapp.ts delete mode 100644 client/src/olympusapp.ts delete mode 100644 client/src/panels/panelsmanager.ts delete mode 100644 client/src/plugin/plugin.ts delete mode 100644 client/views/aic/aic.ejs delete mode 100644 client/views/atc/addflight.ejs delete mode 100644 client/views/atc/atc.ejs delete mode 100644 client/views/atc/board.ejs delete mode 100644 client/views/atc/unitdatatable.ejs delete mode 100644 client/views/other/controltips.ejs diff --git a/client/src/@types/dom.d.ts b/client/@types/dom.d.ts similarity index 89% rename from client/src/@types/dom.d.ts rename to client/@types/dom.d.ts index 7fea9ff0..4d8080e9 100644 --- a/client/src/@types/dom.d.ts +++ b/client/@types/dom.d.ts @@ -29,17 +29,8 @@ declare global { listener: (this: Document, ev: CustomEventMap[K]) => void): void; dispatchEvent(ev: CustomEventMap[K]): void; } + + function getOlympusPlugin(): OlympusPlugin; } -export interface ConfigParameters { - port: number; - address: string; -} - -export interface ContextMenuOption { - tooltip: string; - src: string; - callback: CallableFunction; -} - -export { }; \ No newline at end of file +export { }; diff --git a/client/@types/olympus.d.ts b/client/@types/olympus.d.ts new file mode 100644 index 00000000..d9856110 --- /dev/null +++ b/client/@types/olympus.d.ts @@ -0,0 +1,267 @@ +interface OlympusPlugin { + getName: () => string; + initialize: (any) => boolean; +} + +declare global { + function getOlympusPlugin(): OlympusPlugin; +} + +interface ConfigurationOptions { + port: number; + address: string; +} + +interface ContextMenuOption { + tooltip: string; + src: string; + callback: CallableFunction; +} + +interface AirbasesData { + airbases: { [key: string]: any }, + sessionHash: string; + time: number; +} + +interface BullseyesData { + bullseyes: { [key: string]: { latitude: number, longitude: number, coalition: string } }, + sessionHash: string; + time: number; +} + +interface MissionData { + mission: { + theatre: string, + dateAndTime: DateAndTime; + commandModeOptions: CommandModeOptions; + coalitions: { red: string[], blue: string[] } = { }; + } + time: number; + sessionHash: string; +} + +interface CommandModeOptions { + commandMode: string; + restrictSpawns: boolean; + restrictToCoalition: boolean; + setupTime: number; + spawnPoints: { + red: number, + blue: number + }, + eras: string[] +} + +interface DateAndTime { + date: { Year: number, Month: number, Day: number }; + time: { h: number, m: number, s: number }; + elapsedTime: number; + startTime: number; +} + +interface LogData { + logs: { [key: string]: string }, + sessionHash: string; + time: number; +} + +interface ServerRequestOptions { + time?: number; + commandHash?: string; +} + +interface UnitSpawnTable { + unitType: string, + location: latlng, + altitude?: number, + loadout?: string, + liveryID: string +} + +interface ObjectIconOptions { + showState: boolean, + showVvi: boolean, + showHotgroup: boolean, + showUnitIcon: boolean, + showShortLabel: boolean, + showFuel: boolean, + showAmmo: boolean, + showSummary: boolean, + showCallsign: boolean, + rotateToHeading: boolean +} + +interface GeneralSettings { + prohibitJettison: boolean; + prohibitAA: boolean; + prohibitAG: boolean; + prohibitAfterburner: boolean; + prohibitAirWpn: boolean; +} + +interface TACAN { + isOn: boolean; + channel: number; + XY: string; + callsign: string; +} + +interface Radio { + frequency: number; + callsign: number; + callsignNumber: number; +} + +interface Ammo { + quantity: number, + name: string, + guidance: number, + category: number, + missileCategory: number +} + +interface Contact { + ID: number, + detectionMethod: number +} + +interface Offset { + x: number, + y: number, + z: number +} + +interface UnitData { + category: string, + ID: number; + alive: boolean; + human: boolean; + controlled: boolean; + coalition: string; + country: number; + name: string; + unitName: string; + groupName: string; + state: string; + task: string; + hasTask: boolean; + position: LatLng; + speed: number; + heading: number; + isTanker: boolean; + isAWACS: boolean; + onOff: boolean; + followRoads: boolean; + fuel: number; + desiredSpeed: number; + desiredSpeedType: string; + desiredAltitude: number; + desiredAltitudeType: string; + leaderID: number; + formationOffset: Offset; + targetID: number; + targetPosition: LatLng; + ROE: string; + reactionToThreat: string; + emissionsCountermeasures: string; + TACAN: TACAN; + radio: Radio; + generalSettings: GeneralSettings; + ammo: Ammo[]; + contacts: Contact[]; + activePath: LatLng[]; + isLeader: boolean; +} + +interface LoadoutItemBlueprint { + name: string; + quantity: number; + effectiveAgainst?: string; +} + +interface LoadoutBlueprint { + fuel: number; + items: LoadoutItemBlueprint[]; + roles: string[]; + code: string; + name: string; +} + +interface UnitBlueprint { + name: string; + coalition: string; + era: string; + label: string; + shortLabel: string; + type?: string; + range?: string; + loadouts?: LoadoutBlueprint[]; + filename?: string; + liveries?: { [key: string]: { name: string, countries: string[] } }; + cost?: number; +} + +interface UnitSpawnOptions { + roleType: string; + name: string; + latlng: LatLng; + coalition: string; + count: number; + country: string; + loadout: LoadoutBlueprint | undefined; + airbase: Airbase | undefined; + liveryID: string | undefined; + altitude: number | undefined; +} + +interface AirbaseOptions { + name: string, + position: L.LatLng +} + +interface AirbaseChartData { + elevation: string, + ICAO: string, + TACAN: string, + runways: AirbaseChartRunwayData[] +} + +interface AirbaseChartRunwayData { + headings: AirbaseChartRunwayHeadingData[], + length: string +} + +interface AirbaseChartRunwayHeadingData { + [index: string]: { + magHeading: string, + ILS: string + } +} + +interface Listener { + callback: CallableFunction; + name?: string +} + +interface ShortcutOptions { + altKey?: boolean; + callback: CallableFunction; + ctrlKey?: boolean; + name?: string; + shiftKey?: boolean; +} + +interface KeyboardShortcutOptions extends ShortcutOptions { + code: string; + event?: "keydown" | "keyup"; +} + +interface MouseShortcutOptions extends ShortcutOptions { + button: number; + event: "mousedown" | "mouseup"; +} + +interface Manager { + add: CallableFunction; +} \ No newline at end of file diff --git a/client/app.js b/client/app.js index 651c2b73..1b2edaa9 100644 --- a/client/app.js +++ b/client/app.js @@ -10,6 +10,7 @@ var indexRouter = require('./routes/index'); var uikitRouter = require('./routes/uikit'); var usersRouter = require('./routes/users'); var resourcesRouter = require('./routes/resources'); +var pluginsRouter = require('./routes/plugins'); var app = express(); @@ -22,6 +23,7 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/api/atc', atcRouter); app.use('/api/airbases', airbasesRouter); +app.use('/plugins', pluginsRouter) app.use('/users', usersRouter); app.use('/uikit', uikitRouter); app.use('/resources', resourcesRouter); diff --git a/client/demo.js b/client/demo.js index 758754d9..99c65f9a 100644 --- a/client/demo.js +++ b/client/demo.js @@ -444,7 +444,7 @@ class DemoDataGenerator { var auth = req.get("Authorization"); if (auth) { - var username = atob(auth.replace("Basic ", "")).split(":")[0]; + var username = Buffer.from(auth.replace("Basic ", ""), 'base64').toString('binary').split(":")[0]; switch (username) { case "admin": ret.mission.commandModeOptions.commandMode = "Game master"; diff --git a/client/plugins/controltips/copy.bat b/client/plugins/controltips/copy.bat new file mode 100644 index 00000000..e0a9d89d --- /dev/null +++ b/client/plugins/controltips/copy.bat @@ -0,0 +1,5 @@ +mkdir .\\..\\..\\public\\plugins\\controltipsplugin + +copy .\\index.js .\\..\\..\\public\\plugins\\controltipsplugin\\index.js +copy .\\plugin.json .\\..\\..\\public\\plugins\\controltipsplugin\\plugin.json +copy .\\style.css .\\..\\..\\public\\plugins\\controltipsplugin\\style.css \ No newline at end of file diff --git a/client/plugins/controltips/index.js b/client/plugins/controltips/index.js new file mode 100644 index 00000000..90ee53e6 --- /dev/null +++ b/client/plugins/controltips/index.js @@ -0,0 +1,252 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i { + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").onKeyUp(() => { + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + document.addEventListener("airbaseMouseover", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, true, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + document.addEventListener("airbaseMouseout", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, false, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + //document.addEventListener("unitDeselection", (ev: CustomEvent) => { + // this.#updateTips(); + //}); + document.addEventListener("unitMouseover", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, true, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + document.addEventListener("unitMouseout", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, false, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + //document.addEventListener("unitSelection", (ev: CustomEvent) => { + // this.#updateTips() + //}); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + return true; + } + getElement() { + return __classPrivateFieldGet(this, _ControlTips_element, "f"); + } + toggle(bool) { + this.getElement().classList.toggle("hide", bool); + } +} +exports.ControlTips = ControlTips; +_ControlTips_element = new WeakMap(), _ControlTips_app = new WeakMap(), _ControlTips_shortcutManager = new WeakMap(), _ControlTips_cursorIsHoveringOverUnit = new WeakMap(), _ControlTips_cursorIsHoveringOverAirbase = new WeakMap(), _ControlTips_instances = new WeakSet(), _ControlTips_updateTips = function _ControlTips_updateTips() { + const combos = [ + { + "keys": [], + "tips": [ + { + "key": `SHIFT`, + "action": `Box select`, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "showIfUnitSelected": false + }, + { + "key": `Mouse1`, + "action": `Deselect`, + "showIfUnitSelected": true + }, + { + "key": `Mouse1+drag`, + "action": `Move map`, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "showIfUnitSelected": false + }, + { + "key": `Mouse2`, + "action": `Spawn menu`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse2`, + "action": `Quick options`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": true + }, + { + "key": `Mouse2`, + "action": `Airbase menu`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": true, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse2`, + "action": `Set first waypoint`, + "showIfHoveringOverAirbase": false, + "showIfUnitSelected": true, + "unitsMustBeControlled": true + }, + { + "key": "CTRL+Mouse2", + "action": "Add waypoint", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "unitsMustBeControlled": true + }, + { + "key": `Mouse2 (hold)`, + "action": `Point operations`, + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "unitsMustBeControlled": true + }, + { + "key": "CTRL", + "action": " Pin tool", + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "unitsMustBeControlled": true + }, + { + "key": "CTRL+Mouse2", + "action": " Airbase menu", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": true, + "unitsMustBeControlled": true + }, + { + "key": `Delete`, + "action": `Delete unit`, + "showIfHoveringOverAirbase": false, + "showIfUnitSelected": true + } + ] + }, + { + "keys": ["ControlLeft"], + "tips": [ + { + "key": `Mouse1`, + "action": "Toggle pin", + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse1`, + "action": "Toggle selection", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": true + }, + { + "key": `Mouse2`, + "action": `Add waypoint`, + "showIfHoveringOverAirbase": false, + "showIfUnitSelected": true, + "unitsMustBeControlled": true + }, + { + "key": `Mouse2`, + "action": `Airbase menu`, + "showIfHoveringOverAirbase": true, + "showIfUnitSelected": true, + "unitsMustBeControlled": true + } + ] + }, + { + "keys": ["ShiftLeft"], + "tips": [ + { + "key": `mouse1+drag`, + "action": "Box select" + } + ] + } + ]; + const currentCombo = combos.find((combo) => __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").keyComboMatches(combo.keys)) || combos[0]; + const element = this.getElement(); + element.innerHTML = ""; + let numSelectedUnits = 0; + let unitSelectionContainsControlled = false; + if (__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager()) { + let selectedUnits = Object.values(__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager().getSelectedUnits()); + numSelectedUnits = selectedUnits.length; + unitSelectionContainsControlled = selectedUnits.some((unit) => unit.getControlled()); + } + currentCombo.tips.forEach((tip) => { + if (numSelectedUnits > 0) { + if (tip.showIfUnitSelected === false) { + return; + } + if (tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false) { + return; + } + } + if (numSelectedUnits === 0 && tip.showIfUnitSelected === true) { + return; + } + if (typeof tip.showIfHoveringOverAirbase === "boolean") { + if (tip.showIfHoveringOverAirbase !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverAirbase, "f")) { + return; + } + } + if (typeof tip.showIfHoveringOverUnit === "boolean") { + if (tip.showIfHoveringOverUnit !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverUnit, "f")) { + return; + } + } + element.innerHTML += `
${tip.key}${tip.action}
`; + }); +}; + +},{}],2:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const controltips_1 = require("./controltips"); +globalThis.getOlympusPlugin = () => { + return new controltips_1.ControlTips(); +}; + +},{"./controltips":1}]},{},[2]); diff --git a/client/plugins/controltips/package-lock.json b/client/plugins/controltips/package-lock.json new file mode 100644 index 00000000..86c830ed --- /dev/null +++ b/client/plugins/controltips/package-lock.json @@ -0,0 +1,162 @@ +{ + "name": "ControlTipsPlugin", + "version": "v0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "requires": { + "error-ex": "^1.2.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "tsconfig": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-5.0.3.tgz", + "integrity": "sha512-Cq65A3kVp6BbsUgg9DRHafaGmbMb9EhAc7fjWvudNWKjkbWrt43FnrtZt6awshH1R0ocfF2Z0uxock3lVqEgOg==", + "requires": { + "any-promise": "^1.3.0", + "parse-json": "^2.2.0", + "strip-bom": "^2.0.0", + "strip-json-comments": "^2.0.0" + } + }, + "tsify": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/tsify/-/tsify-5.0.4.tgz", + "integrity": "sha512-XAZtQ5OMPsJFclkZ9xMZWkSNyMhMxEPsz3D2zu79yoKorH9j/DT4xCloJeXk5+cDhosEibu4bseMVjyPOAyLJA==", + "requires": { + "convert-source-map": "^1.1.0", + "fs.realpath": "^1.0.0", + "object-assign": "^4.1.0", + "semver": "^6.1.0", + "through2": "^2.0.0", + "tsconfig": "^5.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/client/plugins/controltips/package.json b/client/plugins/controltips/package.json new file mode 100644 index 00000000..3b0097a1 --- /dev/null +++ b/client/plugins/controltips/package.json @@ -0,0 +1,10 @@ +{ + "name": "ControlTipsPlugin", + "version": "v0.0.1", + "private": true, + "scripts": { + "build": "browserify ./src/index.ts -p [ tsify --noImplicitAny] > index.js && copy.bat" + }, + "dependencies": {}, + "devDependencies": {} +} diff --git a/client/plugins/controltips/plugin.json b/client/plugins/controltips/plugin.json new file mode 100644 index 00000000..77a1f817 --- /dev/null +++ b/client/plugins/controltips/plugin.json @@ -0,0 +1,6 @@ +{ + "name": "Control Tip Plugin", + "version": "0.0.1", + "description": "This plugin shows useful control tips on the right side of the screen. The tips change dynamically depending on what the user does", + "author": "Peekaboo" +} \ No newline at end of file diff --git a/client/src/shortcut/controltips.ts b/client/plugins/controltips/src/controltips.ts similarity index 70% rename from client/src/shortcut/controltips.ts rename to client/plugins/controltips/src/controltips.ts index a31ef77b..9e885247 100644 --- a/client/src/shortcut/controltips.ts +++ b/client/plugins/controltips/src/controltips.ts @@ -1,80 +1,79 @@ -import { OlympusApp } from "../olympusapp"; -import { ShortcutManager } from "../shortcut/shortcutmanager"; -import { Unit } from "../unit/unit"; +export class ControlTipsPlugin implements OlympusPlugin { + #element: HTMLElement; + #app: any; + #shortcutManager: any; + #cursorIsHoveringOverUnit: boolean = false; + #cursorIsHoveringOverAirbase: boolean = false; + + constructor() { + this.#element = document.createElement("div"); + this.#element.id = "control-tips-panel"; + document.body.appendChild(this.#element); + console.log("HELLO") + } -export class ControlTips { + getName() { + return "Control Tips Plugin" + } - #element:HTMLElement; - #cursorIsHoveringOverUnit:boolean = false; - #cursorIsHoveringOverAirbase:boolean = false; - #olympusApp:OlympusApp; - #shortcutManager:ShortcutManager; + initialize(app: any) { + this.#app = app; - constructor( ID:string, olympusApp:OlympusApp ) { + this.#shortcutManager = this.#app.getShortcutManager(); - this.#element = document.getElementById( ID ); - - this.#olympusApp = olympusApp; - - this.#shortcutManager = this.#olympusApp.getShortcutManager(); - - this.#shortcutManager.onKeyDown( () => { - this.#updateTips() + this.#shortcutManager.onKeyDown(() => { + this.#updateTips() }); - this.#shortcutManager.onKeyUp( () => { - this.#updateTips() + this.#shortcutManager.onKeyUp(() => { + this.#updateTips() }); - document.addEventListener( "airbaseMouseover", ( ev:CustomEventInit ) => { + document.addEventListener("airbaseMouseover", (ev: CustomEventInit) => { this.#cursorIsHoveringOverAirbase = true; this.#updateTips(); }); - document.addEventListener( "airbaseMouseout", ( ev:CustomEventInit ) => { + document.addEventListener("airbaseMouseout", (ev: CustomEventInit) => { this.#cursorIsHoveringOverAirbase = false; this.#updateTips(); }); - document.addEventListener( "unitDeselection", ( ev:CustomEvent ) => { - this.#updateTips(); - }); + //document.addEventListener("unitDeselection", (ev: CustomEvent) => { + // this.#updateTips(); + //}); - document.addEventListener( "unitMouseover", ( ev:CustomEventInit ) => { + document.addEventListener("unitMouseover", (ev: CustomEventInit) => { this.#cursorIsHoveringOverUnit = true; this.#updateTips(); }); - document.addEventListener( "unitMouseout", ( ev:CustomEventInit ) => { + document.addEventListener("unitMouseout", (ev: CustomEventInit) => { this.#cursorIsHoveringOverUnit = false; this.#updateTips(); }); - document.addEventListener( "unitSelection", ( ev:CustomEvent ) => { - this.#updateTips() - }); + //document.addEventListener("unitSelection", (ev: CustomEvent) => { + // this.#updateTips() + //}); this.#updateTips(); + return true; } getElement() { return this.#element; } - #getOlympusApp() { - return this.#olympusApp; - } - - toggle( bool?:boolean ) { - this.getElement().classList.toggle( "hide", bool ); - this.#olympusApp.getFeatureSwitches().savePreference( "controlTips", !this.getElement().classList.contains( "hide" ) ); + toggle(bool?: boolean) { + this.getElement().classList.toggle("hide", bool); } #updateTips() { - const combos:Array = [ + const combos: Array = [ { "keys": [], "tips": [ @@ -164,7 +163,7 @@ export class ControlTips { ] }, { - "keys": [ "ControlLeft" ], + "keys": ["ControlLeft"], "tips": [ { "key": `Mouse1`, @@ -197,7 +196,7 @@ export class ControlTips { ] }, { - "keys": [ "ShiftLeft" ], + "keys": ["ShiftLeft"], "tips": [ { "key": `mouse1+drag`, @@ -207,48 +206,44 @@ export class ControlTips { } ]; - const currentCombo:any = combos.find( (combo:any) => this.#shortcutManager.keyComboMatches( combo.keys ) ) || combos[0]; + const currentCombo: any = combos.find((combo: any) => this.#shortcutManager.keyComboMatches(combo.keys)) || combos[0]; const element = this.getElement(); element.innerHTML = ""; - const a = this.#getOlympusApp(); - let numSelectedUnits = 0; let unitSelectionContainsControlled = false; - if ( this.#getOlympusApp().getUnitsManager() ) { - let selectedUnits = Object.values( this.#getOlympusApp().getUnitsManager().getSelectedUnits() ); + if (this.#app.getUnitsManager()) { + let selectedUnits = Object.values(this.#app.getUnitsManager().getSelectedUnits()); numSelectedUnits = selectedUnits.length; - unitSelectionContainsControlled = selectedUnits.some( (unit:Unit) => unit.getControlled() ); + unitSelectionContainsControlled = selectedUnits.some((unit: any) => unit.getControlled()); } - - currentCombo.tips.forEach( ( tip:any ) => { - - if ( numSelectedUnits > 0 ) { - if ( tip.showIfUnitSelected === false ) { + currentCombo.tips.forEach((tip: any) => { + if (numSelectedUnits > 0) { + if (tip.showIfUnitSelected === false) { return; } - if ( tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false ) { + if (tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false) { return; } } - if ( numSelectedUnits === 0 && tip.showIfUnitSelected === true ) { + if (numSelectedUnits === 0 && tip.showIfUnitSelected === true) { return; } - if ( typeof tip.showIfHoveringOverAirbase === "boolean" ) { - if ( tip.showIfHoveringOverAirbase !== this.#cursorIsHoveringOverAirbase ) { + if (typeof tip.showIfHoveringOverAirbase === "boolean") { + if (tip.showIfHoveringOverAirbase !== this.#cursorIsHoveringOverAirbase) { return; } } - if ( typeof tip.showIfHoveringOverUnit === "boolean" ) { - if ( tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit ) { + if (typeof tip.showIfHoveringOverUnit === "boolean") { + if (tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit) { return; } } @@ -256,8 +251,5 @@ export class ControlTips { element.innerHTML += `
${tip.key}${tip.action}
` }); - - } - } \ No newline at end of file diff --git a/client/plugins/controltips/src/index.ts b/client/plugins/controltips/src/index.ts new file mode 100644 index 00000000..d6372eb6 --- /dev/null +++ b/client/plugins/controltips/src/index.ts @@ -0,0 +1,5 @@ +import { ControlTipsPlugin } from "./controltips"; + +globalThis.getOlympusPlugin = () => { + return new ControlTipsPlugin(); +} \ No newline at end of file diff --git a/client/public/stylesheets/other/controltips.css b/client/plugins/controltips/style.css similarity index 61% rename from client/public/stylesheets/other/controltips.css rename to client/plugins/controltips/style.css index 6ed26c79..0ab48856 100644 --- a/client/public/stylesheets/other/controltips.css +++ b/client/plugins/controltips/style.css @@ -11,23 +11,23 @@ z-index: 999; } -#control-tips-panel > * { +#control-tips-panel>* { align-items: center; align-self: end; - background-color: var( --background-steel ); + background-color: var(--background-steel); border-radius: var(--border-radius-md); color: white; column-gap: 8px; - display:flex; + display: flex; justify-items: right; opacity: .9; - padding:5px; - width:fit-content; + padding: 5px; + width: fit-content; } -#control-tips-panel > * > .key { - background-color: var( --background-grey ); - border-radius: var( --border-radius-sm ); +#control-tips-panel>*>.key { + background-color: var(--background-grey); + border-radius: var(--border-radius-sm); color: white; - padding:1px 4px; + padding: 1px 4px; } \ No newline at end of file diff --git a/client/plugins/controltips/tsconfig.json b/client/plugins/controltips/tsconfig.json new file mode 100644 index 00000000..2ba9ed01 --- /dev/null +++ b/client/plugins/controltips/tsconfig.json @@ -0,0 +1,104 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "ES2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + "rootDirs": ["./src", "../../@types"], /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + "typeRoots": [ + "./node_modules/@types", + "../../@types" + ], /* Specify multiple folders that act like './node_modules/@types'. */ + "types": [ + "olympus" + ], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": [ + "src/*.ts", + "../../@types/*.d.ts" + ] +} \ No newline at end of file diff --git a/client/public/plugins/controltipsplugin/index.js b/client/public/plugins/controltipsplugin/index.js new file mode 100644 index 00000000..90ee53e6 --- /dev/null +++ b/client/public/plugins/controltipsplugin/index.js @@ -0,0 +1,252 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i { + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").onKeyUp(() => { + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + document.addEventListener("airbaseMouseover", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, true, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + document.addEventListener("airbaseMouseout", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, false, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + //document.addEventListener("unitDeselection", (ev: CustomEvent) => { + // this.#updateTips(); + //}); + document.addEventListener("unitMouseover", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, true, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + document.addEventListener("unitMouseout", (ev) => { + __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, false, "f"); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + }); + //document.addEventListener("unitSelection", (ev: CustomEvent) => { + // this.#updateTips() + //}); + __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + return true; + } + getElement() { + return __classPrivateFieldGet(this, _ControlTips_element, "f"); + } + toggle(bool) { + this.getElement().classList.toggle("hide", bool); + } +} +exports.ControlTips = ControlTips; +_ControlTips_element = new WeakMap(), _ControlTips_app = new WeakMap(), _ControlTips_shortcutManager = new WeakMap(), _ControlTips_cursorIsHoveringOverUnit = new WeakMap(), _ControlTips_cursorIsHoveringOverAirbase = new WeakMap(), _ControlTips_instances = new WeakSet(), _ControlTips_updateTips = function _ControlTips_updateTips() { + const combos = [ + { + "keys": [], + "tips": [ + { + "key": `SHIFT`, + "action": `Box select`, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "showIfUnitSelected": false + }, + { + "key": `Mouse1`, + "action": `Deselect`, + "showIfUnitSelected": true + }, + { + "key": `Mouse1+drag`, + "action": `Move map`, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "showIfUnitSelected": false + }, + { + "key": `Mouse2`, + "action": `Spawn menu`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse2`, + "action": `Quick options`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": true + }, + { + "key": `Mouse2`, + "action": `Airbase menu`, + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": true, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse2`, + "action": `Set first waypoint`, + "showIfHoveringOverAirbase": false, + "showIfUnitSelected": true, + "unitsMustBeControlled": true + }, + { + "key": "CTRL+Mouse2", + "action": "Add waypoint", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "unitsMustBeControlled": true + }, + { + "key": `Mouse2 (hold)`, + "action": `Point operations`, + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "unitsMustBeControlled": true + }, + { + "key": "CTRL", + "action": " Pin tool", + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false, + "unitsMustBeControlled": true + }, + { + "key": "CTRL+Mouse2", + "action": " Airbase menu", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": true, + "unitsMustBeControlled": true + }, + { + "key": `Delete`, + "action": `Delete unit`, + "showIfHoveringOverAirbase": false, + "showIfUnitSelected": true + } + ] + }, + { + "keys": ["ControlLeft"], + "tips": [ + { + "key": `Mouse1`, + "action": "Toggle pin", + "showIfUnitSelected": false, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": false + }, + { + "key": `Mouse1`, + "action": "Toggle selection", + "showIfUnitSelected": true, + "showIfHoveringOverAirbase": false, + "showIfHoveringOverUnit": true + }, + { + "key": `Mouse2`, + "action": `Add waypoint`, + "showIfHoveringOverAirbase": false, + "showIfUnitSelected": true, + "unitsMustBeControlled": true + }, + { + "key": `Mouse2`, + "action": `Airbase menu`, + "showIfHoveringOverAirbase": true, + "showIfUnitSelected": true, + "unitsMustBeControlled": true + } + ] + }, + { + "keys": ["ShiftLeft"], + "tips": [ + { + "key": `mouse1+drag`, + "action": "Box select" + } + ] + } + ]; + const currentCombo = combos.find((combo) => __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").keyComboMatches(combo.keys)) || combos[0]; + const element = this.getElement(); + element.innerHTML = ""; + let numSelectedUnits = 0; + let unitSelectionContainsControlled = false; + if (__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager()) { + let selectedUnits = Object.values(__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager().getSelectedUnits()); + numSelectedUnits = selectedUnits.length; + unitSelectionContainsControlled = selectedUnits.some((unit) => unit.getControlled()); + } + currentCombo.tips.forEach((tip) => { + if (numSelectedUnits > 0) { + if (tip.showIfUnitSelected === false) { + return; + } + if (tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false) { + return; + } + } + if (numSelectedUnits === 0 && tip.showIfUnitSelected === true) { + return; + } + if (typeof tip.showIfHoveringOverAirbase === "boolean") { + if (tip.showIfHoveringOverAirbase !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverAirbase, "f")) { + return; + } + } + if (typeof tip.showIfHoveringOverUnit === "boolean") { + if (tip.showIfHoveringOverUnit !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverUnit, "f")) { + return; + } + } + element.innerHTML += `
${tip.key}${tip.action}
`; + }); +}; + +},{}],2:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const controltips_1 = require("./controltips"); +globalThis.getOlympusPlugin = () => { + return new controltips_1.ControlTips(); +}; + +},{"./controltips":1}]},{},[2]); diff --git a/client/public/plugins/controltipsplugin/plugin.json b/client/public/plugins/controltipsplugin/plugin.json new file mode 100644 index 00000000..77a1f817 --- /dev/null +++ b/client/public/plugins/controltipsplugin/plugin.json @@ -0,0 +1,6 @@ +{ + "name": "Control Tip Plugin", + "version": "0.0.1", + "description": "This plugin shows useful control tips on the right side of the screen. The tips change dynamically depending on what the user does", + "author": "Peekaboo" +} \ No newline at end of file diff --git a/client/public/plugins/controltipsplugin/style.css b/client/public/plugins/controltipsplugin/style.css new file mode 100644 index 00000000..0ab48856 --- /dev/null +++ b/client/public/plugins/controltipsplugin/style.css @@ -0,0 +1,33 @@ +#control-tips-panel { + align-self: center; + display: flex; + flex-flow: column wrap; + font-size: 13px; + justify-self: flex-end; + position: absolute; + right: 10px; + row-gap: 20px; + text-align: right; + z-index: 999; +} + +#control-tips-panel>* { + align-items: center; + align-self: end; + background-color: var(--background-steel); + border-radius: var(--border-radius-md); + color: white; + column-gap: 8px; + display: flex; + justify-items: right; + opacity: .9; + padding: 5px; + width: fit-content; +} + +#control-tips-panel>*>.key { + background-color: var(--background-grey); + border-radius: var(--border-radius-sm); + color: white; + padding: 1px 4px; +} \ No newline at end of file diff --git a/client/public/stylesheets/leaflet/leaflet.css b/client/public/stylesheets/leaflet/leaflet.css index 9ade8dc4..1981009f 100644 --- a/client/public/stylesheets/leaflet/leaflet.css +++ b/client/public/stylesheets/leaflet/leaflet.css @@ -60,11 +60,6 @@ padding: 0; } -.leaflet-container img.leaflet-tile { - /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */ - mix-blend-mode: plus-lighter; -} - .leaflet-container.leaflet-touch-zoom { -ms-touch-action: pan-x pan-y; touch-action: pan-x pan-y; @@ -651,7 +646,7 @@ svg.leaflet-image-layer.leaflet-interactive path { } /* Printing */ - + @media print { /* Prevent printers from removing background-images of controls. */ .leaflet-control { diff --git a/client/routes/api/atc.js b/client/routes/api/atc.js index 2429cdce..b0896b15 100644 --- a/client/routes/api/atc.js +++ b/client/routes/api/atc.js @@ -1,82 +1,65 @@ -var express = require('express'); -var app = express(); +var express = require('express'); +var app = express(); const bodyParser = require('body-parser'); -app.use(bodyParser.urlencoded({ extended: false})); +app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); - -/* - - Flight: - "name" - "take-off time" - "priority" - "status" - -//*/ - function uuidv4() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } - - - -function Flight( name, boardId, unitId ) { +function Flight(name, boardId, unitId) { this.assignedAltitude = 0; - this.assignedSpeed = 0; - this.id = uuidv4(); - this.boardId = boardId; - this.name = name; - this.status = "unknown"; - this.takeoffTime = -1; - this.unitId = parseInt( unitId ); + this.assignedSpeed = 0; + this.id = uuidv4(); + this.boardId = boardId; + this.name = name; + this.status = "unknown"; + this.takeoffTime = -1; + this.unitId = parseInt(unitId); } -Flight.prototype.getData = function() { +Flight.prototype.getData = function () { return { - "assignedAltitude" : this.assignedAltitude, - "assignedSpeed" : this.assignedSpeed, - "id" : this.id, - "boardId" : this.boardId, - "name" : this.name, - "status" : this.status, - "takeoffTime" : this.takeoffTime, - "unitId" : this.unitId + "assignedAltitude": this.assignedAltitude, + "assignedSpeed": this.assignedSpeed, + "id": this.id, + "boardId": this.boardId, + "name": this.name, + "status": this.status, + "takeoffTime": this.takeoffTime, + "unitId": this.unitId }; } +Flight.prototype.setAssignedAltitude = function (assignedAltitude) { -Flight.prototype.setAssignedAltitude = function( assignedAltitude ) { - - if ( isNaN( assignedAltitude ) ) { + if (isNaN(assignedAltitude)) { return "Altitude must be a number" } - this.assignedAltitude = parseInt( assignedAltitude ); + this.assignedAltitude = parseInt(assignedAltitude); return true; } +Flight.prototype.setAssignedSpeed = function (assignedSpeed) { -Flight.prototype.setAssignedSpeed = function( assignedSpeed ) { - - if ( isNaN( assignedSpeed ) ) { + if (isNaN(assignedSpeed)) { return "Speed must be a number" } - this.assignedSpeed = parseInt( assignedSpeed ); + this.assignedSpeed = parseInt(assignedSpeed); return true; } - -Flight.prototype.setOrder = function( order ) { +Flight.prototype.setOrder = function (order) { this.order = order; @@ -84,10 +67,9 @@ Flight.prototype.setOrder = function( order ) { } +Flight.prototype.setStatus = function (status) { -Flight.prototype.setStatus = function( status ) { - - if ( [ "unknown", "checkedin", "readytotaxi", "clearedtotaxi", "halted", "terminated" ].indexOf( status ) < 0 ) { + if (["unknown", "checkedin", "readytotaxi", "clearedtotaxi", "halted", "terminated"].indexOf(status) < 0) { return "Invalid status"; } @@ -97,197 +79,186 @@ Flight.prototype.setStatus = function( status ) { } +Flight.prototype.setTakeoffTime = function (takeoffTime) { -Flight.prototype.setTakeoffTime = function( takeoffTime ) { - - if ( takeoffTime === "" || takeoffTime === -1 ) { + if (takeoffTime === "" || takeoffTime === -1) { this.takeoffTime = -1; } - if ( isNaN( takeoffTime ) ) { + if (isNaN(takeoffTime)) { return "Invalid takeoff time" } - this.takeoffTime = parseInt( takeoffTime ); + this.takeoffTime = parseInt(takeoffTime); return true; } - - -function ATCDataHandler( data ) { +function ATCDataHandler(data) { this.data = data; } -ATCDataHandler.prototype.addFlight = function( flight ) { +ATCDataHandler.prototype.addFlight = function (flight) { - if ( flight instanceof Flight === false ) { - throw new Error( "Given flight is not an instance of Flight" ); + if (flight instanceof Flight === false) { + throw new Error("Given flight is not an instance of Flight"); } - this.data.flights[ flight.id ] = flight; + this.data.flights[flight.id] = flight; } - -ATCDataHandler.prototype.deleteFlight = function( flightId ) { - delete this.data.flights[ flightId ]; +ATCDataHandler.prototype.deleteFlight = function (flightId) { + delete this.data.flights[flightId]; } - -ATCDataHandler.prototype.getFlight = function( flightId ) { - return this.data.flights[ flightId ] || false; +ATCDataHandler.prototype.getFlight = function (flightId) { + return this.data.flights[flightId] || false; } - -ATCDataHandler.prototype.getFlights = function() { +ATCDataHandler.prototype.getFlights = function () { return this.data.flights; } - -const dataHandler = new ATCDataHandler( { +const dataHandler = new ATCDataHandler({ "flights": {} -} ); - - +}); /**************************************************************************************************************/ // Endpoints /**************************************************************************************************************/ +app.get("/flight", (req, res) => { + let flights = Object.values(dataHandler.getFlights()); -app.get( "/flight", ( req, res ) => { + if (flights && req.query.boardId) { - let flights = Object.values( dataHandler.getFlights() ); - - if ( flights && req.query.boardId ) { - - flights = flights.reduce( ( acc, flight ) => { - if ( flight.boardId === req.query.boardId ) { - acc[ flight.id ] = flight; + flights = flights.reduce((acc, flight) => { + if (flight.boardId === req.query.boardId) { + acc[flight.id] = flight; } return acc; - }, {} ); + }, {}); } - res.json( flights ); + res.json(flights); }); -app.patch( "/flight/:flightId", ( req, res ) => { +app.patch("/flight/:flightId", (req, res) => { const flightId = req.params.flightId; - const flight = dataHandler.getFlight( flightId ); + const flight = dataHandler.getFlight(flightId); - if ( !flight ) { - res.status( 400 ).send( `Unrecognised flight ID (given: "${req.params.flightId}")` ); + if (!flight) { + res.status(400).send(`Unrecognised flight ID (given: "${req.params.flightId}")`); } - if ( req.body.hasOwnProperty( "assignedAltitude" ) ) { + if (req.body.hasOwnProperty("assignedAltitude")) { - const altitudeChangeSuccess = flight.setAssignedAltitude( req.body.assignedAltitude ); + const altitudeChangeSuccess = flight.setAssignedAltitude(req.body.assignedAltitude); - if ( altitudeChangeSuccess !== true ) { - res.status( 400 ).send( altitudeChangeSuccess ); + if (altitudeChangeSuccess !== true) { + res.status(400).send(altitudeChangeSuccess); } } - if ( req.body.hasOwnProperty( "assignedSpeed" ) ) { + if (req.body.hasOwnProperty("assignedSpeed")) { - const speedChangeSuccess = flight.setAssignedSpeed( req.body.assignedSpeed ); + const speedChangeSuccess = flight.setAssignedSpeed(req.body.assignedSpeed); - if ( speedChangeSuccess !== true ) { - res.status( 400 ).send( speedChangeSuccess ); + if (speedChangeSuccess !== true) { + res.status(400).send(speedChangeSuccess); } } - if ( req.body.status ) { + if (req.body.status) { - const statusChangeSuccess = flight.setStatus( req.body.status ); + const statusChangeSuccess = flight.setStatus(req.body.status); - if ( statusChangeSuccess !== true ) { - res.status( 400 ).send( statusChangeSuccess ); + if (statusChangeSuccess !== true) { + res.status(400).send(statusChangeSuccess); } } - if ( req.body.hasOwnProperty( "takeoffTime" ) ) { + if (req.body.hasOwnProperty("takeoffTime")) { - const takeoffChangeSuccess = flight.setTakeoffTime( req.body.takeoffTime ); + const takeoffChangeSuccess = flight.setTakeoffTime(req.body.takeoffTime); - if ( takeoffChangeSuccess !== true ) { - res.status( 400 ).send( takeoffChangeSuccess ); + if (takeoffChangeSuccess !== true) { + res.status(400).send(takeoffChangeSuccess); } } - res.json( flight.getData() ); + res.json(flight.getData()); }); -app.post( "/flight/order", ( req, res ) => { +app.post("/flight/order", (req, res) => { - if ( !req.body.boardId ) { - res.status( 400 ).send( "Invalid/missing boardId" ); + if (!req.body.boardId) { + res.status(400).send("Invalid/missing boardId"); } - if ( !req.body.order || !Array.isArray( req.body.order ) ) { - res.status( 400 ).send( "Invalid/missing boardId" ); + if (!req.body.order || !Array.isArray(req.body.order)) { + res.status(400).send("Invalid/missing boardId"); } - req.body.order.forEach( ( flightId, i ) => { + req.body.order.forEach((flightId, i) => { - dataHandler.getFlight( flightId ).setOrder( i ); + dataHandler.getFlight(flightId).setOrder(i); }); - res.send( "" ); + res.send(""); }); -app.post( "/flight", ( req, res ) => { +app.post("/flight", (req, res) => { - if ( !req.body.boardId ) { - res.status( 400 ).send( "Invalid/missing boardId" ); + if (!req.body.boardId) { + res.status(400).send("Invalid/missing boardId"); } - if ( !req.body.name ) { - res.status( 400 ).send( "Invalid/missing flight name" ); + if (!req.body.name) { + res.status(400).send("Invalid/missing flight name"); } - if ( !req.body.unitId || isNaN( req.body.unitId ) ) { - res.status( 400 ).send( "Invalid/missing unitId" ); + if (!req.body.unitId || isNaN(req.body.unitId)) { + res.status(400).send("Invalid/missing unitId"); } - const flight = new Flight( req.body.name, req.body.boardId, req.body.unitId ); + const flight = new Flight(req.body.name, req.body.boardId, req.body.unitId); - dataHandler.addFlight( flight ); + dataHandler.addFlight(flight); - res.status( 201 ); + res.status(201); - res.json( flight.getData() ); + res.json(flight.getData()); }); -app.delete( "/flight/:flightId", ( req, res ) => { +app.delete("/flight/:flightId", (req, res) => { - const flight = dataHandler.getFlight( req.params.flightId ); + const flight = dataHandler.getFlight(req.params.flightId); - if ( !flight ) { - res.status( 400 ).send( `Unrecognised flight ID (given: "${req.params.flightId}")` ); + if (!flight) { + res.status(400).send(`Unrecognised flight ID (given: "${req.params.flightId}")`); } - dataHandler.deleteFlight( req.params.flightId ); + dataHandler.deleteFlight(req.params.flightId); - res.status( 204 ).send( "" ); + res.status(204).send(""); }); diff --git a/client/routes/plugins.js b/client/routes/plugins.js new file mode 100644 index 00000000..1ed9511f --- /dev/null +++ b/client/routes/plugins.js @@ -0,0 +1,23 @@ +const express = require('express'); +const fs = require('fs'); +const path = require('path'); + +const pluginsDirectory = "./public/plugins" + +const router = express.Router(); + +function listDirectories(source) { + const directories = fs.readdirSync(source, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name); + + return directories; +} + +router.get('/list', function (req, res) { + var directories = listDirectories(pluginsDirectory); + console.log(directories) + res.send(directories.filter(directory => fs.existsSync(path.join(pluginsDirectory, directory)))); +}); + +module.exports = router; diff --git a/client/routes/resources.js b/client/routes/resources.js index 2be3af2f..308243bc 100644 --- a/client/routes/resources.js +++ b/client/routes/resources.js @@ -1,6 +1,7 @@ const express = require('express'); const router = express.Router(); +// TODO should be user selectable or at least configurable from configuration file var theme = "olympus"; router.get('/theme/*', function (req, res, next) { diff --git a/client/src/@types/server.d.ts b/client/src/@types/server.d.ts deleted file mode 100644 index 851bfd53..00000000 --- a/client/src/@types/server.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -interface AirbasesData { - airbases: {[key: string]: any}, - sessionHash: string; - time: number; -} - -interface BullseyesData { - bullseyes: {[key: string]: {latitude: number, longitude: number, coalition: string}}, - sessionHash: string; - time: number; -} - -interface MissionData { - mission: { - theatre: string, - dateAndTime: DateAndTime; - commandModeOptions: CommandModeOptions; - coalitions: {red: string[], blue: string[]} = {}; - } - time: number; - sessionHash: string; -} - -interface CommandModeOptions { - commandMode: string; - restrictSpawns: boolean; - restrictToCoalition: boolean; - setupTime: number; - spawnPoints: { - red: number, - blue: number - }, - eras: string[] -} - -interface DateAndTime { - date: {Year: number, Month: number, Day: number}; - time: {h: number, m: number, s: number}; - elapsedTime: number; - startTime: number; -} - -interface LogData { - logs: {[key: string]: string}, - sessionHash: string; - time: number; -} - -interface ServerRequestOptions { - time?: number; - commandHash?: string; -} \ No newline at end of file diff --git a/client/src/@types/unit.d.ts b/client/src/@types/unit.d.ts deleted file mode 100644 index 90c7266c..00000000 --- a/client/src/@types/unit.d.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { LatLng } from "leaflet" - -interface UnitSpawnTable { - unitType: string, - location: latlng, - altitude?: number, - loadout?: string, - liveryID: string -} - -interface ObjectIconOptions { - showState: boolean, - showVvi: boolean, - showHotgroup: boolean, - showUnitIcon: boolean, - showShortLabel: boolean, - showFuel: boolean, - showAmmo: boolean, - showSummary: boolean, - showCallsign: boolean, - rotateToHeading: boolean -} - -interface GeneralSettings { - prohibitJettison: boolean; - prohibitAA: boolean; - prohibitAG: boolean; - prohibitAfterburner: boolean; - prohibitAirWpn: boolean; -} - -interface TACAN { - isOn: boolean; - channel: number; - XY: string; - callsign: string; -} - -interface Radio { - frequency: number; - callsign: number; - callsignNumber: number; -} - -interface Ammo { - quantity: number, - name: string, - guidance: number, - category: number, - missileCategory: number -} - -interface Contact { - ID: number, - detectionMethod: number -} - -interface Offset { - x: number, - y: number, - z: number -} - -interface UnitData { - category: string, - ID: number; - alive: boolean; - human: boolean; - controlled: boolean; - coalition: string; - country: number; - name: string; - unitName: string; - groupName: string; - state: string; - task: string; - hasTask: boolean; - position: LatLng; - speed: number; - heading: number; - isTanker: boolean; - isAWACS: boolean; - onOff: boolean; - followRoads: boolean; - fuel: number; - desiredSpeed: number; - desiredSpeedType: string; - desiredAltitude: number; - desiredAltitudeType: string; - leaderID: number; - formationOffset: Offset; - targetID: number; - targetPosition: LatLng; - ROE: string; - reactionToThreat: string; - emissionsCountermeasures: string; - TACAN: TACAN; - radio: Radio; - generalSettings: GeneralSettings; - ammo: Ammo[]; - contacts: Contact[]; - activePath: LatLng[]; - isLeader: boolean; -} \ No newline at end of file diff --git a/client/src/@types/unitdatabase.d.ts b/client/src/@types/unitdatabase.d.ts deleted file mode 100644 index 08c9efbd..00000000 --- a/client/src/@types/unitdatabase.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { LatLng } from "leaflet"; -import { Airbase } from "../mission/airbase"; - -interface LoadoutItemBlueprint { - name: string; - quantity: number; - effectiveAgainst?: string; -} - -interface LoadoutBlueprint { - fuel: number; - items: LoadoutItemBlueprint[]; - roles: string[]; - code: string; - name: string; -} - -interface UnitBlueprint { - name: string; - coalition: string; - era: string; - label: string; - shortLabel: string; - type?: string; - range?: string; - loadouts?: LoadoutBlueprint[]; - filename?: string; - liveries?: {[key: string]: {name: string, countries: string[]}}; - cost?: number; -} - -interface UnitSpawnOptions { - roleType: string; - name: string; - latlng: LatLng; - coalition: string; - count: number; - country: string; - loadout: LoadoutBlueprint | undefined; - airbase: Airbase | undefined; - liveryID: string | undefined; - altitude: number | undefined; -} diff --git a/client/src/app.ts b/client/src/app.ts new file mode 100644 index 00000000..3010a884 --- /dev/null +++ b/client/src/app.ts @@ -0,0 +1,151 @@ +import { Map } from "./map/map"; +import { MissionManager } from "./mission/missionmanager"; +import { ConnectionStatusPanel } from "./panels/connectionstatuspanel"; +import { HotgroupPanel } from "./panels/hotgrouppanel"; +import { LogPanel } from "./panels/logpanel"; +import { MouseInfoPanel } from "./panels/mouseinfopanel"; +import { ServerStatusPanel } from "./panels/serverstatuspanel"; +import { UnitControlPanel } from "./panels/unitcontrolpanel"; +import { UnitInfoPanel } from "./panels/unitinfopanel"; +import { PluginsManager } from "./plugin/pluginmanager"; +import { Popup } from "./popups/popup"; +import { ShortcutManager } from "./shortcut/shortcutmanager"; +import { CommandModeToolbar } from "./toolbars/commandmodetoolbar"; +import { PrimaryToolbar } from "./toolbars/primarytoolbar"; +import { UnitsManager } from "./unit/unitsmanager"; +import { WeaponsManager } from "./weapon/weaponsmanager"; + +import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants"; +import { Manager } from "./other/manager"; + +export class OlympusApp { + /* Global data */ + #activeCoalition: string = "blue"; + + /* Main leaflet map, extended by custom methods */ + #map: Map | null = null; + + /* Managers */ + #unitsManager: UnitsManager | null = null; + #weaponsManager: WeaponsManager | null = null; + #missionManager: MissionManager | null = null; + #pluginsManager: PluginsManager | null = null; + #panelsManager: Manager | null = null; + #popupsManager: Manager | null = null; + #toolbarsManager: Manager | null = null; + #shortcutManager: ShortcutManager | null = null; + + /* UI Toolbars */ + #primaryToolbar: PrimaryToolbar| null = null; + #commandModeToolbar: CommandModeToolbar| null = null; + + constructor() { + + } + + getMap() { + return this.#map as Map; + } + + getPanelsManager() { + return this.#panelsManager as Manager; + } + + getPopupsManager() { + return this.#popupsManager as Manager; + } + + getToolbarsManager() { + return this.#toolbarsManager as Manager; + } + + getShortcutManager() { + return this.#shortcutManager as ShortcutManager; + } + + getUnitsManager() { + return this.#unitsManager as UnitsManager; + } + + getWeaponsManager() { + return this.#weaponsManager as WeaponsManager; + } + + getMissionManager() { + return this.#missionManager as MissionManager; + } + + getPluginsManager() { + return this.#pluginsManager as PluginsManager; + } + + /** Set the active coalition, i.e. the currently controlled coalition. A game master can change the active coalition, while a commander is bound to his/her coalition + * + * @param newActiveCoalition + */ + setActiveCoalition(newActiveCoalition: string) { + if (this.getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER) + this.#activeCoalition = newActiveCoalition; + } + + /** + * + * @returns The active coalition + */ + getActiveCoalition() { + if (this.getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER) + return this.#activeCoalition; + else { + if (this.getMissionManager().getCommandModeOptions().commandMode == BLUE_COMMANDER) + return "blue"; + else if (this.getMissionManager().getCommandModeOptions().commandMode == RED_COMMANDER) + return "red"; + else + return "neutral"; + } + } + + /** Set a message in the login splash screen + * + * @param status The message to show in the login splash screen + */ + setLoginStatus(status: string) { + const el = document.querySelector("#login-status") as HTMLElement; + if (el) + el.dataset["status"] = status; + } + + start() { + /* Initialize base functionalitites */ + this.#map = new Map('map-container'); + + this.#unitsManager = new UnitsManager(); + this.#weaponsManager = new WeaponsManager(); + this.#missionManager = new MissionManager(); + + this.#shortcutManager = new ShortcutManager(); + + this.#panelsManager = new Manager(); + this.#popupsManager = new Manager(); + this.#toolbarsManager = new Manager(); + + // Panels + this.getPanelsManager() + .add("connectionStatus", new ConnectionStatusPanel("connection-status-panel")) + .add("hotgroup", new HotgroupPanel("hotgroup-panel")) + .add("mouseInfo", new MouseInfoPanel("mouse-info-panel")) + .add("log", new LogPanel("log-panel")) + .add("serverStatus", new ServerStatusPanel("server-status-panel")) + .add("unitControl", new UnitControlPanel("unit-control-panel")) + .add("unitInfo", new UnitInfoPanel("unit-info-panel")) + + // Popups + this.getPopupsManager().add("infoPopup", new Popup("info-popup")); + + // Toolbars + this.getToolbarsManager().add("primaryToolbar", new PrimaryToolbar("primary-toolbar")) + .add("commandModeToolbar", new PrimaryToolbar("command-mode-toolbar")); + + this.#pluginsManager = new PluginsManager(); + } +} \ No newline at end of file diff --git a/client/src/constants/constants.ts b/client/src/constants/constants.ts index 4bfac3c3..20bbbeeb 100644 --- a/client/src/constants/constants.ts +++ b/client/src/constants/constants.ts @@ -106,7 +106,7 @@ export const layers = { urlTemplate: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", maxZoom: 20, minZoom: 1, - attribution: "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community" + attribution: "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, GetApp().getMap()ping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community" }, "USGS Topo": { urlTemplate: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}', diff --git a/client/src/contextmenus/airbasecontextmenu.ts b/client/src/contextmenus/airbasecontextmenu.ts index 5215464a..b8fb6209 100644 --- a/client/src/contextmenus/airbasecontextmenu.ts +++ b/client/src/contextmenus/airbasecontextmenu.ts @@ -1,4 +1,4 @@ -import { getMap, getMissionHandler, getUnitsManager, setActiveCoalition } from ".."; +import { getApp } from ".."; import { GAME_MASTER } from "../constants/constants"; import { Airbase } from "../mission/airbase"; import { dataPointMap } from "../other/utils"; @@ -23,7 +23,7 @@ export class AirbaseContextMenu extends ContextMenu { document.addEventListener("contextMenuLandAirbase", (e: any) => { if (this.#airbase) - getUnitsManager().selectedUnitsLandAt(this.#airbase.getLatLng()); + getApp().getUnitsManager().selectedUnitsLandAt(this.#airbase.getLatLng()); this.hide(); }) } @@ -39,8 +39,8 @@ export class AirbaseContextMenu extends ContextMenu { this.#setProperties(this.#airbase.getProperties()); this.#setParkings(this.#airbase.getParkings()); this.#setCoalition(this.#airbase.getCoalition()); - this.#showLandButton(getUnitsManager().getSelectedUnitsCategories().length == 1 && ["Aircraft", "Helicopter"].includes(getUnitsManager().getSelectedUnitsCategories()[0]) && (getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) === this.#airbase.getCoalition() || this.#airbase.getCoalition() === "neutral")) - this.#showSpawnButton(getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || this.#airbase.getCoalition() == getMissionHandler().getCommandedCoalition()); + this.#showLandButton(getApp().getUnitsManager().getSelectedUnitsCategories().length == 1 && ["Aircraft", "Helicopter"].includes(getApp().getUnitsManager().getSelectedUnitsCategories()[0]) && (getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) === this.#airbase.getCoalition() || this.#airbase.getCoalition() === "neutral")) + this.#showSpawnButton(getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER || this.#airbase.getCoalition() == getApp().getMissionManager().getCommandedCoalition()); this.#setAirbaseData(); this.clip(); @@ -109,8 +109,8 @@ export class AirbaseContextMenu extends ContextMenu { */ #showSpawnMenu() { if (this.#airbase != null) { - setActiveCoalition(this.#airbase.getCoalition()); - getMap().showAirbaseSpawnMenu(this.getX(), this.getY(), this.getLatLng(), this.#airbase); + getApp().setActiveCoalition(this.#airbase.getCoalition()); + getApp().getMap().showAirbaseSpawnMenu(this.getX(), this.getY(), this.getLatLng(), this.#airbase); } } @@ -135,11 +135,11 @@ export class AirbaseContextMenu extends ContextMenu { if ( runways.length === 0 ) { runwaysContainer.innerText = "No data"; } else { - runways.forEach( runway => { + runways.forEach( (runway: AirbaseChartRunwayData) => { let runwayDiv = document.createElement( "div" ); runwayDiv.classList.add( "runway" ); - runway.headings.forEach( headings => { + runway.headings.forEach( (headings: AirbaseChartRunwayHeadingData) => { for ( const [ heading, data ] of Object.entries( headings ) ) { let headingDiv = document.createElement( "div" ); diff --git a/client/src/contextmenus/airbasespawnmenu.ts b/client/src/contextmenus/airbasespawnmenu.ts index 4266a733..a5c40e3c 100644 --- a/client/src/contextmenus/airbasespawnmenu.ts +++ b/client/src/contextmenus/airbasespawnmenu.ts @@ -1,8 +1,8 @@ import { LatLng } from "leaflet"; -import { getActiveCoalition } from ".."; import { ContextMenu } from "./contextmenu"; import { AircraftSpawnMenu, HelicopterSpawnMenu } from "../controls/unitspawnmenu"; import { Airbase } from "../mission/airbase"; +import { getApp } from ".."; /** This context menu is shown when the user wants to spawn a new aircraft or helicopter from the ground at an airbase. * It is shown by clicking on the "spawn" button of a AirbaseContextMenu. */ @@ -54,7 +54,7 @@ export class AirbaseSpawnContextMenu extends ContextMenu { this.#aircraftSpawnMenu.setCountries(); this.#helicopterSpawnMenu.setCountries(); - this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) }); + this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getApp().getActiveCoalition()) }); } /** Sets the airbase at which the new unit will be spawned diff --git a/client/src/contextmenus/coalitionareacontextmenu.ts b/client/src/contextmenus/coalitionareacontextmenu.ts index 94a88e36..375355cc 100644 --- a/client/src/contextmenus/coalitionareacontextmenu.ts +++ b/client/src/contextmenus/coalitionareacontextmenu.ts @@ -1,5 +1,5 @@ import { LatLng } from "leaflet"; -import { getMap, getMissionHandler, getUnitsManager } from ".."; +import { getApp } from ".."; import { GAME_MASTER, IADSTypes } from "../constants/constants"; import { CoalitionArea } from "../map/coalitionarea/coalitionarea"; import { ContextMenu } from "./contextmenu"; @@ -54,20 +54,20 @@ export class CoalitionAreaContextMenu extends ContextMenu { document.addEventListener("coalitionAreaBringToBack", (e: any) => { if (this.#coalitionArea) - getMap().bringCoalitionAreaToBack(this.#coalitionArea); - getMap().hideCoalitionAreaContextMenu(); + getApp().getMap().bringCoalitionAreaToBack(this.#coalitionArea); + getApp().getMap().hideCoalitionAreaContextMenu(); }); document.addEventListener("coalitionAreaDelete", (e: any) => { if (this.#coalitionArea) - getMap().deleteCoalitionArea(this.#coalitionArea); - getMap().hideCoalitionAreaContextMenu(); + getApp().getMap().deleteCoalitionArea(this.#coalitionArea); + getApp().getMap().hideCoalitionAreaContextMenu(); }); document.addEventListener("contextMenuCreateIads", (e: any) => { const area = this.getCoalitionArea(); if (area) - getUnitsManager().createIADS(area, getCheckboxOptions(this.#iadsTypesDropdown), getCheckboxOptions(this.#iadsErasDropdown), getCheckboxOptions(this.#iadsRangesDropdown), this.#iadsDensitySlider.getValue(), this.#iadsDistributionSlider.getValue()); + getApp().getUnitsManager().createIADS(area, getCheckboxOptions(this.#iadsTypesDropdown), getCheckboxOptions(this.#iadsErasDropdown), getCheckboxOptions(this.#iadsRangesDropdown), this.#iadsDensitySlider.getValue(), this.#iadsDistributionSlider.getValue()); }) this.hide(); } @@ -97,7 +97,7 @@ export class CoalitionAreaContextMenu extends ContextMenu { return createCheckboxOption(range, `Add ${range} units to the IADS`); })); - if (getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) + if (getApp().getMissionManager().getCommandModeOptions().commandMode !== GAME_MASTER) this.#coalitionSwitch.hide() } @@ -149,7 +149,7 @@ export class CoalitionAreaContextMenu extends ContextMenu { * @param value Switch position (false: blue, true: red) */ #onSwitchClick(value: boolean) { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER) { + if (getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER) { this.getCoalitionArea()?.setCoalition(value ? "red" : "blue"); this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", this.getCoalitionArea()?.getCoalition()) diff --git a/client/src/contextmenus/mapcontextmenu.ts b/client/src/contextmenus/mapcontextmenu.ts index b35c1705..2d86772c 100644 --- a/client/src/contextmenus/mapcontextmenu.ts +++ b/client/src/contextmenus/mapcontextmenu.ts @@ -1,5 +1,5 @@ import { LatLng } from "leaflet"; -import { getActiveCoalition, getMap, getMissionHandler, setActiveCoalition } from ".."; +import { getApp } from ".."; import { spawnExplosion, spawnSmoke } from "../server/server"; import { ContextMenu } from "./contextmenu"; import { Switch } from "../controls/switch"; @@ -50,7 +50,7 @@ export class MapContextMenu extends ContextMenu { this.hide(); spawnSmoke(e.detail.color, this.getLatLng()); var marker = new SmokeMarker(this.getLatLng(), e.detail.color); - marker.addTo(getMap()); + marker.addTo(getApp().getMap()); }); document.addEventListener("contextMenuExplosion", (e: any) => { @@ -61,7 +61,7 @@ export class MapContextMenu extends ContextMenu { document.addEventListener("editCoalitionArea", (e: any) => { this.hide(); if (this.#coalitionArea) { - getMap().deselectAllCoalitionAreas(); + getApp().getMap().deselectAllCoalitionAreas(); this.#coalitionArea.setSelected(true); } }); @@ -103,13 +103,13 @@ export class MapContextMenu extends ContextMenu { this.#navyUnitSpawnMenu.setCountries(); /* Only a Game Master can choose the coalition of a new unit */ - if (getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) + if (getApp().getMissionManager().getCommandModeOptions().commandMode !== GAME_MASTER) this.#coalitionSwitch.hide() - this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) }); - if (getActiveCoalition() == "blue") + this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getApp().getActiveCoalition()) }); + if (getApp().getActiveCoalition() == "blue") this.#coalitionSwitch.setValue(false); - else if (getActiveCoalition() == "red") + else if (getApp().getActiveCoalition() == "red") this.#coalitionSwitch.setValue(true); else this.#coalitionSwitch.setValue(undefined); @@ -199,8 +199,8 @@ export class MapContextMenu extends ContextMenu { * @param value Switch position (false: "blue", true: "red") */ #onSwitchClick(value: boolean) { - value ? setActiveCoalition("red") : setActiveCoalition("blue"); - this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) }); + value ? getApp().setActiveCoalition("red") : getApp().setActiveCoalition("blue"); + this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getApp().getActiveCoalition()) }); this.#aircraftSpawnMenu.setCountries(); this.#helicopterSpawnMenu.setCountries(); this.#groundUnitSpawnMenu.setCountries(); @@ -212,8 +212,8 @@ export class MapContextMenu extends ContextMenu { */ #onSwitchRightClick() { this.#coalitionSwitch.setValue(undefined); - setActiveCoalition("neutral"); - this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) }); + getApp().setActiveCoalition("neutral"); + this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getApp().getActiveCoalition()) }); this.#aircraftSpawnMenu.setCountries(); this.#helicopterSpawnMenu.setCountries(); this.#groundUnitSpawnMenu.setCountries(); diff --git a/client/src/controls/unitspawnmenu.ts b/client/src/controls/unitspawnmenu.ts index 083806e7..a2702dd8 100644 --- a/client/src/controls/unitspawnmenu.ts +++ b/client/src/controls/unitspawnmenu.ts @@ -2,16 +2,14 @@ import { LatLng } from "leaflet"; import { Dropdown } from "./dropdown"; import { Slider } from "./slider"; import { UnitDatabase } from "../unit/databases/unitdatabase"; -import { getActiveCoalition, getMap, getMissionHandler, getUnitsManager } from ".."; +import { getApp } from ".."; import { GAME_MASTER } from "../constants/constants"; -import { UnitSpawnOptions } from "../@types/unitdatabase"; import { Airbase } from "../mission/airbase"; import { ftToM } from "../other/utils"; import { aircraftDatabase } from "../unit/databases/aircraftdatabase"; import { helicopterDatabase } from "../unit/databases/helicopterdatabase"; import { groundUnitDatabase } from "../unit/databases/groundunitdatabase"; import { navyUnitDatabase } from "../unit/databases/navyunitdatabase"; -import { UnitSpawnTable } from "../@types/unit"; export class UnitSpawnMenu { #container: HTMLElement; @@ -209,8 +207,8 @@ export class UnitSpawnMenu { } setCountries() { - var coalitions = getMissionHandler().getCoalitions(); - var countries = Object.values(coalitions[getActiveCoalition() as keyof typeof coalitions]); + var coalitions = getApp().getMissionManager().getCoalitions(); + var countries = Object.values(coalitions[getApp().getActiveCoalition() as keyof typeof coalitions]); this.#unitCountryDropdown.setOptionsElements(this.#createCountryButtons(this.#unitCountryDropdown, countries, (country: string) => { this.#setUnitCountry(country) })); if (countries.length > 0 && !countries.includes(this.#spawnOptions.country)) { @@ -377,11 +375,11 @@ export class UnitSpawnMenu { } #computeSpawnPoints() { - if (getMissionHandler() && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) { + if (getApp().getMissionManager() && getApp().getMissionManager().getCommandModeOptions().commandMode !== GAME_MASTER) { var unitCount = parseInt(this.#unitCountDropdown.getValue()); var unitSpawnPoints = unitCount * this.#unitDatabase.getSpawnPointsByLabel(this.#unitLabelDropdown.getValue()); this.#deployUnitButtonEl.dataset.points = `${unitSpawnPoints}`; - this.#deployUnitButtonEl.disabled = unitSpawnPoints >= getMissionHandler().getAvailableSpawnPoints(); + this.#deployUnitButtonEl.disabled = unitSpawnPoints >= getApp().getMissionManager().getAvailableSpawnPoints(); } } } @@ -400,7 +398,7 @@ export class AircraftSpawnMenu extends UnitSpawnMenu { } deployUnits(spawnOptions: UnitSpawnOptions, unitsCount: number) { - spawnOptions.coalition = getActiveCoalition(); + spawnOptions.coalition = getApp().getActiveCoalition(); if (spawnOptions) { var unitTable: UnitSpawnTable = { unitType: spawnOptions.name, @@ -414,9 +412,9 @@ export class AircraftSpawnMenu extends UnitSpawnMenu { units.push(unitTable); } - getUnitsManager().spawnUnits("Aircraft", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { + getApp().getUnitsManager().spawnUnits("Aircraft", units, getApp().getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { if (res.commandHash !== undefined) - getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash); + getApp().getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getApp().getActiveCoalition(), res.commandHash); }); this.getContainer().dispatchEvent(new Event("hide")); @@ -438,7 +436,7 @@ export class HelicopterSpawnMenu extends UnitSpawnMenu { } deployUnits(spawnOptions: UnitSpawnOptions, unitsCount: number) { - spawnOptions.coalition = getActiveCoalition(); + spawnOptions.coalition = getApp().getActiveCoalition(); if (spawnOptions) { var unitTable: UnitSpawnTable = { unitType: spawnOptions.name, @@ -452,9 +450,9 @@ export class HelicopterSpawnMenu extends UnitSpawnMenu { units.push(unitTable); } - getUnitsManager().spawnUnits("Helicopter", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { + getApp().getUnitsManager().spawnUnits("Helicopter", units, getApp().getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { if (res.commandHash !== undefined) - getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash); + getApp().getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getApp().getActiveCoalition(), res.commandHash); }); this.getContainer().dispatchEvent(new Event("hide")); @@ -476,7 +474,7 @@ export class GroundUnitSpawnMenu extends UnitSpawnMenu { } deployUnits(spawnOptions: UnitSpawnOptions, unitsCount: number) { - spawnOptions.coalition = getActiveCoalition(); + spawnOptions.coalition = getApp().getActiveCoalition(); if (spawnOptions) { var unitTable: UnitSpawnTable = { unitType: spawnOptions.name, @@ -490,9 +488,9 @@ export class GroundUnitSpawnMenu extends UnitSpawnMenu { unitTable.location.lat += i > 0? 0.0001: 0; } - getUnitsManager().spawnUnits("GroundUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { + getApp().getUnitsManager().spawnUnits("GroundUnit", units, getApp().getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { if (res.commandHash !== undefined) - getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash); + getApp().getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getApp().getActiveCoalition(), res.commandHash); }); this.getContainer().dispatchEvent(new Event("hide")); @@ -514,7 +512,7 @@ export class NavyUnitSpawnMenu extends UnitSpawnMenu { } deployUnits(spawnOptions: UnitSpawnOptions, unitsCount: number) { - spawnOptions.coalition = getActiveCoalition(); + spawnOptions.coalition = getApp().getActiveCoalition(); if (spawnOptions) { var unitTable: UnitSpawnTable = { unitType: spawnOptions.name, @@ -528,9 +526,9 @@ export class NavyUnitSpawnMenu extends UnitSpawnMenu { unitTable.location.lat += i > 0? 0.0001: 0; } - getUnitsManager().spawnUnits("NavyUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { + getApp().getUnitsManager().spawnUnits("NavyUnit", units, getApp().getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => { if (res.commandHash !== undefined) - getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash); + getApp().getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getApp().getActiveCoalition(), res.commandHash); }); this.getContainer().dispatchEvent(new Event("hide")); diff --git a/client/src/features/featureswitches.ts b/client/src/features/featureswitches.ts deleted file mode 100644 index bb78b64c..00000000 --- a/client/src/features/featureswitches.ts +++ /dev/null @@ -1,172 +0,0 @@ -export interface FeatureSwitchInterface { - "defaultEnabled": boolean, // default on/off state (if allowed by forceState) - "forceState": number, // -1 don't force; 0 force off; 1 force on - "label": string, - "name": string, - "onEnabled"?: CallableFunction, - "options"?: object, - "removeArtifactsIfDisabled"?: boolean -} - - -class FeatureSwitch { - - // From config param - defaultEnabled; - forceState = -1; - label; - name; - onEnabled; - removeArtifactsIfDisabled = true; - - // Self-set - userPreference; - - - constructor(config: FeatureSwitchInterface) { - - this.defaultEnabled = config.defaultEnabled; - this.forceState = config.forceState; - this.label = config.label; - this.name = config.name; - this.onEnabled = config.onEnabled; - - this.userPreference = this.getUserPreference(); - - } - - - getUserPreference() { - - let preferences = JSON.parse(localStorage.getItem("featureSwitches") || "{}"); - - return (preferences.hasOwnProperty(this.name)) ? preferences[this.name] : this.defaultEnabled; - - } - - - isEnabled():boolean { - - if ( this.forceState === 0 ) { - return false; - } - - if ( this.forceState === 1 ) { - return true; - } - - return this.userPreference; - } - -} - -export class FeatureSwitches { - - #featureSwitches: FeatureSwitch[] = [ - - new FeatureSwitch({ - "defaultEnabled": false, - "forceState": -1, - "label": "AIC", - "name": "aic" - }), - - new FeatureSwitch({ - "defaultEnabled": false, - "forceState": -1, - "label": "AI Formations", - "name": "ai-formations", - "removeArtifactsIfDisabled": false - }), - - new FeatureSwitch({ - "defaultEnabled": false, - "forceState": -1, - "label": "ATC", - "name": "atc" - }), - - new FeatureSwitch({ - "defaultEnabled": false, - "forceState": -1, - "label": "Control tips", - "name": "controlTips" - }), - - new FeatureSwitch({ - "defaultEnabled": false, - "forceState": -1, - "label": "Force show unit control panel", - "name": "forceShowUnitControlPanel" - }), - - new FeatureSwitch({ - "defaultEnabled": true, - "forceState": -1, - "label": "Show splash screen", - "name": "splashScreen" - }) - - ]; - - - constructor() { - - this.#testSwitches(); - - this.savePreferences(); - - } - - - getSwitch(switchName: string) { - - return this.#featureSwitches.find(featureSwitch => featureSwitch.name === switchName); - - } - - - #testSwitches() { - for (const featureSwitch of this.#featureSwitches) { - if (featureSwitch.isEnabled()) { - if (typeof featureSwitch.onEnabled === "function") { - featureSwitch.onEnabled(); - } - } else { - document.querySelectorAll("[data-feature-switch='" + featureSwitch.name + "']").forEach(el => { - if (featureSwitch.removeArtifactsIfDisabled === false) { - el.remove(); - } else { - el.classList.add("hide"); - } - }); - } - document.body.classList.toggle("feature-" + featureSwitch.name, featureSwitch.isEnabled()); - } - } - - savePreferences() { - - let preferences: any = {}; - - for (const featureSwitch of this.#featureSwitches) { - preferences[featureSwitch.name] = featureSwitch.isEnabled(); - } - - localStorage.setItem("featureSwitches", JSON.stringify(preferences)); - - } - - savePreference( featureSwitchName:string, value:boolean ) { - - const preferences = JSON.parse( localStorage.getItem( "featureSwitches" ) || "{}" ); - - if ( preferences.hasOwnProperty( featureSwitchName ) ) { - preferences[ featureSwitchName ] = value; - } - - localStorage.setItem("featureSwitches", JSON.stringify(preferences)); - - } - -} \ No newline at end of file diff --git a/client/src/features/toggleablefeature.ts b/client/src/features/toggleablefeature.ts deleted file mode 100644 index 09f1723e..00000000 --- a/client/src/features/toggleablefeature.ts +++ /dev/null @@ -1,35 +0,0 @@ -export abstract class ToggleableFeature { - - #status: boolean = false; - - - constructor(defaultStatus: boolean) { - - this.#status = defaultStatus; - - this.onStatusUpdate(); - - } - - - getStatus(): boolean { - return this.#status; - } - - - protected onStatusUpdate() { } - - - toggleStatus(force?: boolean): void { - - if (force) { - this.#status = force; - } else { - this.#status = !this.#status; - } - - this.onStatusUpdate(); - - } - -} \ No newline at end of file diff --git a/client/src/index.ts b/client/src/index.ts index 504c4462..23136d15 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -1,114 +1,30 @@ -import { Map } from "./map/map" -import { UnitsManager } from "./unit/unitsmanager"; -import { UnitInfoPanel } from "./panels/unitinfopanel"; -import { ConnectionStatusPanel } from "./panels/connectionstatuspanel"; -import { MissionManager } from "./mission/missionmanager"; -import { UnitControlPanel } from "./panels/unitcontrolpanel"; -import { MouseInfoPanel } from "./panels/mouseinfopanel"; -import { LogPanel } from "./panels/logpanel"; import { getConfig, getPaused, setAddress, setCredentials, setPaused, startUpdate, toggleDemoEnabled } from "./server/server"; -import { Popup } from "./popups/popup"; -import { HotgroupPanel } from "./panels/hotgrouppanel"; import { SVGInjector } from "@tanem/svg-injector"; -import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants"; -import { ServerStatusPanel } from "./panels/serverstatuspanel"; -import { WeaponsManager } from "./weapon/weaponsmanager"; -import { ConfigParameters } from "./@types/dom"; -import { IndexApp } from "./indexapp"; -import { FeatureSwitches } from "./features/featureswitches"; -import { PrimaryToolbar } from "./toolbars/primarytoolbar"; -import { CommandModeToolbar } from "./toolbars/commandmodetoolbar"; -import { OlympusApp } from "./olympusapp"; +import { OlympusApp } from "./app"; import { ShortcutKeyboard } from "./shortcut/shortcut"; -/* Global data */ -var activeCoalition: string = "blue"; - -/* Main leaflet map, extended by custom methods */ -var map: Map; - -/* Managers */ -var unitsManager: UnitsManager; -var weaponsManager: WeaponsManager; -var missionManager: MissionManager; - -/* UI Panels */ -var unitInfoPanel: UnitInfoPanel; -var connectionStatusPanel: ConnectionStatusPanel; -var serverStatusPanel: ServerStatusPanel; -var unitControlPanel: UnitControlPanel; -var mouseInfoPanel: MouseInfoPanel; -var logPanel: LogPanel; -var hotgroupPanel: HotgroupPanel; - -/* UI Toolbars */ -var primaryToolbar: PrimaryToolbar; -var commandModeToolbar: CommandModeToolbar; - -/* Popups */ -var infoPopup: Popup; +var app: OlympusApp; function setup() { - - /* Initialize base functionalitites */ - map = new Map('map-container'); - - unitsManager = new UnitsManager(); - weaponsManager = new WeaponsManager(); - missionManager = new MissionManager(); - - /* Panels */ - unitInfoPanel = new UnitInfoPanel("unit-info-panel"); - unitControlPanel = new UnitControlPanel("unit-control-panel"); - connectionStatusPanel = new ConnectionStatusPanel("connection-status-panel"); - serverStatusPanel = new ServerStatusPanel("server-status-panel"); - mouseInfoPanel = new MouseInfoPanel("mouse-info-panel"); - hotgroupPanel = new HotgroupPanel("hotgroup-panel"); - logPanel = new LogPanel("log-panel"); - - /* Toolbars */ - primaryToolbar = new PrimaryToolbar("primary-toolbar"); - commandModeToolbar = new CommandModeToolbar("command-mode-toolbar"); - - /* Popups */ - infoPopup = new Popup("info-popup"); - /* Load the config file from the app server*/ - getConfig((config: ConfigParameters) => readConfig(config)); + getConfig((config: ConfigurationOptions) => readConfig(config)); - /* - This is done like this for now as a way to make it work in the new and old world. - Over time/at some point, we'll need to start migrating the pre-existing code to an "app" format - */ - - const indexApp = new IndexApp({ - "featureSwitches": new FeatureSwitches(), - "map": map, - "panels": { - "connectionStatus": connectionStatusPanel, - "hotgroup": hotgroupPanel, - "infoPopup": infoPopup, - "log": logPanel, - "mouseInfo": mouseInfoPanel, - "serverStatus": serverStatusPanel, - "unitControl": unitControlPanel, - "unitInfo": unitInfoPanel - }, - "unitsManager": unitsManager - }); + app = new OlympusApp(); + app.start(); /* Setup event handlers */ - setupEvents( indexApp ); - - indexApp.start(); + setupEvents(app); +} +export function getApp() { + return app; } /** Loads the configuration parameters * * @param config ConfigParameters, defines the address and port of the Olympus REST server */ -function readConfig(config: ConfigParameters) { +function readConfig(config: ConfigurationOptions) { if (config && config.address != undefined && config.port != undefined) { const address = config.address; const port = config.port; @@ -120,8 +36,7 @@ function readConfig(config: ConfigParameters) { } } -function setupEvents( indexApp:OlympusApp ) { - +function setupEvents(app: OlympusApp) { /* Generic clicks */ document.addEventListener("click", (ev) => { if (ev instanceof MouseEvent && ev.target instanceof HTMLElement) { @@ -147,18 +62,15 @@ function setupEvents( indexApp:OlympusApp ) { } }); - - const shortcutManager = indexApp.getShortcutManager(); - - - shortcutManager.add( "toggleDemo", new ShortcutKeyboard({ - "callback": () => { - toggleDemoEnabled(); - }, - "code": "KeyT" - }) + const shortcutManager = app.getShortcutManager(); + shortcutManager.add("toggleDemo", new ShortcutKeyboard({ + "callback": () => { + toggleDemoEnabled(); + }, + "code": "KeyT" + }) ) - .add( "togglePause", new ShortcutKeyboard({ + .add("togglePause", new ShortcutKeyboard({ "altKey": false, "callback": () => { setPaused(!getPaused()); @@ -166,45 +78,43 @@ function setupEvents( indexApp:OlympusApp ) { "code": "Space", "ctrlKey": false }) - ); + ); - [ "KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown" ].forEach( code => { - shortcutManager.add( `pan${code}keydown`, new ShortcutKeyboard({ + ["KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].forEach(code => { + shortcutManager.add(`pan${code}keydown`, new ShortcutKeyboard({ "altKey": false, - "callback": ( ev:KeyboardEvent ) => { - getMap().handleMapPanning(ev); + "callback": (ev: KeyboardEvent) => { + getApp().getMap().handleMapPanning(ev); }, "code": code, "ctrlKey": false, "event": "keydown" })); }); - - [ "KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown" ].forEach( code => { - shortcutManager.add( `pan${code}keyup`, new ShortcutKeyboard({ - "callback": ( ev:KeyboardEvent ) => { - getMap().handleMapPanning(ev); + + ["KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].forEach(code => { + shortcutManager.add(`pan${code}keyup`, new ShortcutKeyboard({ + "callback": (ev: KeyboardEvent) => { + getApp().getMap().handleMapPanning(ev); }, "code": code })); }); - [ "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9" ].forEach( code => { - shortcutManager.add( `hotgroup${code}`, new ShortcutKeyboard({ - "callback": ( ev:KeyboardEvent ) => { + ["Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9"].forEach(code => { + shortcutManager.add(`hotgroup${code}`, new ShortcutKeyboard({ + "callback": (ev: KeyboardEvent) => { if (ev.ctrlKey && ev.shiftKey) - getUnitsManager().selectedUnitsAddToHotgroup(parseInt(ev.code.substring(5))); + getApp().getUnitsManager().selectedUnitsAddToHotgroup(parseInt(ev.code.substring(5))); else if (ev.ctrlKey && !ev.shiftKey) - getUnitsManager().selectedUnitsSetHotgroup(parseInt(ev.code.substring(5))); + getApp().getUnitsManager().selectedUnitsSetHotgroup(parseInt(ev.code.substring(5))); else - getUnitsManager().selectUnitsByHotgroup(parseInt(ev.code.substring(5))); + getApp().getUnitsManager().selectUnitsByHotgroup(parseInt(ev.code.substring(5))); }, "code": code })); }); - - // TODO: move from here in dedicated class document.addEventListener("closeDialog", (ev: CustomEventInit) => { ev.detail._element.closest(".ol-dialog").classList.add("hide"); @@ -222,7 +132,7 @@ function setupEvents( indexApp:OlympusApp ) { /* Start periodically requesting updates */ startUpdate(); - setLoginStatus("connecting"); + getApp().setLoginStatus("connecting"); }) /* Reload the page, used to mimic a restart of the app */ @@ -234,7 +144,7 @@ function setupEvents( indexApp:OlympusApp ) { document.querySelectorAll("[inject-svg]").forEach((el: Element) => { var img = el as HTMLImageElement; var isLoaded = img.complete; - if (isLoaded) + if (isLoaded) SVGInjector(img); else img.addEventListener("load", () => { @@ -243,90 +153,4 @@ function setupEvents( indexApp:OlympusApp ) { }) } -/* Getters */ -export function getMap() { - return map; -} - -export function getUnitsManager() { - return unitsManager; -} - -export function getWeaponsManager() { - return weaponsManager; -} - -export function getMissionHandler() { - return missionManager; -} - -export function getUnitInfoPanel() { - return unitInfoPanel; -} - -export function getUnitControlPanel() { - return unitControlPanel; -} - -export function getMouseInfoPanel() { - return mouseInfoPanel; -} - -export function getLogPanel() { - return logPanel; -} - -export function getConnectionStatusPanel() { - return connectionStatusPanel; -} - -export function getServerStatusPanel() { - return serverStatusPanel; -} - -export function getHotgroupPanel() { - return hotgroupPanel; -} - -export function getInfoPopup() { - return infoPopup; -} - -/** Set the active coalition, i.e. the currently controlled coalition. A game master can change the active coalition, while a commander is bound to his/her coalition - * - * @param newActiveCoalition - */ -export function setActiveCoalition(newActiveCoalition: string) { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER) - activeCoalition = newActiveCoalition; -} - -/** - * - * @returns The active coalition - */ -export function getActiveCoalition() { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER) - return activeCoalition; - else { - if (getMissionHandler().getCommandModeOptions().commandMode == BLUE_COMMANDER) - return "blue"; - else if (getMissionHandler().getCommandModeOptions().commandMode == RED_COMMANDER) - return "red"; - else - return "neutral"; - } -} - -/** Set a message in the login splash screen - * - * @param status The message to show in the login splash screen - */ -export function setLoginStatus(status: string) { - const el = document.querySelector("#login-status") as HTMLElement; - if (el) - el.dataset["status"] = status; -} - -window.onload = setup; - +window.onload = setup; \ No newline at end of file diff --git a/client/src/indexapp.ts b/client/src/indexapp.ts deleted file mode 100644 index 61c28b85..00000000 --- a/client/src/indexapp.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { FeatureSwitches } from "./features/featureswitches"; -import { IOlympusApp, OlympusApp } from "./olympusapp"; -import { ConnectionStatusPanel } from "./panels/connectionstatuspanel"; -import { HotgroupPanel } from "./panels/hotgrouppanel"; -import { LogPanel } from "./panels/logpanel"; -import { MouseInfoPanel } from "./panels/mouseinfopanel"; -import { Panel } from "./panels/panel"; -import { ServerStatusPanel } from "./panels/serverstatuspanel"; -import { UnitControlPanel } from "./panels/unitcontrolpanel"; -import { UnitInfoPanel } from "./panels/unitinfopanel"; -import { Popup } from "./popups/popup"; -import { ControlTips } from "./shortcut/controltips"; -import { UnitsManager } from "./unit/unitsmanager"; - -export interface IIndexApp extends IOlympusApp { - "featureSwitches": FeatureSwitches, - "panels": IIndexAppPanels, - "unitsManager": UnitsManager -} - -export interface IIndexAppPanels { - "connectionStatus": ConnectionStatusPanel, - "hotgroup": HotgroupPanel, - "infoPopup": Popup, - "log": LogPanel, - "mouseInfo": MouseInfoPanel, - "serverStatus": ServerStatusPanel, - "unitControl": UnitControlPanel, - "unitInfo": UnitInfoPanel -} - -export class IndexApp extends OlympusApp { - - constructor( config:IIndexApp ) { - - super( config ); - - // Panels - this.getPanelsManager() - .add( "connectionStatus", config.panels.connectionStatus ) - .add( "hotgroup", config.panels.hotgroup ) - .add( "log", config.panels.log ) - .add( "mouseInfo", config.panels.mouseInfo ) - .add( "serverStatus", config.panels.serverStatus ) - .add( "unitControl", config.panels.unitControl ) - .add( "unitInfo", config.panels.unitInfo ); - - // Popup - this.getPanelsManager().add( "unitPopup", config.panels.infoPopup ); - - // Retrofitting - Object.values( this.getPanelsManager().getAll() ).forEach( ( panel:Panel ) => { - panel.setOlympusApp( this ); - }); - } - - - start() { - - super.start(); - - new ControlTips( "control-tips-panel", this ); - - } - -} \ No newline at end of file diff --git a/client/src/map/coalitionarea/coalitionarea.ts b/client/src/map/coalitionarea/coalitionarea.ts index fb3682c6..e5e71ae0 100644 --- a/client/src/map/coalitionarea/coalitionarea.ts +++ b/client/src/map/coalitionarea/coalitionarea.ts @@ -1,5 +1,5 @@ import { DomUtil, LatLng, LatLngExpression, Map, Point, Polygon, PolylineOptions } from "leaflet"; -import { getMap, getMissionHandler, getUnitsManager } from "../.."; +import { getApp } from "../.."; import { CoalitionAreaHandle } from "./coalitionareahandle"; import { CoalitionAreaMiddleHandle } from "./coalitionareamiddlehandle"; import { BLUE_COMMANDER, RED_COMMANDER } from "../../constants/constants"; @@ -23,8 +23,8 @@ export class CoalitionArea extends Polygon { this.#setColors(); this.#registerCallbacks(); - if ([BLUE_COMMANDER, RED_COMMANDER].includes(getMissionHandler().getCommandModeOptions().commandMode)) - this.setCoalition(getMissionHandler().getCommandedCoalition()); + if ([BLUE_COMMANDER, RED_COMMANDER].includes(getApp().getMissionManager().getCommandModeOptions().commandMode)) + this.setCoalition(getApp().getMissionManager().getCommandedCoalition()); } setCoalition(coalition: string) { @@ -61,7 +61,7 @@ export class CoalitionArea extends Polygon { /* Remove areas with less than 2 vertexes */ if (latlngs.length <= 2) - getMap().deleteCoalitionArea(this); + getApp().getMap().deleteCoalitionArea(this); } getEditing() { @@ -89,7 +89,7 @@ export class CoalitionArea extends Polygon { onRemove(map: Map): this { super.onRemove(map); - this.#handles.concat(this.#middleHandles).forEach((handle: CoalitionAreaHandle | CoalitionAreaMiddleHandle) => handle.removeFrom(getMap())); + this.#handles.concat(this.#middleHandles).forEach((handle: CoalitionAreaHandle | CoalitionAreaMiddleHandle) => handle.removeFrom(getApp().getMap())); return this; } @@ -99,14 +99,14 @@ export class CoalitionArea extends Polygon { } #setHandles() { - this.#handles.forEach((handle: CoalitionAreaHandle) => handle.removeFrom(getMap())); + this.#handles.forEach((handle: CoalitionAreaHandle) => handle.removeFrom(getApp().getMap())); this.#handles = []; if (this.getSelected()) { var latlngs = this.getLatLngs()[0] as LatLng[]; latlngs.forEach((latlng: LatLng, idx: number) => { /* Add the polygon vertex handle (for moving the vertex) */ const handle = new CoalitionAreaHandle(latlng); - handle.addTo(getMap()); + handle.addTo(getApp().getMap()); handle.on("drag", (e: any) => { var latlngs = this.getLatLngs()[0] as LatLng[]; latlngs[idx] = e.target.getLatLng(); @@ -120,7 +120,7 @@ export class CoalitionArea extends Polygon { } #setMiddleHandles() { - this.#middleHandles.forEach((handle: CoalitionAreaMiddleHandle) => handle.removeFrom(getMap())); + this.#middleHandles.forEach((handle: CoalitionAreaMiddleHandle) => handle.removeFrom(getApp().getMap())); this.#middleHandles = []; var latlngs = this.getLatLngs()[0] as LatLng[]; if (this.getSelected() && latlngs.length >= 2) { @@ -128,13 +128,13 @@ export class CoalitionArea extends Polygon { latlngs.concat([latlngs[0]]).forEach((latlng: LatLng, idx: number) => { /* Add the polygon middle point handle (for adding new vertexes) */ if (lastLatLng != null) { - const handle1Point = getMap().latLngToLayerPoint(latlng); - const handle2Point = getMap().latLngToLayerPoint(lastLatLng); + const handle1Point = getApp().getMap().latLngToLayerPoint(latlng); + const handle2Point = getApp().getMap().latLngToLayerPoint(lastLatLng); const middlePoint = new Point((handle1Point.x + handle2Point.x) / 2, (handle1Point.y + handle2Point.y) / 2); - const middleLatLng = getMap().layerPointToLatLng(middlePoint); + const middleLatLng = getApp().getMap().layerPointToLatLng(middlePoint); const middleHandle = new CoalitionAreaMiddleHandle(middleLatLng); - middleHandle.addTo(getMap()); + middleHandle.addTo(getApp().getMap()); middleHandle.on("click", (e: any) => { this.#activeIndex = idx - 1; this.addTemporaryLatLng(middleLatLng); @@ -148,7 +148,7 @@ export class CoalitionArea extends Polygon { #registerCallbacks() { this.on("click", (e: any) => { - getMap().deselectAllCoalitionAreas(); + getApp().getMap().deselectAllCoalitionAreas(); if (!this.getSelected()) { this.setSelected(true); } @@ -156,7 +156,7 @@ export class CoalitionArea extends Polygon { this.on("contextmenu", (e: any) => { if (!this.getEditing()) { - getMap().deselectAllCoalitionAreas(); + getApp().getMap().deselectAllCoalitionAreas(); this.setSelected(true); } else diff --git a/client/src/map/map.ts b/client/src/map/map.ts index fd8745f4..6dc77a01 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -1,5 +1,5 @@ import * as L from "leaflet" -import { getInfoPopup, getMissionHandler, getUnitsManager } from ".."; +import { getApp } from ".."; import { BoxSelect } from "./boxselect"; import { MapContextMenu } from "../contextmenus/mapcontextmenu"; import { UnitContextMenu } from "../contextmenus/unitcontextmenu"; @@ -18,7 +18,7 @@ import { CoalitionArea } from "./coalitionarea/coalitionarea"; import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu"; import { DrawingCursor } from "./coalitionarea/drawingcursor"; import { AirbaseSpawnContextMenu } from "../contextmenus/airbasespawnmenu"; -import { OlympusApp } from "../olympusapp"; +import { Popup } from "../popups/popup"; L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect); @@ -71,8 +71,6 @@ export class Map extends L.Map { #visibilityOptions: { [key: string]: boolean } = {} #hiddenTypes: string[] = []; - #olympusApp!:OlympusApp; - /** * * @param ID - the ID of the HTML element which will contain the context menu @@ -126,17 +124,17 @@ export class Map extends L.Map { const el = ev.detail._element; el?.classList.toggle("off"); this.setHiddenType(ev.detail.coalition, !el?.classList.contains("off")); - Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); + Object.values(getApp().getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); }); document.addEventListener("toggleMarkerVisibility", (ev: CustomEventInit) => { const el = ev.detail._element; el?.classList.toggle("off"); ev.detail.types.forEach((type: string) => this.setHiddenType(type, !el?.classList.contains("off"))); - Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); + Object.values(getApp().getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); if (ev.detail.types.includes("airbase")) { - Object.values(getMissionHandler().getAirbases()).forEach((airbase: Airbase) => { + Object.values(getApp().getMissionManager().getAirbases()).forEach((airbase: Airbase) => { if (el?.classList.contains("off")) airbase.removeFrom(this); else @@ -163,7 +161,7 @@ export class Map extends L.Map { document.addEventListener("mapVisibilityOptionsChanged", () => { this.getContainer().toggleAttribute("data-hide-labels", !this.getVisibilityOptions()[SHOW_UNIT_LABELS]); - this.getOlympusApp().getControlTips().toggle( !this.getVisibilityOptions()[SHOW_CONTROL_TIPS] ); + // TODO this.getControlTips().toggle( !this.getVisibilityOptions()[SHOW_CONTROL_TIPS] ); }); /* Pan interval */ @@ -188,7 +186,7 @@ export class Map extends L.Map { this.#visibilityOptions[SHOW_UNIT_TARGETS] = true; this.#visibilityOptions[SHOW_UNIT_LABELS] = true; - // Manual until we use the OlympusApp approach + // Manual until we use the App approach this.#visibilityOptions[SHOW_CONTROL_TIPS] = JSON.parse( localStorage.getItem( "featureSwitches" ) || "{}" )?.controlTips || true; this.#mapVisibilityOptionsDropdown.setOptionsElements(Object.keys(this.#visibilityOptions).map((option: string) => { @@ -260,7 +258,7 @@ export class Map extends L.Map { else { this.#hiddenTypes.push(key); } - Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); + Object.values(getApp().getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); } getHiddenTypes() { @@ -367,7 +365,7 @@ export class Map extends L.Map { centerOnUnit(ID: number | null) { if (ID != null) { this.options.scrollWheelZoom = 'center'; - this.#centerUnit = getUnitsManager().getUnitByID(ID); + this.#centerUnit = getApp().getUnitsManager().getUnitByID(ID); } else { this.options.scrollWheelZoom = undefined; @@ -487,7 +485,7 @@ export class Map extends L.Map { } else { this.setState(IDLE); - getUnitsManager().deselectAllUnits(); + getApp().getUnitsManager().deselectAllUnits(); } } } @@ -525,9 +523,9 @@ export class Map extends L.Map { } else if (this.#state === MOVE_UNIT) { if (!e.originalEvent.ctrlKey) { - getUnitsManager().selectedUnitsClearDestinations(); + getApp().getUnitsManager().selectedUnitsClearDestinations(); } - getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation) + getApp().getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation) this.#destinationGroupRotation = 0; this.#destinationRotationCenter = null; @@ -550,7 +548,7 @@ export class Map extends L.Map { this.#leftClickTimer = window.setTimeout(() => { this.#preventLeftClick = false; }, 200); - getUnitsManager().selectFromBounds(e.selectionBounds); + getApp().getUnitsManager().selectFromBounds(e.selectionBounds); this.#updateCursor(); } @@ -575,25 +573,25 @@ export class Map extends L.Map { this.#longPressHandled = true; var options: { [key: string]: { text: string, tooltip: string } } = {}; - const selectedUnits = getUnitsManager().getSelectedUnits(); - const selectedUnitTypes = getUnitsManager().getSelectedUnitsCategories(); + const selectedUnits = getApp().getUnitsManager().getSelectedUnits(); + const selectedUnitTypes = getApp().getUnitsManager().getSelectedUnitsCategories(); if (selectedUnitTypes.length === 1 && ["Aircraft", "Helicopter"].includes(selectedUnitTypes[0])) { if (selectedUnits.every((unit: Unit) => { return unit.canFulfillRole(["CAS", "Strike"]) })) { options["bomb"] = { text: "Precision bombing", tooltip: "Precision bombing of a specific point" }; options["carpet-bomb"] = { text: "Carpet bombing", tooltip: "Carpet bombing close to a point" }; } else { - getInfoPopup().setText(`Selected units can not perform point actions.`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Selected units can not perform point actions.`); } } else if (selectedUnitTypes.length === 1 && ["GroundUnit", "NavyUnit"].includes(selectedUnitTypes[0])) { if (selectedUnits.every((unit: Unit) => { return ["Gun Artillery", "Rocket Artillery", "Infantry", "IFV", "Tank", "Cruiser", "Destroyer", "Frigate"].includes(unit.getType()) })) options["fire-at-area"] = { text: "Fire at area", tooltip: "Fire at a large area" }; else - getInfoPopup().setText(`Selected units can not perform point actions.`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Selected units can not perform point actions.`); } else if(selectedUnitTypes.length > 1) { - getInfoPopup().setText(`Multiple unit types selected, no common actions available.`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Multiple unit types selected, no common actions available.`); } if (Object.keys(options).length > 0) { @@ -601,16 +599,16 @@ export class Map extends L.Map { this.getUnitContextMenu().setOptions(options, (option: string) => { this.hideUnitContextMenu(); if (option === "bomb") { - getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE); - getUnitsManager().selectedUnitsBombPoint(this.getMouseCoordinates()); + getApp().getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE); + getApp().getUnitsManager().selectedUnitsBombPoint(this.getMouseCoordinates()); } else if (option === "carpet-bomb") { - getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE); - getUnitsManager().selectedUnitsCarpetBomb(this.getMouseCoordinates()); + getApp().getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE); + getApp().getUnitsManager().selectedUnitsCarpetBomb(this.getMouseCoordinates()); } else if (option === "fire-at-area") { - getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE); - getUnitsManager().selectedUnitsFireAtArea(this.getMouseCoordinates()); + getApp().getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE); + getApp().getUnitsManager().selectedUnitsFireAtArea(this.getMouseCoordinates()); } }); } @@ -703,7 +701,7 @@ export class Map extends L.Map { #showDestinationCursors() { const singleCursor = !this.#shiftKey; - const selectedUnitsCount = getUnitsManager().getSelectedUnits({ excludeHumans: false, onlyOnePerGroup: true }).length; + const selectedUnitsCount = getApp().getUnitsManager().getSelectedUnits({ excludeHumans: false, onlyOnePerGroup: true }).length; if (selectedUnitsCount > 0) { if (singleCursor && this.#destinationPreviewCursors.length != 1) { this.#hideDestinationCursors(); @@ -733,7 +731,7 @@ export class Map extends L.Map { if (this.#destinationPreviewCursors.length == 1) this.#destinationPreviewCursors[0].setLatLng(this.getMouseCoordinates()); else { - Object.values(getUnitsManager().selectedUnitsComputeGroupDestination(groupLatLng, this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => { + Object.values(getApp().getUnitsManager().selectedUnitsComputeGroupDestination(groupLatLng, this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => { if (idx < this.#destinationPreviewCursors.length) this.#destinationPreviewCursors[idx].setLatLng(this.#shiftKey ? latlng : this.getMouseCoordinates()); }) @@ -803,15 +801,5 @@ export class Map extends L.Map { this.#visibilityOptions[option] = ev.currentTarget.checked; document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged")); } - - getOlympusApp() { - return this.#olympusApp; - } - - setOlympusApp( olympusApp:OlympusApp ) { - - this.#olympusApp = olympusApp; - - } } diff --git a/client/src/map/markers/smokemarker.ts b/client/src/map/markers/smokemarker.ts index 39cf9f82..d7ec80cf 100644 --- a/client/src/map/markers/smokemarker.ts +++ b/client/src/map/markers/smokemarker.ts @@ -1,7 +1,7 @@ import { DivIcon, LatLngExpression, MarkerOptions } from "leaflet"; import { CustomMarker } from "./custommarker"; import { SVGInjector } from "@tanem/svg-injector"; -import { getMap } from "../.."; +import { getApp } from "../.."; export class SmokeMarker extends CustomMarker { #color: string; @@ -10,7 +10,7 @@ export class SmokeMarker extends CustomMarker { super(latlng, options); this.setZIndexOffset(9999); this.#color = color; - window.setTimeout(() => { this.removeFrom(getMap()); }, 300000) /* Remove the smoke after 5 minutes */ + window.setTimeout(() => { this.removeFrom(getApp().getMap()); }, 300000) /* Remove the smoke after 5 minutes */ } createIcon() { diff --git a/client/src/map/markers/temporaryunitmarker.ts b/client/src/map/markers/temporaryunitmarker.ts index 0f8e55ee..1d480a13 100644 --- a/client/src/map/markers/temporaryunitmarker.ts +++ b/client/src/map/markers/temporaryunitmarker.ts @@ -3,7 +3,7 @@ import { DivIcon, LatLng } from "leaflet"; import { SVGInjector } from "@tanem/svg-injector"; import { getMarkerCategoryByName, getUnitDatabaseByCategory } from "../../other/utils"; import { isCommandExecuted } from "../../server/server"; -import { getMap } from "../.."; +import { getApp } from "../.."; export class TemporaryUnitMarker extends CustomMarker { #name: string; @@ -27,7 +27,7 @@ export class TemporaryUnitMarker extends CustomMarker { if (this.#commandHash !== undefined) { isCommandExecuted((res: any) => { if (res.commandExecuted) { - this.removeFrom(getMap()); + this.removeFrom(getApp().getMap()); window.clearInterval(this.#timer); } }, this.#commandHash) diff --git a/client/src/mission/airbase.ts b/client/src/mission/airbase.ts index 6e85a997..dc74fee5 100644 --- a/client/src/mission/airbase.ts +++ b/client/src/mission/airbase.ts @@ -2,30 +2,6 @@ import { DivIcon } from 'leaflet'; import { CustomMarker } from '../map/markers/custommarker'; import { SVGInjector } from '@tanem/svg-injector'; -export interface AirbaseOptions { - name: string, - position: L.LatLng -} - - -export interface AirbaseChartData { - elevation: string, - ICAO: string, - TACAN: string, - runways: AirbaseChartRunwayData[] -} - -export interface AirbaseChartRunwayData { - "headings": AirbaseChartRunwayHeadingData[], - "length": string -} - -export interface AirbaseChartRunwayHeadingData { - [index: string]: { - "magHeading": string, - "ILS": string - } -} export class Airbase extends CustomMarker { #name: string = ""; diff --git a/client/src/mission/missionmanager.ts b/client/src/mission/missionmanager.ts index ffe298ee..1b6f2c85 100644 --- a/client/src/mission/missionmanager.ts +++ b/client/src/mission/missionmanager.ts @@ -1,5 +1,5 @@ import { LatLng } from "leaflet"; -import { getInfoPopup, getMap } from ".."; +import { getApp } from ".."; import { Airbase } from "./airbase"; import { Bullseye } from "./bullseye"; import { BLUE_COMMANDER, GAME_MASTER, NONE, RED_COMMANDER } from "../constants/constants"; @@ -10,6 +10,7 @@ import { createCheckboxOption, getCheckboxOptions } from "../other/utils"; import { aircraftDatabase } from "../unit/databases/aircraftdatabase"; import { helicopterDatabase } from "../unit/databases/helicopterdatabase"; import { navyUnitDatabase } from "../unit/databases/navyunitdatabase"; +import { Popup } from "../popups/popup"; /** The MissionManager */ export class MissionManager { @@ -38,7 +39,7 @@ export class MissionManager { for (let idx in data.bullseyes) { const bullseye = data.bullseyes[idx]; if (!(idx in this.#bullseyes)) - this.#bullseyes[idx] = new Bullseye([0, 0]).addTo(getMap()); + this.#bullseyes[idx] = new Bullseye([0, 0]).addTo(getApp().getMap()); if (bullseye.latitude && bullseye.longitude && bullseye.coalition) { this.#bullseyes[idx].setLatLng(new LatLng(bullseye.latitude, bullseye.longitude)); @@ -54,7 +55,7 @@ export class MissionManager { this.#airbases[airbase.callsign] = new Airbase({ position: new LatLng(airbase.latitude, airbase.longitude), name: airbase.callsign - }).addTo(getMap()); + }).addTo(getApp().getMap()); this.#airbases[airbase.callsign].on('contextmenu', (e) => this.#onAirbaseClick(e)); this.#loadAirbaseChartData(airbase.callsign); } @@ -72,8 +73,8 @@ export class MissionManager { /* Set the mission theatre */ if (data.mission.theatre != this.#theatre) { this.#theatre = data.mission.theatre; - getMap().setTheatre(this.#theatre); - getInfoPopup().setText("Map set to " + this.#theatre); + getApp().getMap().setTheatre(this.#theatre); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Map set to " + this.#theatre); } /* Set the date and time data */ @@ -232,7 +233,7 @@ export class MissionManager { } #onAirbaseClick(e: any) { - getMap().showAirbaseContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng, e.sourceTarget); + getApp().getMap().showAirbaseContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng, e.sourceTarget); } #loadAirbaseChartData(callsign: string) { diff --git a/client/src/olympusapp.ts b/client/src/olympusapp.ts deleted file mode 100644 index bf99cfe7..00000000 --- a/client/src/olympusapp.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { FeatureSwitches } from "./features/featureswitches"; -import { Map } from "./map/map"; -import { PanelsManager } from "./panels/panelsmanager"; -import { ControlTips } from "./shortcut/controltips"; -import { ShortcutManager } from "./shortcut/shortcutmanager"; -import { UnitsManager } from "./unit/unitsmanager"; - - -export interface IOlympusApp { - featureSwitches: FeatureSwitches; - map: Map, - unitsManager: UnitsManager; -} - -export abstract class OlympusApp { - - #controlTips: ControlTips; - #featureSwitches: FeatureSwitches; - #map: Map; - #panelsManager: PanelsManager = new PanelsManager( this ); - #shortcutManager: ShortcutManager = new ShortcutManager( this ); - #unitsManager: UnitsManager; - - constructor( config:IOlympusApp ) { - - this.#controlTips = new ControlTips( "control-tips-panel", this ); - this.#featureSwitches = config.featureSwitches; - this.#map = config.map; - this.#unitsManager = config.unitsManager; - - this.getMap().setOlympusApp( this ); - - } - - getControlTips() { - return this.#controlTips; - } - - getFeatureSwitches() { - return this.#featureSwitches; - } - - getMap() { - return this.#map; - } - - getPanelsManager() { - return this.#panelsManager; - } - - getShortcutManager() { - return this.#shortcutManager; - } - - getUnitsManager() { - return this.#unitsManager; - } - - getWeaponsManager() { - return this.getWeaponsManager; - } - - start() { - - // Start the app - - - } - -} \ No newline at end of file diff --git a/client/src/other/eventsmanager.ts b/client/src/other/eventsmanager.ts index 6bdc504c..9173b2b1 100644 --- a/client/src/other/eventsmanager.ts +++ b/client/src/other/eventsmanager.ts @@ -1,10 +1,7 @@ -import { OlympusApp } from "../olympusapp"; import { Manager } from "./manager"; export abstract class EventsManager extends Manager { - - constructor( olympusApp:OlympusApp ) { - super( olympusApp ); + constructor() { + super(); } - } \ No newline at end of file diff --git a/client/src/other/manager.ts b/client/src/other/manager.ts index 92bfd949..6ac10ea8 100644 --- a/client/src/other/manager.ts +++ b/client/src/other/manager.ts @@ -1,54 +1,33 @@ -import { OlympusApp } from "../olympusapp"; - -export interface IManager { - add:CallableFunction; -} - -export abstract class Manager { - - #items: {[key:string]: any } = {}; - #olympusApp: OlympusApp; - - constructor( olympusApp:OlympusApp ) { - - this.#olympusApp = olympusApp; +export class Manager { + #items: { [key: string]: any } = {}; + constructor() { } - add( name:string, item:any ) { - - const regex = new RegExp( "^[a-z][a-z0-9]{2,}$", "i" ); - - if ( regex.test( name ) === false ) { - throw new Error( `Item name "${name}" does not match regex: ${regex.toString()}.` ); + add(name: string, item: any) { + const regex = new RegExp("^[a-z][a-z0-9]{2,}$", "i"); + if (regex.test(name) === false) { + throw new Error(`Item name "${name}" does not match regex: ${regex.toString()}.`); } - if ( this.#items.hasOwnProperty( name ) ) { - throw new Error( `Item with name "${name}" already exists.` ); + if (this.#items.hasOwnProperty(name)) { + throw new Error(`Item with name "${name}" already exists.`); } - this.#items[ name ] = item; - + this.#items[name] = item; return this; - } - get( name:string ) { - - if ( this.#items.hasOwnProperty( name ) ) { - return this.#items[ name ]; + get(name: string) { + if (this.#items.hasOwnProperty(name)) { + return this.#items[name]; } else { return false; } - } getAll() { return this.#items; } - getOlympusApp() { - return this.#olympusApp; - } - } \ No newline at end of file diff --git a/client/src/other/utils.ts b/client/src/other/utils.ts index 4d46d202..78d025e2 100644 --- a/client/src/other/utils.ts +++ b/client/src/other/utils.ts @@ -7,7 +7,6 @@ import { groundUnitDatabase } from "../unit/databases/groundunitdatabase"; import { Buffer } from "buffer"; import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants"; import { Dropdown } from "../controls/dropdown"; -import { UnitBlueprint } from "../@types/unitdatabase"; import { navyUnitDatabase } from "../unit/databases/navyunitdatabase"; export function bearing(lat1: number, lon1: number, lat2: number, lon2: number) { diff --git a/client/src/panels/hotgrouppanel.ts b/client/src/panels/hotgrouppanel.ts index 94643fa0..007e5b92 100644 --- a/client/src/panels/hotgrouppanel.ts +++ b/client/src/panels/hotgrouppanel.ts @@ -1,4 +1,4 @@ -import { getUnitsManager } from ".."; +import { getApp } from ".."; import { Unit } from "../unit/unit"; import { Panel } from "./panel"; @@ -15,7 +15,7 @@ export class HotgroupPanel extends Panel { refreshHotgroups() { for (let hotgroup = 1; hotgroup <= 9; hotgroup++){ this.removeHotgroup(hotgroup); - if (getUnitsManager().getUnitsByHotgroup(hotgroup).length > 0) + if (getApp().getUnitsManager().getUnitsByHotgroup(hotgroup).length > 0) this.addHotgroup(hotgroup); } @@ -32,7 +32,7 @@ export class HotgroupPanel extends Panel { // Hotgroup unit count var countDiv = document.createElement("div"); - countDiv.innerText = `x${getUnitsManager().getUnitsByHotgroup(hotgroup).length}`; + countDiv.innerText = `x${getApp().getUnitsManager().getUnitsByHotgroup(hotgroup).length}`; var el = document.createElement("div"); el.appendChild(hotgroupDiv); @@ -43,15 +43,15 @@ export class HotgroupPanel extends Panel { this.getElement().appendChild(el); el.addEventListener("click", () => { - getUnitsManager().selectUnitsByHotgroup(hotgroup); + getApp().getUnitsManager().selectUnitsByHotgroup(hotgroup); }); el.addEventListener("mouseover", () => { - getUnitsManager().getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHighlighted(true)); + getApp().getUnitsManager().getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHighlighted(true)); }); el.addEventListener("mouseout", () => { - getUnitsManager().getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHighlighted(false)); + getApp().getUnitsManager().getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHighlighted(false)); }); } diff --git a/client/src/panels/logpanel.ts b/client/src/panels/logpanel.ts index a0a38b7c..f41017f2 100644 --- a/client/src/panels/logpanel.ts +++ b/client/src/panels/logpanel.ts @@ -1,4 +1,5 @@ -import { getMouseInfoPanel } from ".."; +import { getApp } from ".."; +import { MouseInfoPanel } from "./mouseinfopanel"; import { Panel } from "./panel"; export class LogPanel extends Panel { @@ -37,7 +38,7 @@ export class LogPanel extends Panel { }); - const mouseInfoPanel = getMouseInfoPanel(); + const mouseInfoPanel = getApp().getPanelsManager().get("mouseInfo") as MouseInfoPanel; new ResizeObserver(() => this.#calculateHeight()).observe(mouseInfoPanel.getElement()) } @@ -89,7 +90,7 @@ export class LogPanel extends Panel { } #calculateHeight() { - const mouseInfoPanel = getMouseInfoPanel(); + const mouseInfoPanel = getApp().getPanelsManager().get("mouseInfo"); if (this.#open) this.getElement().style.height = `${mouseInfoPanel.getElement().offsetTop - this.getElement().offsetTop - 10}px`; else diff --git a/client/src/panels/mouseinfopanel.ts b/client/src/panels/mouseinfopanel.ts index e5561c68..90ba077c 100644 --- a/client/src/panels/mouseinfopanel.ts +++ b/client/src/panels/mouseinfopanel.ts @@ -1,5 +1,5 @@ import { Icon, LatLng, Marker, Polyline } from "leaflet"; -import { getMap, getMissionHandler, getUnitsManager } from ".."; +import { getApp } from ".."; import { distance, bearing, zeroAppend, mToNm, nmToFt } from "../other/utils"; import { Unit } from "../unit/unit"; import { Panel } from "./panel"; @@ -22,19 +22,19 @@ export class MouseInfoPanel extends Panel { this.#measureBox.classList.add("ol-measure-box", "hide"); document.body.appendChild(this.#measureBox); - getMap()?.on("click", (e: any) => this.#onMapClick(e)); - getMap()?.on('zoom', (e: any) => this.#onZoom(e)); - getMap()?.on('mousemove', (e: any) => this.#onMouseMove(e)); + getApp().getMap()?.on("click", (e: any) => this.#onMapClick(e)); + getApp().getMap()?.on('zoom', (e: any) => this.#onZoom(e)); + getApp().getMap()?.on('mousemove', (e: any) => this.#onMouseMove(e)); document.addEventListener('unitsSelection', (e: CustomEvent) => this.#update()); document.addEventListener('clearSelection', () => this.#update()); } #update() { - const mousePosition = getMap().getMouseCoordinates(); + const mousePosition = getApp().getMap().getMouseCoordinates(); var selectedUnitPosition = null; - var selectedUnits = getUnitsManager().getSelectedUnits(); + var selectedUnits = getApp().getUnitsManager().getSelectedUnits(); if (selectedUnits && selectedUnits.length == 1) selectedUnitPosition = new LatLng(selectedUnits[0].getPosition().lat, selectedUnits[0].getPosition().lng); @@ -44,7 +44,7 @@ export class MouseInfoPanel extends Panel { this.getElement().querySelector(`#measuring-tool`)?.classList.toggle("hide", this.#measurePoint === null && selectedUnitPosition === null); - var bullseyes = getMissionHandler().getBullseyes(); + var bullseyes = getApp().getMissionManager().getBullseyes(); for (let idx in bullseyes) this.#drawMeasure(null, `bullseye-${idx}`, bullseyes[idx].getLatLng(), mousePosition); @@ -61,19 +61,19 @@ export class MouseInfoPanel extends Panel { this.#measureBox.classList.toggle("hide", false); this.#measurePoint = e.latlng; this.#measureMarker.setLatLng(e.latlng); - this.#measureMarker.addTo(getMap()); - if (!getMap().hasLayer(this.#measureLine)) - this.#measureLine.addTo(getMap()); + this.#measureMarker.addTo(getApp().getMap()); + if (!getApp().getMap().hasLayer(this.#measureLine)) + this.#measureLine.addTo(getApp().getMap()); } else { this.#measureBox.classList.toggle("hide", true); this.#measurePoint = null; - if (getMap().hasLayer(this.#measureMarker)) - getMap().removeLayer(this.#measureMarker); + if (getApp().getMap().hasLayer(this.#measureMarker)) + getApp().getMap().removeLayer(this.#measureMarker); this.#measureLine.setLatLngs([]); - if (getMap().hasLayer(this.#measureLine)) - getMap().removeLayer(this.#measureLine); + if (getApp().getMap().hasLayer(this.#measureLine)) + getApp().getMap().removeLayer(this.#measureLine); } } @@ -81,15 +81,15 @@ export class MouseInfoPanel extends Panel { } #drawMeasureLine() { - var mouseLatLng = getMap().containerPointToLatLng(getMap().getMousePosition()); + var mouseLatLng = getApp().getMap().containerPointToLatLng(getApp().getMap().getMousePosition()); if (this.#measurePoint != null) { var points = [this.#measurePoint, mouseLatLng]; this.#measureLine.setLatLngs(points); var dist = distance(this.#measurePoint.lat, this.#measurePoint.lng, mouseLatLng.lat, mouseLatLng.lng); var bear = bearing(this.#measurePoint.lat, this.#measurePoint.lng, mouseLatLng.lat, mouseLatLng.lng); - var startXY = getMap().latLngToContainerPoint(this.#measurePoint); - var dx = (getMap().getMousePosition().x - startXY.x); - var dy = (getMap().getMousePosition().y - startXY.y); + var startXY = getApp().getMap().latLngToContainerPoint(this.#measurePoint); + var dx = (getApp().getMap().getMousePosition().x - startXY.x); + var dy = (getApp().getMap().getMousePosition().y - startXY.y); var angle = Math.atan2(dy, dx); if (angle > Math.PI / 2) @@ -108,8 +108,8 @@ export class MouseInfoPanel extends Panel { let data = [`${bng}°`, `${str} ${unit}`]; this.#measureBox.innerText = data.join(" / "); - this.#measureBox.style.left = (getMap().getMousePosition().x + startXY.x) / 2 - this.#measureBox.offsetWidth / 2 + "px"; - this.#measureBox.style.top = (getMap().getMousePosition().y + startXY.y) / 2 - this.#measureBox.offsetHeight / 2 + "px"; + this.#measureBox.style.left = (getApp().getMap().getMousePosition().x + startXY.x) / 2 - this.#measureBox.offsetWidth / 2 + "px"; + this.#measureBox.style.top = (getApp().getMap().getMousePosition().y + startXY.y) / 2 - this.#measureBox.offsetHeight / 2 + "px"; this.#measureBox.style.rotate = angle + "rad"; } } diff --git a/client/src/panels/panel.ts b/client/src/panels/panel.ts index 8899ac7e..a315ea16 100644 --- a/client/src/panels/panel.ts +++ b/client/src/panels/panel.ts @@ -1,35 +1,31 @@ -import { OlympusApp } from "../olympusapp"; import { PanelEventsManager } from "./paneleventsmanager"; export abstract class Panel { #element: HTMLElement #eventsManager!: PanelEventsManager; - #olympusApp!: OlympusApp; - constructor(ID: string, olympusApp?:OlympusApp ) { + constructor(ID: string) { this.#element = document.getElementById(ID); - - if ( olympusApp ) { - this.setOlympusApp( olympusApp ); - } + + this.#eventsManager = new PanelEventsManager(); } show() { this.#element.classList.toggle("hide", false); - this.getEventsManager()?.trigger( "show", {} ); + this.getEventsManager()?.trigger("show", {}); } hide() { this.#element.classList.toggle("hide", true); - this.getEventsManager()?.trigger( "hide", {} ); + this.getEventsManager()?.trigger("hide", {}); } toggle() { // Simple way to track if currently visible if (this.getVisible()) this.hide(); - else + else this.show(); } @@ -37,21 +33,11 @@ export abstract class Panel { return this.#element; } - getVisible(){ - return (!this.getElement().classList.contains( "hide" ) ); + getVisible() { + return (!this.getElement().classList.contains("hide")); } getEventsManager() { return this.#eventsManager; } - - getOlympusApp() { - return this.#olympusApp; - } - - setOlympusApp( olympusApp:OlympusApp ) { - this.#olympusApp = olympusApp; - this.#eventsManager = new PanelEventsManager( this.getOlympusApp() ); - } - } \ No newline at end of file diff --git a/client/src/panels/paneleventsmanager.ts b/client/src/panels/paneleventsmanager.ts index d98cf10a..906f169b 100644 --- a/client/src/panels/paneleventsmanager.ts +++ b/client/src/panels/paneleventsmanager.ts @@ -1,50 +1,29 @@ -import { OlympusApp } from "../olympusapp"; import { EventsManager } from "../other/eventsmanager"; -interface IListener { - callback: CallableFunction; - name?: string -} - export class PanelEventsManager extends EventsManager { - - constructor( olympusApp:OlympusApp ) { + constructor() { + super(); - super( olympusApp ); - - this.add( "hide", [] ); - this.add( "show", [] ); - + this.add("hide", []); + this.add("show", []); } - on( eventName:string, listener:IListener ) { - - const event = this.get( eventName ); - - if ( !event ) { - throw new Error( `Event name "${eventName}" is not valid.` ); + on(eventName: string, listener: Listener) { + const event = this.get(eventName); + if (!event) { + throw new Error(`Event name "${eventName}" is not valid.`); } - - this.get( eventName ).push({ + this.get(eventName).push({ "callback": listener.callback }); - } - trigger( eventName:string, contextData:object ) { - - const listeners = this.get( eventName ); - - if ( listeners ) { - - listeners.forEach( ( listener:IListener ) => { - - listener.callback( contextData ); - + trigger(eventName: string, contextData: object) { + const listeners = this.get(eventName); + if (listeners) { + listeners.forEach((listener: Listener) => { + listener.callback(contextData); }); - } - } - } \ No newline at end of file diff --git a/client/src/panels/panelsmanager.ts b/client/src/panels/panelsmanager.ts deleted file mode 100644 index 9153753b..00000000 --- a/client/src/panels/panelsmanager.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { OlympusApp } from "../olympusapp"; -import { Manager } from "../other/manager"; -import { Panel } from "./panel"; - -export class PanelsManager extends Manager { - - #panels: { [key:string]: Panel } = {} - - constructor( olympusApp:OlympusApp ) { - super( olympusApp ); - } - - get( name:string ): Panel { - return super.get( name ); - } - -} \ No newline at end of file diff --git a/client/src/panels/unitcontrolpanel.ts b/client/src/panels/unitcontrolpanel.ts index e8631f1a..24f441b8 100644 --- a/client/src/panels/unitcontrolpanel.ts +++ b/client/src/panels/unitcontrolpanel.ts @@ -1,5 +1,5 @@ import { SVGInjector } from "@tanem/svg-injector"; -import { getUnitsManager } from ".."; +import { getApp } from ".."; import { Dropdown } from "../controls/dropdown"; import { Slider } from "../controls/slider"; import { aircraftDatabase } from "../unit/databases/aircraftdatabase"; @@ -8,7 +8,6 @@ import { Panel } from "./panel"; import { Switch } from "../controls/switch"; import { ROEDescriptions, ROEs, altitudeIncrements, emissionsCountermeasures, emissionsCountermeasuresDescriptions, maxAltitudeValues, maxSpeedValues, minAltitudeValues, minSpeedValues, reactionsToThreat, reactionsToThreatDescriptions, speedIncrements } from "../constants/constants"; import { ftToM, knotsToMs, mToFt, msToKnots } from "../other/utils"; -import { GeneralSettings, Radio, TACAN } from "../@types/unit"; export class UnitControlPanel extends Panel { #altitudeSlider: Slider; @@ -33,24 +32,24 @@ export class UnitControlPanel extends Panel { super(ID); /* Unit control sliders */ - this.#altitudeSlider = new Slider("altitude-slider", 0, 100, "ft", (value: number) => { getUnitsManager().selectedUnitsSetAltitude(ftToM(value)); }); - this.#altitudeTypeSwitch = new Switch("altitude-type-switch", (value: boolean) => { getUnitsManager().selectedUnitsSetAltitudeType(value? "ASL": "AGL"); }); + this.#altitudeSlider = new Slider("altitude-slider", 0, 100, "ft", (value: number) => { getApp().getUnitsManager().selectedUnitsSetAltitude(ftToM(value)); }); + this.#altitudeTypeSwitch = new Switch("altitude-type-switch", (value: boolean) => { getApp().getUnitsManager().selectedUnitsSetAltitudeType(value? "ASL": "AGL"); }); - this.#speedSlider = new Slider("speed-slider", 0, 100, "kts", (value: number) => { getUnitsManager().selectedUnitsSetSpeed(knotsToMs(value)); }); - this.#speedTypeSwitch = new Switch("speed-type-switch", (value: boolean) => { getUnitsManager().selectedUnitsSetSpeedType(value? "CAS": "GS"); }); + this.#speedSlider = new Slider("speed-slider", 0, 100, "kts", (value: number) => { getApp().getUnitsManager().selectedUnitsSetSpeed(knotsToMs(value)); }); + this.#speedTypeSwitch = new Switch("speed-type-switch", (value: boolean) => { getApp().getUnitsManager().selectedUnitsSetSpeedType(value? "CAS": "GS"); }); /* Option buttons */ // Reversing the ROEs so that the least "aggressive" option is always on the left this.#optionButtons["ROE"] = ROEs.slice(0).reverse().map((option: string, index: number) => { - return this.#createOptionButton(option, `roe/${option.toLowerCase()}.svg`, ROEDescriptions.slice(0).reverse()[index], () => { getUnitsManager().selectedUnitsSetROE(option); }); + return this.#createOptionButton(option, `roe/${option.toLowerCase()}.svg`, ROEDescriptions.slice(0).reverse()[index], () => { getApp().getUnitsManager().selectedUnitsSetROE(option); }); }).filter((button: HTMLButtonElement, index: number) => {return ROEs[index] !== "";}); this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string, index: number) => { - return this.#createOptionButton(option, `threat/${option.toLowerCase()}.svg`, reactionsToThreatDescriptions[index],() => { getUnitsManager().selectedUnitsSetReactionToThreat(option); }); + return this.#createOptionButton(option, `threat/${option.toLowerCase()}.svg`, reactionsToThreatDescriptions[index],() => { getApp().getUnitsManager().selectedUnitsSetReactionToThreat(option); }); }); this.#optionButtons["emissionsCountermeasures"] = emissionsCountermeasures.map((option: string, index: number) => { - return this.#createOptionButton(option, `emissions/${option.toLowerCase()}.svg`, emissionsCountermeasuresDescriptions[index],() => { getUnitsManager().selectedUnitsSetEmissionsCountermeasures(option); }); + return this.#createOptionButton(option, `emissions/${option.toLowerCase()}.svg`, emissionsCountermeasuresDescriptions[index],() => { getApp().getUnitsManager().selectedUnitsSetEmissionsCountermeasures(option); }); }); this.getElement().querySelector("#roe-buttons-container")?.append(...this.#optionButtons["ROE"]); @@ -59,12 +58,12 @@ export class UnitControlPanel extends Panel { /* On off switch */ this.#onOffSwitch = new Switch("on-off-switch", (value: boolean) => { - getUnitsManager().selectedUnitsSetOnOff(value); + getApp().getUnitsManager().selectedUnitsSetOnOff(value); }); /* Follow roads switch */ this.#followRoadsSwitch = new Switch("follow-roads-switch", (value: boolean) => { - getUnitsManager().selectedUnitsSetFollowRoads(value); + getApp().getUnitsManager().selectedUnitsSetFollowRoads(value); }); /* Advanced settings dialog */ @@ -84,7 +83,7 @@ export class UnitControlPanel extends Panel { document.addEventListener("clearSelection", () => { this.hide() }); document.addEventListener("applyAdvancedSettings", () => {this.#applyAdvancedSettings();}) document.addEventListener("showAdvancedSettings", () => { - this.#updateAdvancedSettingsDialog(getUnitsManager().getSelectedUnits()); + this.#updateAdvancedSettingsDialog(getApp().getUnitsManager().getSelectedUnits()); this.#advancedSettingsDialog.classList.remove("hide"); }); @@ -108,8 +107,8 @@ export class UnitControlPanel extends Panel { } addButtons() { - this.#units = getUnitsManager().getSelectedUnits(); - this.#selectedUnitsTypes = getUnitsManager().getSelectedUnitsCategories(); + this.#units = getApp().getUnitsManager().getSelectedUnits(); + this.#selectedUnitsTypes = getApp().getUnitsManager().getSelectedUnitsCategories(); if (this.#units.length < 20) { this.getElement().querySelector("#selected-units-container")?.replaceChildren(...this.#units.map((unit: Unit, index: number) => { @@ -127,12 +126,12 @@ export class UnitControlPanel extends Panel { button.addEventListener("click", ( ev:MouseEventInit ) => { // Ctrl-click deselection if ( ev.ctrlKey === true && ev.shiftKey === false && ev.altKey === false ) { - getUnitsManager().deselectUnit( unit.ID ); + getApp().getUnitsManager().deselectUnit( unit.ID ); button.remove(); // Deselect all } else { - getUnitsManager().deselectAllUnits(); - getUnitsManager().selectUnit(unit.ID, true); + getApp().getUnitsManager().deselectAllUnits(); + getApp().getUnitsManager().selectUnit(unit.ID, true); } }); return (button); @@ -161,12 +160,12 @@ export class UnitControlPanel extends Panel { if (this.#selectedUnitsTypes.length == 1) { /* Flight controls */ - var desiredAltitude = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitude()}); - var desiredAltitudeType = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitudeType()}); - var desiredSpeed = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeed()}); - var desiredSpeedType = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeedType()}); - var onOff = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getOnOff()}); - var followRoads = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getFollowRoads()}); + var desiredAltitude = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitude()}); + var desiredAltitudeType = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitudeType()}); + var desiredSpeed = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeed()}); + var desiredSpeedType = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeedType()}); + var onOff = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getOnOff()}); + var followRoads = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getFollowRoads()}); this.#altitudeTypeSwitch.setValue(desiredAltitudeType != undefined? desiredAltitudeType == "ASL": undefined, false); this.#speedTypeSwitch.setValue(desiredSpeedType != undefined? desiredSpeedType == "CAS": undefined, false); @@ -328,7 +327,7 @@ export class UnitControlPanel extends Panel { } /* Send command and close */ - var units = getUnitsManager().getSelectedUnits(); + var units = getApp().getUnitsManager().getSelectedUnits(); if (units.length > 0) units[0].setAdvancedOptions(isTanker, isAWACS, TACAN, radio, generalSettings); diff --git a/client/src/panels/unitinfopanel.ts b/client/src/panels/unitinfopanel.ts index 36e779c2..206afe94 100644 --- a/client/src/panels/unitinfopanel.ts +++ b/client/src/panels/unitinfopanel.ts @@ -1,4 +1,3 @@ -import { Ammo } from "../@types/unit"; import { aircraftDatabase } from "../unit/databases/aircraftdatabase"; import { Unit } from "../unit/unit"; import { Panel } from "./panel"; diff --git a/client/src/plugin/plugin.ts b/client/src/plugin/plugin.ts deleted file mode 100644 index 97204563..00000000 --- a/client/src/plugin/plugin.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { OlympusApp } from "../olympusapp"; -const templateParser = require( "ejs" ); - -export abstract class Plugin { - - #olympusApp!:OlympusApp; - protected name = ""; - #templateParser:any; - - constructor( olympusApp:OlympusApp, pluginName:string ) { - - const regex = "^[a-zA-Z][a-zA-Z\d]{4,}" - - if ( new RegExp( regex ).test( pluginName ) === false ) { - throw new Error( `Plugin names must match regex: ${regex}` ); - } - - this.name = pluginName; - this.#olympusApp = olympusApp; - this.#templateParser = templateParser; - - } - - getName() { - return this.name; - } - - getOlympusApp() { - return this.#olympusApp; - } - - getTemplateParser() { - return this.#templateParser; - } - -} \ No newline at end of file diff --git a/client/src/plugin/pluginmanager.ts b/client/src/plugin/pluginmanager.ts index 7e017d5a..3179786b 100644 --- a/client/src/plugin/pluginmanager.ts +++ b/client/src/plugin/pluginmanager.ts @@ -1,13 +1,55 @@ -import { OlympusApp } from "../olympusapp"; +import path from "path"; import { Manager } from "../other/manager"; +import { getApp } from ".."; +export class PluginsManager extends Manager { + constructor() { + super(); -export class PluginManager extends Manager { - - constructor( olympusApp:OlympusApp ) { - - super( olympusApp ); - + var xhr = new XMLHttpRequest(); + xhr.open('GET', "/plugins/list", true); + xhr.responseType = 'json'; + xhr.onload = () => { + var status = xhr.status; + if (status === 200) { + this.#loadPlugins(xhr.response); + } else { + console.error(`Error retrieving plugins`) + } + }; + xhr.send(); + } + + #loadPlugins(pluginsFolders: string[]) { + pluginsFolders.forEach((pluginName: string) => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', path.join("/plugins", pluginName, "index.js"), true); + xhr.responseType = 'text'; + xhr.onload = () => { + var status = xhr.status; + if (status === 200) { + /* Inject the plugin style */ + var link = document.createElement("link"); + link.href = path.join("/plugins", pluginName, "style.css"); + link.type = "text/css"; + link.rel = "stylesheet"; + document.getElementsByTagName("head")[0].appendChild(link); + + /* Evaluate the plugin javascript */ + eval(xhr.response); + const plugin = globalThis.getOlympusPlugin() as OlympusPlugin; + console.log(plugin.getName() + " loaded correctly"); + + if (plugin.initialize(getApp())) { + console.log(plugin.getName() + " initialized correctly"); + this.add(pluginName, plugin); + } + + } else { + console.error(`Error retrieving plugin from ${pluginName}`) + } + }; + xhr.send(); + }) } - } \ No newline at end of file diff --git a/client/src/server/dataextractor.ts b/client/src/server/dataextractor.ts index d22b6201..efd61d8b 100644 --- a/client/src/server/dataextractor.ts +++ b/client/src/server/dataextractor.ts @@ -1,5 +1,4 @@ import { LatLng } from "leaflet"; -import { Ammo, Contact, GeneralSettings, Offset, Radio, TACAN } from "../@types/unit"; export class DataExtractor { #seekPosition = 0; diff --git a/client/src/server/server.ts b/client/src/server/server.ts index 05695c86..9087abfa 100644 --- a/client/src/server/server.ts +++ b/client/src/server/server.ts @@ -1,7 +1,10 @@ import { LatLng } from 'leaflet'; -import { getConnectionStatusPanel, getInfoPopup, getLogPanel, getMissionHandler, getServerStatusPanel, getUnitsManager, getWeaponsManager, setLoginStatus } from '..'; -import { GeneralSettings, Radio, TACAN } from '../@types/unit'; +import { getApp } from '..'; import { AIRBASES_URI, BULLSEYE_URI, COMMANDS_URI, LOGS_URI, MISSION_URI, NONE, ROEs, UNITS_URI, WEAPONS_URI, emissionsCountermeasures, reactionsToThreat } from '../constants/constants'; +import { ServerStatusPanel } from '../panels/serverstatuspanel'; +import { LogPanel } from '../panels/logpanel'; +import { Popup } from '../popups/popup'; +import { ConnectionStatusPanel } from '../panels/connectionstatuspanel'; var connected: boolean = false; var paused: boolean = false; @@ -64,12 +67,12 @@ export function GET(callback: CallableFunction, uri: string, options?: ServerReq lastUpdateTimes[uri] = callback(result); if (result.frameRate !== undefined && result.load !== undefined) - getServerStatusPanel().update(result.frameRate, result.load); + (getApp().getPanelsManager().get("serverStatus") as ServerStatusPanel).update(result.frameRate, result.load); } } else if (xmlHttp.status == 401) { /* Bad credentials */ console.error("Incorrect username/password"); - setLoginStatus("failed"); + getApp().setLoginStatus("failed"); } else { /* Failure, probably disconnected */ setConnected(false); @@ -351,74 +354,74 @@ export function startUpdate() { if (!getPaused()) { getMission((data: MissionData) => { checkSessionHash(data.sessionHash); - getMissionHandler()?.updateMission(data); + getApp().getMissionManager()?.updateMission(data); return data.time; }); } }, 1000); window.setInterval(() => { - if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) { + if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { getAirbases((data: AirbasesData) => { checkSessionHash(data.sessionHash); - getMissionHandler()?.updateAirbases(data); + getApp().getMissionManager()?.updateAirbases(data); return data.time; }); } }, 10000); window.setInterval(() => { - if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE){ + if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE){ getBullseye((data: BullseyesData) => { checkSessionHash(data.sessionHash); - getMissionHandler()?.updateBullseyes(data); + getApp().getMissionManager()?.updateBullseyes(data); return data.time; }); } }, 10000); window.setInterval(() => { - if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) { + if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { getLogs((data: any) => { checkSessionHash(data.sessionHash); - getLogPanel().appendLogs(data.logs) + (getApp().getPanelsManager().get("log") as LogPanel).appendLogs(data.logs) return data.time; }); } }, 1000); window.setInterval(() => { - if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) { + if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { getUnits((buffer: ArrayBuffer) => { - var time = getUnitsManager()?.update(buffer); + var time = getApp().getUnitsManager()?.update(buffer); return time; }, false); } }, 250); window.setInterval(() => { - if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) { + if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { getWeapons((buffer: ArrayBuffer) => { - var time = getWeaponsManager()?.update(buffer); + var time = getApp().getWeaponsManager()?.update(buffer); return time; }, false); } }, 250); window.setInterval(() => { - if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) { + if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { getUnits((buffer: ArrayBuffer) => { - var time = getUnitsManager()?.update(buffer); + var time = getApp().getUnitsManager()?.update(buffer); return time; }, true); - getConnectionStatusPanel()?.update(getConnected()); + (getApp().getPanelsManager().get("connectionStatus") as ConnectionStatusPanel).update(getConnected()); } }, 5000); window.setInterval(() => { - if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) { + if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { getWeapons((buffer: ArrayBuffer) => { - var time = getWeaponsManager()?.update(buffer); + var time = getApp().getWeaponsManager()?.update(buffer); return time; }, true); } @@ -428,29 +431,29 @@ export function startUpdate() { export function refreshAll() { getAirbases((data: AirbasesData) => { checkSessionHash(data.sessionHash); - getMissionHandler()?.updateAirbases(data); + getApp().getMissionManager()?.updateAirbases(data); return data.time; }); getBullseye((data: BullseyesData) => { checkSessionHash(data.sessionHash); - getMissionHandler()?.updateBullseyes(data); + getApp().getMissionManager()?.updateBullseyes(data); return data.time; }); getLogs((data: any) => { checkSessionHash(data.sessionHash); - getLogPanel().appendLogs(data.logs) + (getApp().getPanelsManager().get("log") as LogPanel).appendLogs(data.logs) return data.time; }); getWeapons((buffer: ArrayBuffer) => { - var time = getWeaponsManager()?.update(buffer); + var time = getApp().getWeaponsManager()?.update(buffer); return time; }, true); getUnits((buffer: ArrayBuffer) => { - var time = getUnitsManager()?.update(buffer); + var time = getApp().getUnitsManager()?.update(buffer); return time; }, true); } @@ -466,7 +469,7 @@ export function checkSessionHash(newSessionHash: string) { export function setConnected(newConnected: boolean) { if (connected != newConnected) - newConnected ? getInfoPopup().setText("Connected to DCS Olympus server") : getInfoPopup().setText("Disconnected from DCS Olympus server"); + newConnected ? (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Connected to DCS Olympus server") : (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Disconnected from DCS Olympus server"); connected = newConnected; if (connected) { @@ -481,7 +484,7 @@ export function getConnected() { export function setPaused(newPaused: boolean) { paused = newPaused; - paused ? getInfoPopup().setText("View paused") : getInfoPopup().setText("View unpaused"); + paused ? (getApp().getPopupsManager().get("infoPopup") as Popup).setText("View paused") : (getApp().getPopupsManager().get("infoPopup") as Popup).setText("View unpaused"); } export function getPaused() { diff --git a/client/src/shortcut/shortcut.ts b/client/src/shortcut/shortcut.ts index a2b9bac0..095ba6cd 100644 --- a/client/src/shortcut/shortcut.ts +++ b/client/src/shortcut/shortcut.ts @@ -1,70 +1,42 @@ import { keyEventWasInInput } from "../other/utils"; -interface IShortcut { - altKey?:boolean; - callback:CallableFunction; - ctrlKey?:boolean; - name?:string; - shiftKey?:boolean; -} - -interface IShortcutKeyboard extends IShortcut { - code:string; - event?:"keydown"|"keyup"; -} - -interface IShortcutMouse extends IShortcut { - button:number; - event:"mousedown"|"mouseup"; -} - export abstract class Shortcut { + #config: ShortcutOptions - #config:IShortcut - - constructor( config:IShortcut ) { + constructor(config: ShortcutOptions) { this.#config = config; } getConfig() { return this.#config; } - } export class ShortcutKeyboard extends Shortcut { - - constructor( config:IShortcutKeyboard ) { - + constructor(config: KeyboardShortcutOptions) { config.event = config.event || "keyup"; - - super( config ); + super(config); - document.addEventListener( config.event, ( ev:any ) => { - - if ( ev instanceof KeyboardEvent === false || keyEventWasInInput( ev )) { + document.addEventListener(config.event, (ev: any) => { + if (ev instanceof KeyboardEvent === false || keyEventWasInInput(ev)) { return; } - if ( config.code !== ev.code ) { + if (config.code !== ev.code) { return; } - if ( ( ( typeof config.altKey !== "boolean" ) || ( typeof config.altKey === "boolean" && ev.altKey === config.altKey ) ) - && ( ( typeof config.ctrlKey !== "boolean" ) || ( typeof config.ctrlKey === "boolean" && ev.ctrlKey === config.ctrlKey ) ) - && ( ( typeof config.shiftKey !== "boolean" ) || ( typeof config.shiftKey === "boolean" && ev.shiftKey === config.shiftKey ) ) ) { - config.callback( ev ); + if (((typeof config.altKey !== "boolean") || (typeof config.altKey === "boolean" && ev.altKey === config.altKey)) + && ((typeof config.ctrlKey !== "boolean") || (typeof config.ctrlKey === "boolean" && ev.ctrlKey === config.ctrlKey)) + && ((typeof config.shiftKey !== "boolean") || (typeof config.shiftKey === "boolean" && ev.shiftKey === config.shiftKey))) { + config.callback(ev); } }); - } - } export class ShortcutMouse extends Shortcut { - - constructor( config:IShortcutMouse ) { - super( config ); + constructor(config: MouseShortcutOptions) { + super(config); } - } \ No newline at end of file diff --git a/client/src/shortcut/shortcutmanager.ts b/client/src/shortcut/shortcutmanager.ts index 54e6386a..6f1acd21 100644 --- a/client/src/shortcut/shortcutmanager.ts +++ b/client/src/shortcut/shortcutmanager.ts @@ -1,33 +1,32 @@ -import { OlympusApp } from "../olympusapp"; import { Manager } from "../other/manager"; import { Shortcut } from "./shortcut"; export class ShortcutManager extends Manager { - #keysBeingHeld:string[] = []; - #keyDownCallbacks:CallableFunction[] = []; - #keyUpCallbacks:CallableFunction[] = []; + #keysBeingHeld: string[] = []; + #keyDownCallbacks: CallableFunction[] = []; + #keyUpCallbacks: CallableFunction[] = []; - constructor( olympusApp:OlympusApp ) { - - super( olympusApp ); + constructor() { - document.addEventListener( "keydown", ( ev:KeyboardEvent ) => { - if ( this.#keysBeingHeld.indexOf( ev.code ) < 0 ) { - this.#keysBeingHeld.push( ev.code ) + super(); + + document.addEventListener("keydown", (ev: KeyboardEvent) => { + if (this.#keysBeingHeld.indexOf(ev.code) < 0) { + this.#keysBeingHeld.push(ev.code) } - this.#keyDownCallbacks.forEach( callback => callback( ev ) ); + this.#keyDownCallbacks.forEach(callback => callback(ev)); }); - document.addEventListener( "keyup", ( ev:KeyboardEvent ) => { - this.#keysBeingHeld = this.#keysBeingHeld.filter( held => held !== ev.code ); - this.#keyUpCallbacks.forEach( callback => callback( ev ) ); + document.addEventListener("keyup", (ev: KeyboardEvent) => { + this.#keysBeingHeld = this.#keysBeingHeld.filter(held => held !== ev.code); + this.#keyUpCallbacks.forEach(callback => callback(ev)); }); } - add( name:string, shortcut:Shortcut ) { - super.add( name, shortcut ); + add(name: string, shortcut: Shortcut) { + super.add(name, shortcut); return this; } @@ -35,24 +34,20 @@ export class ShortcutManager extends Manager { return this.#keysBeingHeld; } - keyComboMatches( combo:string[] ) { - + keyComboMatches(combo: string[]) { const heldKeys = this.getKeysBeingHeld(); - - if ( combo.length !== heldKeys.length ) { + if (combo.length !== heldKeys.length) { return false; } - return combo.every( key => heldKeys.indexOf( key ) > -1 ); - + return combo.every(key => heldKeys.indexOf(key) > -1); } - onKeyDown( callback:CallableFunction ) { - this.#keyDownCallbacks.push( callback ); + onKeyDown(callback: CallableFunction) { + this.#keyDownCallbacks.push(callback); } - onKeyUp( callback:CallableFunction ) { - this.#keyUpCallbacks.push( callback ); + onKeyUp(callback: CallableFunction) { + this.#keyUpCallbacks.push(callback); } - } \ No newline at end of file diff --git a/client/src/unit/databases/aircraftdatabase.ts b/client/src/unit/databases/aircraftdatabase.ts index 31d072cb..74ecf23f 100644 --- a/client/src/unit/databases/aircraftdatabase.ts +++ b/client/src/unit/databases/aircraftdatabase.ts @@ -1,4 +1,4 @@ -import { getMissionHandler } from "../.."; +import { getApp } from "../.."; import { GAME_MASTER } from "../../constants/constants"; import { UnitDatabase } from "./unitdatabase" @@ -12,7 +12,7 @@ export class AircraftDatabase extends UnitDatabase { } getSpawnPointsByName(name: string) { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || !getMissionHandler().getCommandModeOptions().restrictSpawns) + if (getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER || !getApp().getMissionManager().getCommandModeOptions().restrictSpawns) return 0; const blueprint = this.getByName(name); diff --git a/client/src/unit/databases/groundunitdatabase.ts b/client/src/unit/databases/groundunitdatabase.ts index e34c6313..a4d8213a 100644 --- a/client/src/unit/databases/groundunitdatabase.ts +++ b/client/src/unit/databases/groundunitdatabase.ts @@ -1,4 +1,4 @@ -import { getMissionHandler } from "../.."; +import { getApp } from "../.."; import { GAME_MASTER } from "../../constants/constants"; import { UnitDatabase } from "./unitdatabase" @@ -8,7 +8,7 @@ export class GroundUnitDatabase extends UnitDatabase { } getSpawnPointsByName(name: string) { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || !getMissionHandler().getCommandModeOptions().restrictSpawns) + if (getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER || !getApp().getMissionManager().getCommandModeOptions().restrictSpawns) return 0; const blueprint = this.getByName(name); diff --git a/client/src/unit/databases/helicopterdatabase.ts b/client/src/unit/databases/helicopterdatabase.ts index a39de1c8..d105d282 100644 --- a/client/src/unit/databases/helicopterdatabase.ts +++ b/client/src/unit/databases/helicopterdatabase.ts @@ -1,4 +1,4 @@ -import { getMissionHandler } from "../.."; +import { getApp } from "../.."; import { GAME_MASTER } from "../../constants/constants"; import { UnitDatabase } from "./unitdatabase" @@ -8,7 +8,7 @@ export class HelicopterDatabase extends UnitDatabase { } getSpawnPointsByName(name: string) { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || !getMissionHandler().getCommandModeOptions().restrictSpawns) + if (getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER || !getApp().getMissionManager().getCommandModeOptions().restrictSpawns) return 0; const blueprint = this.getByName(name); diff --git a/client/src/unit/databases/navyunitdatabase.ts b/client/src/unit/databases/navyunitdatabase.ts index c45f07c2..6f5111eb 100644 --- a/client/src/unit/databases/navyunitdatabase.ts +++ b/client/src/unit/databases/navyunitdatabase.ts @@ -1,4 +1,4 @@ -import { getMissionHandler } from "../.."; +import { getApp } from "../.."; import { GAME_MASTER } from "../../constants/constants"; import { UnitDatabase } from "./unitdatabase" @@ -8,7 +8,7 @@ export class NavyUnitDatabase extends UnitDatabase { } getSpawnPointsByName(name: string) { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || !getMissionHandler().getCommandModeOptions().restrictSpawns) + if (getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER || !getApp().getMissionManager().getCommandModeOptions().restrictSpawns) return 0; const blueprint = this.getByName(name); diff --git a/client/src/unit/databases/unitdatabase.ts b/client/src/unit/databases/unitdatabase.ts index 92316d90..b64a6e01 100644 --- a/client/src/unit/databases/unitdatabase.ts +++ b/client/src/unit/databases/unitdatabase.ts @@ -1,7 +1,6 @@ import { LatLng } from "leaflet"; -import { getMissionHandler, getUnitsManager } from "../.."; +import { getApp } from "../.."; import { GAME_MASTER } from "../../constants/constants"; -import { UnitBlueprint } from "../../@types/unitdatabase"; export class UnitDatabase { blueprints: { [key: string]: UnitBlueprint } = {}; @@ -44,15 +43,15 @@ export class UnitDatabase { } getBlueprints() { - if (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || !getMissionHandler().getCommandModeOptions().restrictSpawns) + if (getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER || !getApp().getMissionManager().getCommandModeOptions().restrictSpawns) return this.blueprints; else { var filteredBlueprints: { [key: string]: UnitBlueprint } = {}; for (let unit in this.blueprints) { const blueprint = this.blueprints[unit]; - if (this.getSpawnPointsByName(blueprint.name) <= getMissionHandler().getAvailableSpawnPoints() && - getMissionHandler().getCommandModeOptions().eras.includes(blueprint.era) && - (!getMissionHandler().getCommandModeOptions().restrictToCoalition || blueprint.coalition === getMissionHandler().getCommandedCoalition() || blueprint.coalition === undefined)) { + if (this.getSpawnPointsByName(blueprint.name) <= getApp().getMissionManager().getAvailableSpawnPoints() && + getApp().getMissionManager().getCommandModeOptions().eras.includes(blueprint.era) && + (!getApp().getMissionManager().getCommandModeOptions().restrictToCoalition || blueprint.coalition === getApp().getMissionManager().getCommandedCoalition() || blueprint.coalition === undefined)) { filteredBlueprints[unit] = blueprint; } } @@ -201,7 +200,7 @@ export class UnitDatabase { var row = Math.floor(idx / gridSize); var col = idx - row * gridSize; var location = new LatLng(initialPosition.lat + col * step, initialPosition.lng + row * step) - getUnitsManager().spawnUnits(this.getCategory(), [{unitType: unitBlueprint.name, location: location, altitude: 1000, loadout: "", liveryID: ""}]); + getApp().getUnitsManager().spawnUnits(this.getCategory(), [{unitType: unitBlueprint.name, location: location, altitude: 1000, loadout: "", liveryID: ""}]); }) } diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index 56c4c54e..7ca1d5d8 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -1,5 +1,5 @@ import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point } from 'leaflet'; -import { getMap, getMissionHandler, getUnitsManager, getWeaponsManager } from '..'; +import { getApp } from '..'; import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad, ftToM } from '../other/utils'; import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures, setSpeedType, setAltitudeType, setOnOff, setFollowRoads, bombPoint, carpetBomb, bombBuilding, fireAtArea } from '../server/server'; import { CustomMarker } from '../map/markers/custommarker'; @@ -7,12 +7,10 @@ import { SVGInjector } from '@tanem/svg-injector'; import { UnitDatabase } from './databases/unitdatabase'; import { TargetMarker } from '../map/markers/targetmarker'; import { DLINK, DataIndexes, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_CONTACT_LINES, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants'; -import { Ammo, Contact, GeneralSettings, Offset, Radio, TACAN, ObjectIconOptions, UnitData } from '../@types/unit'; import { DataExtractor } from '../server/dataextractor'; import { groundUnitDatabase } from './databases/groundunitdatabase'; import { navyUnitDatabase } from './databases/navyunitdatabase'; import { Weapon } from '../weapon/weapon'; -import { LoadoutBlueprint } from '../@types/unitdatabase'; var pathIcon = new Icon({ iconUrl: '/resources/theme/images/markers/marker-icon.png', @@ -147,7 +145,7 @@ export class Unit extends CustomMarker { this.#selectable = true; this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 }); - this.#pathPolyline.addTo(getMap()); + this.#pathPolyline.addTo(getApp().getMap()); this.#contactsPolylines = []; this.#targetPositionMarker = new TargetMarker(new LatLng(0, 0)); this.#targetPositionPolyline = new Polyline([], { color: '#FF0000', weight: 3, opacity: 0.5, smoothFactor: 1 }); @@ -165,7 +163,7 @@ export class Unit extends CustomMarker { this.setHighlighted(false); document.dispatchEvent(new CustomEvent("unitMouseout", { detail: this })); }); - getMap().on("zoomend", () => { this.#onZoom(); }) + getApp().getMap().on("zoomend", () => { this.#onZoom(); }) /* Deselect units if they are hidden */ document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => { @@ -190,7 +188,7 @@ export class Unit extends CustomMarker { /********************** Unit data *************************/ setData(dataExtractor: DataExtractor) { - var updateMarker = !getMap().hasLayer(this); + var updateMarker = !getApp().getMap().hasLayer(this); var datumIndex = 0; while (datumIndex != DataIndexes.endOfData) { @@ -243,7 +241,7 @@ export class Unit extends CustomMarker { if (updateMarker) this.#updateMarker(); - if (this.getSelected() || getMap().getCenterUnit() === this) + if (this.getSelected() || getApp().getMap().getCenterUnit() === this) document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this })); } @@ -342,7 +340,7 @@ export class Unit extends CustomMarker { } this.getElement()?.querySelector(`.unit`)?.toggleAttribute("data-is-selected", selected); - if (this.getCategory() === "GroundUnit" && getMap().getZoom() < 13) { + if (this.getCategory() === "GroundUnit" && getApp().getMap().getZoom() < 13) { if (this.#isLeader) this.getGroupMembers().forEach((unit: Unit) => unit.setSelected(selected)); else @@ -393,11 +391,11 @@ export class Unit extends CustomMarker { } getGroupMembers() { - return Object.values(getUnitsManager().getUnits()).filter((unit: Unit) => { return unit != this && unit.#groupName === this.#groupName; }); + return Object.values(getApp().getUnitsManager().getUnits()).filter((unit: Unit) => { return unit != this && unit.#groupName === this.#groupName; }); } belongsToCommandedCoalition() { - if (getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER && getMissionHandler().getCommandedCoalition() !== this.#coalition) + if (getApp().getMissionManager().getCommandModeOptions().commandMode !== GAME_MASTER && getApp().getMissionManager().getCommandedCoalition() !== this.#coalition) return false; return true; } @@ -523,13 +521,13 @@ export class Unit extends CustomMarker { /********************** Visibility *************************/ updateVisibility() { - const hiddenUnits = getMap().getHiddenTypes(); + const hiddenUnits = getApp().getMap().getHiddenTypes(); var hidden = ((this.#human && hiddenUnits.includes("human")) || (this.#controlled == false && hiddenUnits.includes("dcs")) || (hiddenUnits.includes(this.getMarkerCategory())) || (hiddenUnits.includes(this.#coalition)) || (!this.belongsToCommandedCoalition() && (this.#detectionMethods.length == 0 || (this.#detectionMethods.length == 1 && this.#detectionMethods[0] === RWR))) || - (getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getMap().getZoom() < 13 && (this.belongsToCommandedCoalition() || (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0)))) && + (getApp().getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getApp().getMap().getZoom() < 13 && (this.belongsToCommandedCoalition() || (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0)))) && !(this.getSelected()); this.setHidden(hidden || !this.#alive); @@ -539,16 +537,16 @@ export class Unit extends CustomMarker { this.#hidden = hidden; /* Add the marker if not present */ - if (!getMap().hasLayer(this) && !this.getHidden()) { - if (getMap().isZooming()) - this.once("zoomend", () => { this.addTo(getMap()) }) + if (!getApp().getMap().hasLayer(this) && !this.getHidden()) { + if (getApp().getMap().isZooming()) + this.once("zoomend", () => { this.addTo(getApp().getMap()) }) else - this.addTo(getMap()); + this.addTo(getApp().getMap()); } /* Hide the marker if necessary*/ - if (getMap().hasLayer(this) && this.getHidden()) { - getMap().removeLayer(this); + if (getApp().getMap().hasLayer(this) && this.getHidden()) { + getApp().getMap().removeLayer(this); } } @@ -573,7 +571,7 @@ export class Unit extends CustomMarker { } getLeader() { - return getUnitsManager().getUnitByID(this.#leaderID); + return getApp().getUnitsManager().getUnitByID(this.#leaderID); } canFulfillRole(roles: string | string[]) { @@ -591,7 +589,7 @@ export class Unit extends CustomMarker { isInViewport() { - const mapBounds = getMap().getBounds(); + const mapBounds = getApp().getMap().getBounds(); const unitPos = this.getPosition(); return (unitPos.lng > mapBounds.getWest() @@ -739,9 +737,9 @@ export class Unit extends CustomMarker { /***********************************************/ #onClick(e: any) { if (!this.#preventClick) { - if (getMap().getState() === IDLE || getMap().getState() === MOVE_UNIT || e.originalEvent.ctrlKey) { + if (getApp().getMap().getState() === IDLE || getApp().getMap().getState() === MOVE_UNIT || e.originalEvent.ctrlKey) { if (!e.originalEvent.ctrlKey) - getUnitsManager().deselectAllUnits(); + getApp().getUnitsManager().deselectAllUnits(); this.setSelected(!this.getSelected()); const detail = { "detail": { "unit": this } }; @@ -756,7 +754,7 @@ export class Unit extends CustomMarker { } #onDoubleClick(e: any) { - const unitsManager = getUnitsManager(); + const unitsManager = getApp().getUnitsManager(); Object.values(unitsManager.getUnits()).forEach((unit: Unit) => { if (unit.getAlive() === true && unit.getName() === this.getName() && unit.isInViewport()) unitsManager.selectUnit(unit.ID, false); @@ -768,14 +766,14 @@ export class Unit extends CustomMarker { #onContextMenu(e: any) { var options: { [key: string]: { text: string, tooltip: string } } = {}; - const selectedUnits = getUnitsManager().getSelectedUnits(); - const selectedUnitTypes = getUnitsManager().getSelectedUnitsCategories(); + const selectedUnits = getApp().getUnitsManager().getSelectedUnits(); + const selectedUnitTypes = getApp().getUnitsManager().getSelectedUnitsCategories(); options["center-map"] = { text: "Center map", tooltip: "Center the map on the unit and follow it" }; if (selectedUnits.length > 0 && !(selectedUnits.length == 1 && (selectedUnits.includes(this)))) { options["attack"] = { text: "Attack", tooltip: "Attack the unit using A/A or A/G weapons" }; - if (getUnitsManager().getSelectedUnitsCategories().length == 1 && getUnitsManager().getSelectedUnitsCategories()[0] === "Aircraft") + if (getApp().getUnitsManager().getSelectedUnitsCategories().length == 1 && getApp().getUnitsManager().getSelectedUnitsCategories()[0] === "Aircraft") options["follow"] = { text: "Follow", tooltip: "Follow the unit at a user defined distance and position" };; } else if ((selectedUnits.length > 0 && (selectedUnits.includes(this))) || selectedUnits.length == 0) { @@ -784,13 +782,13 @@ export class Unit extends CustomMarker { } } - if (selectedUnitTypes.length === 1 && ["NavyUnit", "GroundUnit"].includes(selectedUnitTypes[0]) && getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) !== undefined) + if (selectedUnitTypes.length === 1 && ["NavyUnit", "GroundUnit"].includes(selectedUnitTypes[0]) && getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) !== undefined) options["group"] = { text: "Create group", tooltip: "Create a group from the selected units." }; if (Object.keys(options).length > 0) { - getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); - getMap().getUnitContextMenu().setOptions(options, (option: string) => { - getMap().hideUnitContextMenu(); + getApp().getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); + getApp().getMap().getUnitContextMenu().setOptions(options, (option: string) => { + getApp().getMap().hideUnitContextMenu(); this.#executeAction(e, option); }); } @@ -798,13 +796,13 @@ export class Unit extends CustomMarker { #executeAction(e: any, action: string) { if (action === "center-map") - getMap().centerOnUnit(this.ID); + getApp().getMap().centerOnUnit(this.ID); if (action === "attack") - getUnitsManager().selectedUnitsAttackUnit(this.ID); + getApp().getUnitsManager().selectedUnitsAttackUnit(this.ID); else if (action === "refuel") - getUnitsManager().selectedUnitsRefuel(); + getApp().getUnitsManager().selectedUnitsRefuel(); else if (action === "group") - getUnitsManager().selectedUnitsCreateGroup(); + getApp().getUnitsManager().selectedUnitsCreateGroup(); else if (action === "follow") this.#showFollowOptions(e); } @@ -823,12 +821,12 @@ export class Unit extends CustomMarker { 'custom': { text: "Custom", tooltip: "Set a custom formation position" }, } - getMap().getUnitContextMenu().setOptions(options, (option: string) => { - getMap().hideUnitContextMenu(); + getApp().getMap().getUnitContextMenu().setOptions(options, (option: string) => { + getApp().getMap().hideUnitContextMenu(); this.#applyFollowOptions(option); }); - getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); + getApp().getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); } #applyFollowOptions(action: string) { @@ -856,12 +854,12 @@ export class Unit extends CustomMarker { var y = upDown; var z = distance * Math.sin(angleRad); - getUnitsManager().selectedUnitsFollowUnit(this.ID, { "x": x, "y": y, "z": z }); + getApp().getUnitsManager().selectedUnitsFollowUnit(this.ID, { "x": x, "y": y, "z": z }); } }); } else { - getUnitsManager().selectedUnitsFollowUnit(this.ID, undefined, action); + getApp().getUnitsManager().selectedUnitsFollowUnit(this.ID, undefined, action); } } @@ -879,7 +877,7 @@ export class Unit extends CustomMarker { this.#miniMapMarker.setStyle({ color: "#ff5858" }); else this.#miniMapMarker.setStyle({ color: "#247be2" }); - this.#miniMapMarker.addTo(getMap().getMiniMapLayerGroup()); + this.#miniMapMarker.addTo(getApp().getMap().getMiniMapLayerGroup()); this.#miniMapMarker.bringToBack(); } else { @@ -890,8 +888,8 @@ export class Unit extends CustomMarker { } } else { - if (this.#miniMapMarker != null && getMap().getMiniMapLayerGroup().hasLayer(this.#miniMapMarker)) { - getMap().getMiniMapLayerGroup().removeLayer(this.#miniMapMarker); + if (this.#miniMapMarker != null && getApp().getMap().getMiniMapLayerGroup().hasLayer(this.#miniMapMarker)) { + getApp().getMap().getMiniMapLayerGroup().removeLayer(this.#miniMapMarker); this.#miniMapMarker = null; } } @@ -976,25 +974,25 @@ export class Unit extends CustomMarker { } /* Set vertical offset for altitude stacking */ - var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); + var pos = getApp().getMap().latLngToLayerPoint(this.getLatLng()).round(); this.setZIndexOffset(1000 + Math.floor(this.#position.alt as number) - pos.y + (this.#highlighted || this.#selected ? 5000 : 0)); } } #drawPath() { - if (this.#activePath != undefined && getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) { + if (this.#activePath != undefined && getApp().getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) { var points = []; points.push(new LatLng(this.#position.lat, this.#position.lng)); /* Add markers if missing */ while (this.#pathMarkers.length < Object.keys(this.#activePath).length) { - var marker = new Marker([0, 0], { icon: pathIcon }).addTo(getMap()); + var marker = new Marker([0, 0], { icon: pathIcon }).addTo(getApp().getMap()); this.#pathMarkers.push(marker); } /* Remove markers if too many */ while (this.#pathMarkers.length > Object.keys(this.#activePath).length) { - getMap().removeLayer(this.#pathMarkers[this.#pathMarkers.length - 1]); + getApp().getMap().removeLayer(this.#pathMarkers[this.#pathMarkers.length - 1]); this.#pathMarkers.splice(this.#pathMarkers.length - 1, 1) } @@ -1016,7 +1014,7 @@ export class Unit extends CustomMarker { #clearPath() { for (let WP in this.#pathMarkers) { - getMap().removeLayer(this.#pathMarkers[WP]); + getApp().getMap().removeLayer(this.#pathMarkers[WP]); } this.#pathMarkers = []; this.#pathPolyline.setLatLngs([]); @@ -1024,25 +1022,25 @@ export class Unit extends CustomMarker { #drawContacts() { this.#clearContacts(); - if (getMap().getVisibilityOptions()[SHOW_CONTACT_LINES]) { + if (getApp().getMap().getVisibilityOptions()[SHOW_CONTACT_LINES]) { for (let index in this.#contacts) { var contactData = this.#contacts[index]; var contact: Unit | Weapon | null; - if (contactData.ID in getUnitsManager().getUnits()) - contact = getUnitsManager().getUnitByID(contactData.ID); + if (contactData.ID in getApp().getUnitsManager().getUnits()) + contact = getApp().getUnitsManager().getUnitByID(contactData.ID); else - contact = getWeaponsManager().getWeaponByID(contactData.ID); + contact = getApp().getWeaponsManager().getWeaponByID(contactData.ID); if (contact != null && contact.getAlive()) { var startLatLng = new LatLng(this.#position.lat, this.#position.lng); var endLatLng: LatLng; if (contactData.detectionMethod === RWR) { var bearingToContact = bearing(this.#position.lat, this.#position.lng, contact.getPosition().lat, contact.getPosition().lng); - var startXY = getMap().latLngToContainerPoint(startLatLng); + var startXY = getApp().getMap().latLngToContainerPoint(startLatLng); var endX = startXY.x + 80 * Math.sin(deg2rad(bearingToContact)); var endY = startXY.y - 80 * Math.cos(deg2rad(bearingToContact)); - endLatLng = getMap().containerPointToLatLng(new Point(endX, endY)); + endLatLng = getApp().getMap().containerPointToLatLng(new Point(endX, endY)); } else endLatLng = new LatLng(contact.getPosition().lat, contact.getPosition().lng); @@ -1057,7 +1055,7 @@ export class Unit extends CustomMarker { else color = "#FFFFFF"; var contactPolyline = new Polyline([startLatLng, endLatLng], { color: color, weight: 3, opacity: 1, smoothFactor: 1, dashArray: "4, 8" }); - contactPolyline.addTo(getMap()); + contactPolyline.addTo(getApp().getMap()); this.#contactsPolylines.push(contactPolyline) } } @@ -1066,17 +1064,17 @@ export class Unit extends CustomMarker { #clearContacts() { for (let index in this.#contactsPolylines) { - getMap().removeLayer(this.#contactsPolylines[index]) + getApp().getMap().removeLayer(this.#contactsPolylines[index]) } } #drawTarget() { - if (this.#targetPosition.lat != 0 && this.#targetPosition.lng != 0 && getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) { + if (this.#targetPosition.lat != 0 && this.#targetPosition.lng != 0 && getApp().getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) { this.#drawTargetPosition(this.#targetPosition); } - else if (this.#targetID != 0 && getMap().getVisibilityOptions()[SHOW_UNIT_TARGETS]) { - const target = getUnitsManager().getUnitByID(this.#targetID); - if (target && (getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || (this.belongsToCommandedCoalition() && getUnitsManager().getUnitDetectedMethods(target).some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))))) { + else if (this.#targetID != 0 && getApp().getMap().getVisibilityOptions()[SHOW_UNIT_TARGETS]) { + const target = getApp().getUnitsManager().getUnitByID(this.#targetID); + if (target && (getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER || (this.belongsToCommandedCoalition() && getApp().getUnitsManager().getUnitDetectedMethods(target).some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))))) { this.#drawTargetPosition(target.getPosition()); } } @@ -1085,20 +1083,20 @@ export class Unit extends CustomMarker { } #drawTargetPosition(targetPosition: LatLng) { - if (!getMap().hasLayer(this.#targetPositionMarker)) - this.#targetPositionMarker.addTo(getMap()); - if (!getMap().hasLayer(this.#targetPositionPolyline)) - this.#targetPositionPolyline.addTo(getMap()); + if (!getApp().getMap().hasLayer(this.#targetPositionMarker)) + this.#targetPositionMarker.addTo(getApp().getMap()); + if (!getApp().getMap().hasLayer(this.#targetPositionPolyline)) + this.#targetPositionPolyline.addTo(getApp().getMap()); this.#targetPositionMarker.setLatLng(new LatLng(targetPosition.lat, targetPosition.lng)); this.#targetPositionPolyline.setLatLngs([new LatLng(this.#position.lat, this.#position.lng), new LatLng(targetPosition.lat, targetPosition.lng)]) } #clearTarget() { - if (getMap().hasLayer(this.#targetPositionMarker)) - this.#targetPositionMarker.removeFrom(getMap()); + if (getApp().getMap().hasLayer(this.#targetPositionMarker)) + this.#targetPositionMarker.removeFrom(getApp().getMap()); - if (getMap().hasLayer(this.#targetPositionPolyline)) - this.#targetPositionPolyline.removeFrom(getMap()); + if (getApp().getMap().hasLayer(this.#targetPositionPolyline)) + this.#targetPositionPolyline.removeFrom(getApp().getMap()); } #onZoom() { diff --git a/client/src/unit/unitsmanager.ts b/client/src/unit/unitsmanager.ts index cf1808a3..c0a0f6d5 100644 --- a/client/src/unit/unitsmanager.ts +++ b/client/src/unit/unitsmanager.ts @@ -1,18 +1,19 @@ import { LatLng, LatLngBounds } from "leaflet"; -import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler, getUnitsManager, getWeaponsManager } from ".."; +import { getApp } from ".."; import { Unit } from "./unit"; -import { cloneUnits, deleteUnit, spawnAircrafts, spawnGroundUnits, spawnHelicopters, spawnNavyUnits } from "../server/server"; +import { cloneUnits, spawnAircrafts, spawnGroundUnits, spawnHelicopters, spawnNavyUnits } from "../server/server"; import { bearingAndDistanceToLatLng, deg2rad, getUnitDatabaseByCategory, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polyContains, polygonArea, randomPointInPoly, randomUnitBlueprint } from "../other/utils"; import { CoalitionArea } from "../map/coalitionarea/coalitionarea"; import { groundUnitDatabase } from "./databases/groundunitdatabase"; import { DataIndexes, GAME_MASTER, IADSDensities, IDLE, MOVE_UNIT } from "../constants/constants"; import { DataExtractor } from "../server/dataextractor"; -import { Contact, UnitData, UnitSpawnTable } from "../@types/unit"; import { citiesDatabase } from "./citiesDatabase"; import { aircraftDatabase } from "./databases/aircraftdatabase"; import { helicopterDatabase } from "./databases/helicopterdatabase"; import { navyUnitDatabase } from "./databases/navyunitdatabase"; import { TemporaryUnitMarker } from "../map/markers/temporaryunitmarker"; +import { Popup } from "../popups/popup"; +import { HotgroupPanel } from "../panels/hotgrouppanel"; /** The UnitsManager handles the creation, update, and control of units. Data is strictly updated by the server ONLY. This means that any interaction from the user will always and only * result in a command to the server, executed by means of a REST PUT request. Any subsequent change in data will be reflected only when the new data is sent back by the server. This strategy allows @@ -124,12 +125,12 @@ export class UnitsManager { /* If we are not in Game Master mode, visibility of units by the user is determined by the detections of the units themselves. This is performed here. This operation is computationally expensive, therefore it is only performed when #requestDetectionUpdate is true. This happens whenever a change in the detectionUpdates is detected */ - if (this.#requestDetectionUpdate && getMissionHandler().getCommandModeOptions().commandMode != GAME_MASTER) { + if (this.#requestDetectionUpdate && getApp().getMissionManager().getCommandModeOptions().commandMode != GAME_MASTER) { /* Create a dictionary of empty detection methods arrays */ var detectionMethods: { [key: string]: number[] } = {}; for (let ID in this.#units) detectionMethods[ID] = []; - for (let ID in getWeaponsManager().getWeapons()) + for (let ID in getApp().getWeaponsManager().getWeapons()) detectionMethods[ID] = []; /* Fill the array with the detection methods */ @@ -152,8 +153,8 @@ export class UnitsManager { } /* Set the detection methods for every weapon (weapons must be detected too) */ - for (let ID in getWeaponsManager().getWeapons()) { - const weapon = getWeaponsManager().getWeaponByID(parseInt(ID)); + for (let ID in getApp().getWeaponsManager().getWeapons()) { + const weapon = getApp().getWeaponsManager().getWeaponByID(parseInt(ID)); weapon?.setDetectionMethods(detectionMethods[ID]); } @@ -636,7 +637,7 @@ export class UnitsManager { } cloneUnits(units, true, 0 /* No spawn points, we delete the original units */); } else { - getInfoPopup().setText(`Groups can only be created from units of the same category`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Groups can only be created from units of the same category`); } } @@ -659,7 +660,7 @@ export class UnitsManager { selectedUnits[idx].setHotgroup(hotgroup); } this.#showActionMessage(selectedUnits, `added to hotgroup ${hotgroup}`); - getHotgroupPanel().refreshHotgroups(); + (getApp().getPanelsManager().get("hotgroup") as HotgroupPanel).refreshHotgroups(); } /** Delete the selected units @@ -730,7 +731,7 @@ export class UnitsManager { selectedUnitsCopy() { /* A JSON is used to deepcopy the units, creating a "snapshot" of their properties at the time of the copy */ this.#copiedUnits = JSON.parse(JSON.stringify(this.getSelectedUnits().map((unit: Unit) => { return unit.getData() }))); /* Can be applied to humans too */ - getInfoPopup().setText(`${this.#copiedUnits.length} units copied`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`${this.#copiedUnits.length} units copied`); } /*********************** Unit manipulation functions ************************/ @@ -742,9 +743,9 @@ export class UnitsManager { let spawnPoints = 0; /* If spawns are restricted, check that the user has the necessary spawn points */ - if (getMissionHandler().getCommandModeOptions().commandMode != GAME_MASTER) { - if (getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0) { - getInfoPopup().setText(`Units can be pasted only during SETUP phase`); + if (getApp().getMissionManager().getCommandModeOptions().commandMode != GAME_MASTER) { + if (getApp().getMissionManager().getCommandModeOptions().restrictSpawns && getApp().getMissionManager().getRemainingSetupTime() < 0) { + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Units can be pasted only during SETUP phase`); return false; } @@ -754,8 +755,8 @@ export class UnitsManager { spawnPoints += unitSpawnPoints; }) - if (spawnPoints > getMissionHandler().getAvailableSpawnPoints()) { - getInfoPopup().setText("Not enough spawn points available!"); + if (spawnPoints > getApp().getMissionManager().getAvailableSpawnPoints()) { + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Not enough spawn points available!"); return false; } } @@ -784,8 +785,8 @@ export class UnitsManager { var units: { ID: number, location: LatLng }[] = []; let markers: TemporaryUnitMarker[] = []; groups[groupName].forEach((unit: UnitData) => { - var position = new LatLng(getMap().getMouseCoordinates().lat + unit.position.lat - avgLat, getMap().getMouseCoordinates().lng + unit.position.lng - avgLng); - markers.push(getMap().addTemporaryMarker(position, unit.name, unit.coalition)); + var position = new LatLng(getApp().getMap().getMouseCoordinates().lat + unit.position.lat - avgLat, getApp().getMap().getMouseCoordinates().lng + unit.position.lng - avgLng); + markers.push(getApp().getMap().addTemporaryMarker(position, unit.name, unit.coalition)); units.push({ ID: unit.ID, location: position }); }); @@ -797,10 +798,10 @@ export class UnitsManager { } }); } - getInfoPopup().setText(`${this.#copiedUnits.length} units pasted`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`${this.#copiedUnits.length} units pasted`); } else { - getInfoPopup().setText("No units copied!"); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("No units copied!"); } } @@ -888,7 +889,7 @@ export class UnitsManager { var units = aliveUnits.map((unit: UnitData) => { return { unitType: unit.name, location: unit.position, liveryID: "" } }); - getUnitsManager().spawnUnits(groups[groupName][0].category, units, groups[groupName][0].coalition, true); + getApp().getUnitsManager().spawnUnits(groups[groupName][0].category, units, groups[groupName][0].coalition, true); } } }; @@ -911,18 +912,18 @@ export class UnitsManager { spawnUnits(category: string, units: UnitSpawnTable[], coalition: string = "blue", immediate: boolean = true, airbase: string = "", country: string = "", callback: CallableFunction = () => {}) { var spawnPoints = 0; var spawnFunction = () => {}; - var spawnsRestricted = getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER; + var spawnsRestricted = getApp().getMissionManager().getCommandModeOptions().restrictSpawns && getApp().getMissionManager().getRemainingSetupTime() < 0 && getApp().getMissionManager().getCommandModeOptions().commandMode !== GAME_MASTER; if (category === "Aircraft") { if (airbase == "" && spawnsRestricted) { - getInfoPopup().setText("Aircrafts can be air spawned during the SETUP phase only"); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Aircrafts can be air spawned during the SETUP phase only"); return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + aircraftDatabase.getSpawnPointsByName(unit.unitType)}, 0); spawnFunction = () => spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints, callback); } else if (category === "Helicopter") { if (airbase == "" && spawnsRestricted) { - getInfoPopup().setText("Helicopters can be air spawned during the SETUP phase only"); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Helicopters can be air spawned during the SETUP phase only"); return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + helicopterDatabase.getSpawnPointsByName(unit.unitType)}, 0); @@ -930,7 +931,7 @@ export class UnitsManager { } else if (category === "GroundUnit") { if (spawnsRestricted) { - getInfoPopup().setText("Ground units can be spawned during the SETUP phase only"); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Ground units can be spawned during the SETUP phase only"); return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0); @@ -938,19 +939,19 @@ export class UnitsManager { } else if (category === "NavyUnit") { if (spawnsRestricted) { - getInfoPopup().setText("Navy units can be spawned during the SETUP phase only"); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Navy units can be spawned during the SETUP phase only"); return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0); spawnFunction = () => spawnNavyUnits(units, coalition, country, immediate, spawnPoints, callback); } - if (spawnPoints <= getMissionHandler().getAvailableSpawnPoints()) { - getMissionHandler().setSpentSpawnPoints(spawnPoints); + if (spawnPoints <= getApp().getMissionManager().getAvailableSpawnPoints()) { + getApp().getMissionManager().setSpentSpawnPoints(spawnPoints); spawnFunction(); return true; } else { - getInfoPopup().setText("Not enough spawn points available!"); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Not enough spawn points available!"); return false; } } @@ -969,7 +970,7 @@ export class UnitsManager { if (this.getSelectedUnits().length > 0) { /* Disable the firing of the selection event for a certain amount of time. This avoids firing many events if many units are selected */ if (!this.#selectionEventDisabled) { - getMap().setState(MOVE_UNIT); + getApp().getMap().setState(MOVE_UNIT); window.setTimeout(() => { document.dispatchEvent(new CustomEvent("unitsSelection", { detail: this.getSelectedUnits() })); this.#selectionEventDisabled = false; @@ -978,14 +979,14 @@ export class UnitsManager { } } else { - getMap().setState(IDLE); + getApp().getMap().setState(IDLE); document.dispatchEvent(new CustomEvent("clearSelection")); } } #onUnitDeselection(unit: Unit) { if (this.getSelectedUnits().length == 0) { - getMap().setState(IDLE); + getApp().getMap().setState(IDLE); document.dispatchEvent(new CustomEvent("clearSelection")); } else @@ -994,8 +995,8 @@ export class UnitsManager { #showActionMessage(units: Unit[], message: string) { if (units.length == 1) - getInfoPopup().setText(`${units[0].getUnitName()} ${message}`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`${units[0].getUnitName()} ${message}`); else if (units.length > 1) - getInfoPopup().setText(`${units[0].getUnitName()} and ${units.length - 1} other units ${message}`); + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`${units[0].getUnitName()} and ${units.length - 1} other units ${message}`); } } \ No newline at end of file diff --git a/client/src/weapon/weapon.ts b/client/src/weapon/weapon.ts index 777afea3..139a1651 100644 --- a/client/src/weapon/weapon.ts +++ b/client/src/weapon/weapon.ts @@ -1,10 +1,9 @@ import { LatLng, DivIcon, Map } from 'leaflet'; -import { getMap, getMissionHandler, getUnitsManager } from '..'; +import { getApp } from '..'; import { enumToCoalition, mToFt, msToKnots, rad2deg } from '../other/utils'; import { CustomMarker } from '../map/markers/custommarker'; import { SVGInjector } from '@tanem/svg-injector'; import { DLINK, DataIndexes, GAME_MASTER, IRST, OPTIC, RADAR, VISUAL } from '../constants/constants'; -import { ObjectIconOptions } from '../@types/unit'; import { DataExtractor } from '../server/dataextractor'; export class Weapon extends CustomMarker { @@ -58,7 +57,7 @@ export class Weapon extends CustomMarker { /********************** Unit data *************************/ setData(dataExtractor: DataExtractor) { - var updateMarker = !getMap().hasLayer(this); + var updateMarker = !getApp().getMap().hasLayer(this); var datumIndex = 0; while (datumIndex != DataIndexes.endOfData) { @@ -116,7 +115,7 @@ export class Weapon extends CustomMarker { } belongsToCommandedCoalition() { - if (getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER && getMissionHandler().getCommandedCoalition() !== this.#coalition) + if (getApp().getMissionManager().getCommandModeOptions().commandMode !== GAME_MASTER && getApp().getMissionManager().getCommandedCoalition() !== this.#coalition) return false; return true; } @@ -166,7 +165,7 @@ export class Weapon extends CustomMarker { /********************** Visibility *************************/ updateVisibility() { - const hiddenUnits = getMap().getHiddenTypes(); + const hiddenUnits = getApp().getMap().getHiddenTypes(); var hidden = (hiddenUnits.includes(this.getMarkerCategory())) || (hiddenUnits.includes(this.#coalition)) || (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0); @@ -178,16 +177,16 @@ export class Weapon extends CustomMarker { this.#hidden = hidden; /* Add the marker if not present */ - if (!getMap().hasLayer(this) && !this.getHidden()) { - if (getMap().isZooming()) - this.once("zoomend", () => {this.addTo(getMap())}) + if (!getApp().getMap().hasLayer(this) && !this.getHidden()) { + if (getApp().getMap().isZooming()) + this.once("zoomend", () => {this.addTo(getApp().getMap())}) else - this.addTo(getMap()); + this.addTo(getApp().getMap()); } /* Hide the marker if necessary*/ - if (getMap().hasLayer(this) && this.getHidden()) { - getMap().removeLayer(this); + if (getApp().getMap().hasLayer(this) && this.getHidden()) { + getApp().getMap().removeLayer(this); } } @@ -250,7 +249,7 @@ export class Weapon extends CustomMarker { } /* Set vertical offset for altitude stacking */ - var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); + var pos = getApp().getMap().latLngToLayerPoint(this.getLatLng()).round(); this.setZIndexOffset(1000 + Math.floor(this.#position.alt as number) - pos.y); } } diff --git a/client/src/weapon/weaponsmanager.ts b/client/src/weapon/weaponsmanager.ts index 57b6e48d..4de95b38 100644 --- a/client/src/weapon/weaponsmanager.ts +++ b/client/src/weapon/weaponsmanager.ts @@ -1,8 +1,7 @@ -import { getMissionHandler, getUnitsManager } from ".."; +import { getApp } from ".."; import { Weapon } from "./weapon"; import { DataIndexes, GAME_MASTER } from "../constants/constants"; import { DataExtractor } from "../server/dataextractor"; -import { Contact } from "../@types/unit"; /** The WeaponsManager handles the creation and update of weapons. Data is strictly updated by the server ONLY. */ export class WeaponsManager { @@ -93,7 +92,7 @@ export class WeaponsManager { */ getWeaponDetectedMethods(weapon: Weapon) { var detectionMethods: number[] = []; - var units = getUnitsManager().getUnits(); + var units = getApp().getUnitsManager().getUnits(); for (let idx in units) { if (units[idx].getAlive() && units[idx].getIsLeader() && units[idx].getCoalition() !== "neutral" && units[idx].getCoalition() != weapon.getCoalition()) { diff --git a/client/tsconfig.json b/client/tsconfig.json index c293f5f2..63da637e 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -23,19 +23,22 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ "module": "commonjs", /* Specify what module code is generated. */ - "rootDir": "./src", /* Specify the root folder within your source files. */ + "rootDirs": ["./src", "./@types"], /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ "typeRoots": [ - "./node_modules/@types" + "./node_modules/@types", + "./@types" ], /* Specify multiple folders that act like './node_modules/@types'. */ "types": [ "leaflet", "geojson", "node", - "formatcoords" + "formatcoords", + "olympus", + "dom" ], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ @@ -100,6 +103,7 @@ "skipLibCheck": true /* Skip type checking all .d.ts files. */ }, "include": [ - "src/**/*.ts" + "src/**/*.ts", + "@types/*.d.ts" ] } \ No newline at end of file diff --git a/client/views/aic/aic.ejs b/client/views/aic/aic.ejs deleted file mode 100644 index 229a5a82..00000000 --- a/client/views/aic/aic.ejs +++ /dev/null @@ -1,52 +0,0 @@ -
-
-
-
- -
-
×
-
AIC Help
-
-

How to be a good AIC and get people to do stuff good, too.

-
-
[DCS with Volvo video]
-
-
-
- -
- -
- -
-

My callsign

-
Magic
-
- -
- - -
- -
-

Control

-
- - -
-
- - -
-
- -
- -

Formations

- -
- -
- -
\ No newline at end of file diff --git a/client/views/atc/addflight.ejs b/client/views/atc/addflight.ejs deleted file mode 100644 index 97e1ae5b..00000000 --- a/client/views/atc/addflight.ejs +++ /dev/null @@ -1,5 +0,0 @@ -
-
- - -
\ No newline at end of file diff --git a/client/views/atc/atc.ejs b/client/views/atc/atc.ejs deleted file mode 100644 index 65984a3a..00000000 --- a/client/views/atc/atc.ejs +++ /dev/null @@ -1,11 +0,0 @@ -<%- include('board.ejs', { - "boardId": "strip-board-tower", - "boardType": "tower", - "headers": [ "Flight", "a. Alt", "alt", "a. Speed", "Speed" ] -}) %> - -<%- include('board.ejs', { - "boardId": "strip-board-ground", - "boardType": "ground", - "headers": [ "Flight", "Status", "T/O Time", "TTG" ] -}) %> \ No newline at end of file diff --git a/client/views/atc/board.ejs b/client/views/atc/board.ejs deleted file mode 100644 index 58d3dfcc..00000000 --- a/client/views/atc/board.ejs +++ /dev/null @@ -1,22 +0,0 @@ -
- -
- -
-

<%= boardType %>

- <%- include('addflight.ejs') %> -
-
- -
-
-
- <% headers.forEach( header => { %> -
<%= header %>
- <% }); %> -
-
-
-
- -
\ No newline at end of file diff --git a/client/views/atc/unitdatatable.ejs b/client/views/atc/unitdatatable.ejs deleted file mode 100644 index 0c090652..00000000 --- a/client/views/atc/unitdatatable.ejs +++ /dev/null @@ -1,13 +0,0 @@ -
- -
- -
-

Unit list

-
- -
- -
- -
\ No newline at end of file diff --git a/client/views/index.ejs b/client/views/index.ejs index e78b0a48..2c08cc48 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -23,9 +23,6 @@ - - <%- include('other/controltips.ejs') %> - <%- include('panels/unitcontrol.ejs') %> <%- include('panels/unitinfo.ejs') %> <%- include('panels/mouseinfo.ejs') %> diff --git a/client/views/other/controltips.ejs b/client/views/other/controltips.ejs deleted file mode 100644 index 463b5c1d..00000000 --- a/client/views/other/controltips.ejs +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file From 2f125e3d0eb4e432b8d200f963f56bb0bbe4f981 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Fri, 15 Sep 2023 23:07:15 +0200 Subject: [PATCH 11/12] Completed plugins framework More work required to define all interfaces for the useful classes in the @types folder --- .gitignore | 3 +- client/plugins/controltips/index.js | 90 ++++--- .../{controltips.ts => controltipsplugin.ts} | 24 +- client/plugins/controltips/src/index.ts | 2 +- .../public/plugins/controltipsplugin/index.js | 252 ------------------ .../plugins/controltipsplugin/plugin.json | 6 - .../plugins/controltipsplugin/style.css | 33 --- client/public/stylesheets/olympus.css | 1 - client/public/stylesheets/style/style.css | 11 - client/src/app.ts | 131 ++++++++- client/src/constants/constants.ts | 1 - client/src/controls/dropdown.ts | 4 + client/src/index.ts | 158 ++--------- client/src/map/map.ts | 25 +- client/src/plugin/pluginmanager.ts | 34 ++- 15 files changed, 244 insertions(+), 531 deletions(-) rename client/plugins/controltips/src/{controltips.ts => controltipsplugin.ts} (94%) delete mode 100644 client/public/plugins/controltipsplugin/index.js delete mode 100644 client/public/plugins/controltipsplugin/plugin.json delete mode 100644 client/public/plugins/controltipsplugin/style.css diff --git a/.gitignore b/.gitignore index 12d0171d..f58d9ee8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ Output node_modules /client/TODO.txt /client/public/javascripts/bundle.js -!client/bin \ No newline at end of file +!client/bin +/client/public/plugins diff --git a/client/plugins/controltips/index.js b/client/plugins/controltips/index.js index 90ee53e6..37ad45af 100644 --- a/client/plugins/controltips/index.js +++ b/client/plugins/controltips/index.js @@ -11,68 +11,72 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function ( if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; -var _ControlTips_instances, _ControlTips_element, _ControlTips_app, _ControlTips_shortcutManager, _ControlTips_cursorIsHoveringOverUnit, _ControlTips_cursorIsHoveringOverAirbase, _ControlTips_updateTips; +var _ControlTipsPlugin_instances, _ControlTipsPlugin_element, _ControlTipsPlugin_app, _ControlTipsPlugin_shortcutManager, _ControlTipsPlugin_cursorIsHoveringOverUnit, _ControlTipsPlugin_cursorIsHoveringOverAirbase, _ControlTipsPlugin_updateTips; Object.defineProperty(exports, "__esModule", { value: true }); -exports.ControlTips = void 0; -class ControlTips { +exports.ControlTipsPlugin = void 0; +const SHOW_CONTROL_TIPS = "Show control tips"; +class ControlTipsPlugin { constructor() { - _ControlTips_instances.add(this); - _ControlTips_element.set(this, void 0); - _ControlTips_app.set(this, void 0); - _ControlTips_shortcutManager.set(this, void 0); - _ControlTips_cursorIsHoveringOverUnit.set(this, false); - _ControlTips_cursorIsHoveringOverAirbase.set(this, false); - __classPrivateFieldSet(this, _ControlTips_element, document.createElement("div"), "f"); - __classPrivateFieldGet(this, _ControlTips_element, "f").id = "control-tips-panel"; - document.body.appendChild(__classPrivateFieldGet(this, _ControlTips_element, "f")); - console.log("HELLO"); + _ControlTipsPlugin_instances.add(this); + _ControlTipsPlugin_element.set(this, void 0); + _ControlTipsPlugin_app.set(this, void 0); + _ControlTipsPlugin_shortcutManager.set(this, void 0); + _ControlTipsPlugin_cursorIsHoveringOverUnit.set(this, false); + _ControlTipsPlugin_cursorIsHoveringOverAirbase.set(this, false); + __classPrivateFieldSet(this, _ControlTipsPlugin_element, document.createElement("div"), "f"); + __classPrivateFieldGet(this, _ControlTipsPlugin_element, "f").id = "control-tips-panel"; + document.body.appendChild(__classPrivateFieldGet(this, _ControlTipsPlugin_element, "f")); } getName() { return "Control Tips Plugin"; } initialize(app) { - __classPrivateFieldSet(this, _ControlTips_app, app, "f"); - __classPrivateFieldSet(this, _ControlTips_shortcutManager, __classPrivateFieldGet(this, _ControlTips_app, "f").getShortcutManager(), "f"); - __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").onKeyDown(() => { - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + __classPrivateFieldSet(this, _ControlTipsPlugin_app, app, "f"); + __classPrivateFieldSet(this, _ControlTipsPlugin_shortcutManager, __classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getShortcutManager(), "f"); + __classPrivateFieldGet(this, _ControlTipsPlugin_shortcutManager, "f").onKeyDown(() => { + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); }); - __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").onKeyUp(() => { - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + __classPrivateFieldGet(this, _ControlTipsPlugin_shortcutManager, "f").onKeyUp(() => { + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); }); document.addEventListener("airbaseMouseover", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, true, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + __classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverAirbase, true, "f"); + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); }); document.addEventListener("airbaseMouseout", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, false, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + __classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverAirbase, false, "f"); + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); + }); + document.addEventListener("unitDeselection", (ev) => { + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); }); - //document.addEventListener("unitDeselection", (ev: CustomEvent) => { - // this.#updateTips(); - //}); document.addEventListener("unitMouseover", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, true, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + __classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverUnit, true, "f"); + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); }); document.addEventListener("unitMouseout", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, false, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + __classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverUnit, false, "f"); + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); }); - //document.addEventListener("unitSelection", (ev: CustomEvent) => { - // this.#updateTips() - //}); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); + document.addEventListener("unitSelection", (ev) => { + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); + }); + document.addEventListener("mapVisibilityOptionsChanged", () => { + this.toggle(!__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getMap().getVisibilityOptions()[SHOW_CONTROL_TIPS]); + }); + __classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this); + __classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getMap().addVisibilityOption(SHOW_CONTROL_TIPS, true); return true; } getElement() { - return __classPrivateFieldGet(this, _ControlTips_element, "f"); + return __classPrivateFieldGet(this, _ControlTipsPlugin_element, "f"); } toggle(bool) { this.getElement().classList.toggle("hide", bool); } } -exports.ControlTips = ControlTips; -_ControlTips_element = new WeakMap(), _ControlTips_app = new WeakMap(), _ControlTips_shortcutManager = new WeakMap(), _ControlTips_cursorIsHoveringOverUnit = new WeakMap(), _ControlTips_cursorIsHoveringOverAirbase = new WeakMap(), _ControlTips_instances = new WeakSet(), _ControlTips_updateTips = function _ControlTips_updateTips() { +exports.ControlTipsPlugin = ControlTipsPlugin; +_ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap(), _ControlTipsPlugin_shortcutManager = new WeakMap(), _ControlTipsPlugin_cursorIsHoveringOverUnit = new WeakMap(), _ControlTipsPlugin_cursorIsHoveringOverAirbase = new WeakMap(), _ControlTipsPlugin_instances = new WeakSet(), _ControlTipsPlugin_updateTips = function _ControlTipsPlugin_updateTips() { const combos = [ { "keys": [], @@ -205,13 +209,13 @@ _ControlTips_element = new WeakMap(), _ControlTips_app = new WeakMap(), _Control ] } ]; - const currentCombo = combos.find((combo) => __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").keyComboMatches(combo.keys)) || combos[0]; + const currentCombo = combos.find((combo) => __classPrivateFieldGet(this, _ControlTipsPlugin_shortcutManager, "f").keyComboMatches(combo.keys)) || combos[0]; const element = this.getElement(); element.innerHTML = ""; let numSelectedUnits = 0; let unitSelectionContainsControlled = false; - if (__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager()) { - let selectedUnits = Object.values(__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager().getSelectedUnits()); + if (__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getUnitsManager()) { + let selectedUnits = Object.values(__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getUnitsManager().getSelectedUnits()); numSelectedUnits = selectedUnits.length; unitSelectionContainsControlled = selectedUnits.some((unit) => unit.getControlled()); } @@ -228,12 +232,12 @@ _ControlTips_element = new WeakMap(), _ControlTips_app = new WeakMap(), _Control return; } if (typeof tip.showIfHoveringOverAirbase === "boolean") { - if (tip.showIfHoveringOverAirbase !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverAirbase, "f")) { + if (tip.showIfHoveringOverAirbase !== __classPrivateFieldGet(this, _ControlTipsPlugin_cursorIsHoveringOverAirbase, "f")) { return; } } if (typeof tip.showIfHoveringOverUnit === "boolean") { - if (tip.showIfHoveringOverUnit !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverUnit, "f")) { + if (tip.showIfHoveringOverUnit !== __classPrivateFieldGet(this, _ControlTipsPlugin_cursorIsHoveringOverUnit, "f")) { return; } } @@ -246,7 +250,7 @@ _ControlTips_element = new WeakMap(), _ControlTips_app = new WeakMap(), _Control Object.defineProperty(exports, "__esModule", { value: true }); const controltips_1 = require("./controltips"); globalThis.getOlympusPlugin = () => { - return new controltips_1.ControlTips(); + return new controltips_1.ControlTipsPlugin(); }; },{"./controltips":1}]},{},[2]); diff --git a/client/plugins/controltips/src/controltips.ts b/client/plugins/controltips/src/controltipsplugin.ts similarity index 94% rename from client/plugins/controltips/src/controltips.ts rename to client/plugins/controltips/src/controltipsplugin.ts index 9e885247..2eeba8ff 100644 --- a/client/plugins/controltips/src/controltips.ts +++ b/client/plugins/controltips/src/controltipsplugin.ts @@ -1,3 +1,5 @@ +const SHOW_CONTROL_TIPS = "Show control tips" + export class ControlTipsPlugin implements OlympusPlugin { #element: HTMLElement; #app: any; @@ -9,8 +11,6 @@ export class ControlTipsPlugin implements OlympusPlugin { this.#element = document.createElement("div"); this.#element.id = "control-tips-panel"; document.body.appendChild(this.#element); - - console.log("HELLO") } getName() { @@ -40,9 +40,9 @@ export class ControlTipsPlugin implements OlympusPlugin { this.#updateTips(); }); - //document.addEventListener("unitDeselection", (ev: CustomEvent) => { - // this.#updateTips(); - //}); + document.addEventListener("unitDeselection", (ev: CustomEvent) => { + this.#updateTips(); + }); document.addEventListener("unitMouseover", (ev: CustomEventInit) => { this.#cursorIsHoveringOverUnit = true; @@ -54,12 +54,18 @@ export class ControlTipsPlugin implements OlympusPlugin { this.#updateTips(); }); - //document.addEventListener("unitSelection", (ev: CustomEvent) => { - // this.#updateTips() - //}); + document.addEventListener("unitSelection", (ev: CustomEvent) => { + this.#updateTips() + }); + + document.addEventListener("mapVisibilityOptionsChanged", () => { + this.toggle( !this.#app.getMap().getVisibilityOptions()[SHOW_CONTROL_TIPS] ); + }); this.#updateTips(); + this.#app.getMap().addVisibilityOption(SHOW_CONTROL_TIPS, true); + return true; } @@ -72,7 +78,6 @@ export class ControlTipsPlugin implements OlympusPlugin { } #updateTips() { - const combos: Array = [ { "keys": [], @@ -249,7 +254,6 @@ export class ControlTipsPlugin implements OlympusPlugin { } element.innerHTML += `
${tip.key}${tip.action}
` - }); } } \ No newline at end of file diff --git a/client/plugins/controltips/src/index.ts b/client/plugins/controltips/src/index.ts index d6372eb6..425907e0 100644 --- a/client/plugins/controltips/src/index.ts +++ b/client/plugins/controltips/src/index.ts @@ -1,4 +1,4 @@ -import { ControlTipsPlugin } from "./controltips"; +import { ControlTipsPlugin } from "./controltipsplugin"; globalThis.getOlympusPlugin = () => { return new ControlTipsPlugin(); diff --git a/client/public/plugins/controltipsplugin/index.js b/client/public/plugins/controltipsplugin/index.js deleted file mode 100644 index 90ee53e6..00000000 --- a/client/public/plugins/controltipsplugin/index.js +++ /dev/null @@ -1,252 +0,0 @@ -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i { - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); - }); - __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").onKeyUp(() => { - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); - }); - document.addEventListener("airbaseMouseover", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, true, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); - }); - document.addEventListener("airbaseMouseout", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverAirbase, false, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); - }); - //document.addEventListener("unitDeselection", (ev: CustomEvent) => { - // this.#updateTips(); - //}); - document.addEventListener("unitMouseover", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, true, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); - }); - document.addEventListener("unitMouseout", (ev) => { - __classPrivateFieldSet(this, _ControlTips_cursorIsHoveringOverUnit, false, "f"); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); - }); - //document.addEventListener("unitSelection", (ev: CustomEvent) => { - // this.#updateTips() - //}); - __classPrivateFieldGet(this, _ControlTips_instances, "m", _ControlTips_updateTips).call(this); - return true; - } - getElement() { - return __classPrivateFieldGet(this, _ControlTips_element, "f"); - } - toggle(bool) { - this.getElement().classList.toggle("hide", bool); - } -} -exports.ControlTips = ControlTips; -_ControlTips_element = new WeakMap(), _ControlTips_app = new WeakMap(), _ControlTips_shortcutManager = new WeakMap(), _ControlTips_cursorIsHoveringOverUnit = new WeakMap(), _ControlTips_cursorIsHoveringOverAirbase = new WeakMap(), _ControlTips_instances = new WeakSet(), _ControlTips_updateTips = function _ControlTips_updateTips() { - const combos = [ - { - "keys": [], - "tips": [ - { - "key": `SHIFT`, - "action": `Box select`, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": false, - "showIfUnitSelected": false - }, - { - "key": `Mouse1`, - "action": `Deselect`, - "showIfUnitSelected": true - }, - { - "key": `Mouse1+drag`, - "action": `Move map`, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": false, - "showIfUnitSelected": false - }, - { - "key": `Mouse2`, - "action": `Spawn menu`, - "showIfUnitSelected": false, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": false - }, - { - "key": `Mouse2`, - "action": `Quick options`, - "showIfUnitSelected": false, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": true - }, - { - "key": `Mouse2`, - "action": `Airbase menu`, - "showIfUnitSelected": false, - "showIfHoveringOverAirbase": true, - "showIfHoveringOverUnit": false - }, - { - "key": `Mouse2`, - "action": `Set first waypoint`, - "showIfHoveringOverAirbase": false, - "showIfUnitSelected": true, - "unitsMustBeControlled": true - }, - { - "key": "CTRL+Mouse2", - "action": "Add waypoint", - "showIfUnitSelected": true, - "showIfHoveringOverAirbase": false, - "unitsMustBeControlled": true - }, - { - "key": `Mouse2 (hold)`, - "action": `Point operations`, - "showIfUnitSelected": true, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": false, - "unitsMustBeControlled": true - }, - { - "key": "CTRL", - "action": " Pin tool", - "showIfUnitSelected": false, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": false, - "unitsMustBeControlled": true - }, - { - "key": "CTRL+Mouse2", - "action": " Airbase menu", - "showIfUnitSelected": true, - "showIfHoveringOverAirbase": true, - "unitsMustBeControlled": true - }, - { - "key": `Delete`, - "action": `Delete unit`, - "showIfHoveringOverAirbase": false, - "showIfUnitSelected": true - } - ] - }, - { - "keys": ["ControlLeft"], - "tips": [ - { - "key": `Mouse1`, - "action": "Toggle pin", - "showIfUnitSelected": false, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": false - }, - { - "key": `Mouse1`, - "action": "Toggle selection", - "showIfUnitSelected": true, - "showIfHoveringOverAirbase": false, - "showIfHoveringOverUnit": true - }, - { - "key": `Mouse2`, - "action": `Add waypoint`, - "showIfHoveringOverAirbase": false, - "showIfUnitSelected": true, - "unitsMustBeControlled": true - }, - { - "key": `Mouse2`, - "action": `Airbase menu`, - "showIfHoveringOverAirbase": true, - "showIfUnitSelected": true, - "unitsMustBeControlled": true - } - ] - }, - { - "keys": ["ShiftLeft"], - "tips": [ - { - "key": `mouse1+drag`, - "action": "Box select" - } - ] - } - ]; - const currentCombo = combos.find((combo) => __classPrivateFieldGet(this, _ControlTips_shortcutManager, "f").keyComboMatches(combo.keys)) || combos[0]; - const element = this.getElement(); - element.innerHTML = ""; - let numSelectedUnits = 0; - let unitSelectionContainsControlled = false; - if (__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager()) { - let selectedUnits = Object.values(__classPrivateFieldGet(this, _ControlTips_app, "f").getUnitsManager().getSelectedUnits()); - numSelectedUnits = selectedUnits.length; - unitSelectionContainsControlled = selectedUnits.some((unit) => unit.getControlled()); - } - currentCombo.tips.forEach((tip) => { - if (numSelectedUnits > 0) { - if (tip.showIfUnitSelected === false) { - return; - } - if (tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false) { - return; - } - } - if (numSelectedUnits === 0 && tip.showIfUnitSelected === true) { - return; - } - if (typeof tip.showIfHoveringOverAirbase === "boolean") { - if (tip.showIfHoveringOverAirbase !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverAirbase, "f")) { - return; - } - } - if (typeof tip.showIfHoveringOverUnit === "boolean") { - if (tip.showIfHoveringOverUnit !== __classPrivateFieldGet(this, _ControlTips_cursorIsHoveringOverUnit, "f")) { - return; - } - } - element.innerHTML += `
${tip.key}${tip.action}
`; - }); -}; - -},{}],2:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const controltips_1 = require("./controltips"); -globalThis.getOlympusPlugin = () => { - return new controltips_1.ControlTips(); -}; - -},{"./controltips":1}]},{},[2]); diff --git a/client/public/plugins/controltipsplugin/plugin.json b/client/public/plugins/controltipsplugin/plugin.json deleted file mode 100644 index 77a1f817..00000000 --- a/client/public/plugins/controltipsplugin/plugin.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Control Tip Plugin", - "version": "0.0.1", - "description": "This plugin shows useful control tips on the right side of the screen. The tips change dynamically depending on what the user does", - "author": "Peekaboo" -} \ No newline at end of file diff --git a/client/public/plugins/controltipsplugin/style.css b/client/public/plugins/controltipsplugin/style.css deleted file mode 100644 index 0ab48856..00000000 --- a/client/public/plugins/controltipsplugin/style.css +++ /dev/null @@ -1,33 +0,0 @@ -#control-tips-panel { - align-self: center; - display: flex; - flex-flow: column wrap; - font-size: 13px; - justify-self: flex-end; - position: absolute; - right: 10px; - row-gap: 20px; - text-align: right; - z-index: 999; -} - -#control-tips-panel>* { - align-items: center; - align-self: end; - background-color: var(--background-steel); - border-radius: var(--border-radius-md); - color: white; - column-gap: 8px; - display: flex; - justify-items: right; - opacity: .9; - padding: 5px; - width: fit-content; -} - -#control-tips-panel>*>.key { - background-color: var(--background-grey); - border-radius: var(--border-radius-sm); - color: white; - padding: 1px 4px; -} \ No newline at end of file diff --git a/client/public/stylesheets/olympus.css b/client/public/stylesheets/olympus.css index eab3e9ba..7e51ec7a 100644 --- a/client/public/stylesheets/olympus.css +++ b/client/public/stylesheets/olympus.css @@ -1,7 +1,6 @@ @import url("layout/layout.css"); @import url("style/style.css"); -@import url("other/controltips.css"); @import url("panels/connectionstatus.css"); @import url("panels/serverstatus.css"); @import url("panels/mouseinfo.css"); diff --git a/client/public/stylesheets/style/style.css b/client/public/stylesheets/style/style.css index 08b8350d..b4866edd 100644 --- a/client/public/stylesheets/style/style.css +++ b/client/public/stylesheets/style/style.css @@ -653,17 +653,6 @@ nav.ol-panel> :last-child { stroke: var(--background-steel) !important; } -#atc-navbar-control { - align-items: center; - display: flex; - flex-direction: column; -} - -#atc-navbar-control button svg { - height: 24px; - width: 24px; -} - #roe-buttons-container button, #reaction-to-threat-buttons-container button, #emissions-countermeasures-buttons-container button { diff --git a/client/src/app.ts b/client/src/app.ts index 3010a884..0f7c611f 100644 --- a/client/src/app.ts +++ b/client/src/app.ts @@ -17,6 +17,9 @@ import { WeaponsManager } from "./weapon/weaponsmanager"; import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants"; import { Manager } from "./other/manager"; +import { ShortcutKeyboard } from "./shortcut/shortcut"; +import { getPaused, setCredentials, setPaused, startUpdate, toggleDemoEnabled } from "./server/server"; +import { SVGInjector } from "@tanem/svg-injector"; export class OlympusApp { /* Global data */ @@ -36,11 +39,11 @@ export class OlympusApp { #shortcutManager: ShortcutManager | null = null; /* UI Toolbars */ - #primaryToolbar: PrimaryToolbar| null = null; - #commandModeToolbar: CommandModeToolbar| null = null; + #primaryToolbar: PrimaryToolbar | null = null; + #commandModeToolbar: CommandModeToolbar | null = null; constructor() { - + } getMap() { @@ -122,7 +125,7 @@ export class OlympusApp { this.#unitsManager = new UnitsManager(); this.#weaponsManager = new WeaponsManager(); this.#missionManager = new MissionManager(); - + this.#shortcutManager = new ShortcutManager(); this.#panelsManager = new Manager(); @@ -136,16 +139,130 @@ export class OlympusApp { .add("mouseInfo", new MouseInfoPanel("mouse-info-panel")) .add("log", new LogPanel("log-panel")) .add("serverStatus", new ServerStatusPanel("server-status-panel")) - .add("unitControl", new UnitControlPanel("unit-control-panel")) + .add("unitControl", new UnitControlPanel("unit-control-panel")) .add("unitInfo", new UnitInfoPanel("unit-info-panel")) - + // Popups this.getPopupsManager().add("infoPopup", new Popup("info-popup")); // Toolbars this.getToolbarsManager().add("primaryToolbar", new PrimaryToolbar("primary-toolbar")) - .add("commandModeToolbar", new PrimaryToolbar("command-mode-toolbar")); + .add("commandModeToolbar", new PrimaryToolbar("command-mode-toolbar")); this.#pluginsManager = new PluginsManager(); + + this.#setupEvents(); + } + + #setupEvents() { + /* Generic clicks */ + document.addEventListener("click", (ev) => { + if (ev instanceof MouseEvent && ev.target instanceof HTMLElement) { + const target = ev.target; + + if (target.classList.contains("olympus-dialog-close")) { + target.closest("div.olympus-dialog")?.classList.add("hide"); + } + + const triggerElement = target.closest("[data-on-click]"); + + if (triggerElement instanceof HTMLElement) { + const eventName: string = triggerElement.dataset.onClick || ""; + let params = JSON.parse(triggerElement.dataset.onClickParams || "{}"); + params._element = triggerElement; + + if (eventName) { + document.dispatchEvent(new CustomEvent(eventName, { + detail: params + })); + } + } + } + }); + + const shortcutManager = this.getShortcutManager(); + shortcutManager.add("toggleDemo", new ShortcutKeyboard({ + "callback": () => { + toggleDemoEnabled(); + }, + "code": "KeyT" + })).add("togglePause", new ShortcutKeyboard({ + "altKey": false, + "callback": () => { + setPaused(!getPaused()); + }, + "code": "Space", + "ctrlKey": false + })); + + ["KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].forEach(code => { + shortcutManager.add(`pan${code}keydown`, new ShortcutKeyboard({ + "altKey": false, + "callback": (ev: KeyboardEvent) => { + this.getMap().handleMapPanning(ev); + }, + "code": code, + "ctrlKey": false, + "event": "keydown" + })); + }); + + ["KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].forEach(code => { + shortcutManager.add(`pan${code}keyup`, new ShortcutKeyboard({ + "callback": (ev: KeyboardEvent) => { + this.getMap().handleMapPanning(ev); + }, + "code": code + })); + }); + + ["Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9"].forEach(code => { + shortcutManager.add(`hotgroup${code}`, new ShortcutKeyboard({ + "callback": (ev: KeyboardEvent) => { + if (ev.ctrlKey && ev.shiftKey) + this.getUnitsManager().selectedUnitsAddToHotgroup(parseInt(ev.code.substring(5))); + else if (ev.ctrlKey && !ev.shiftKey) + this.getUnitsManager().selectedUnitsSetHotgroup(parseInt(ev.code.substring(5))); + else + this.getUnitsManager().selectUnitsByHotgroup(parseInt(ev.code.substring(5))); + }, + "code": code + })); + }); + + // TODO: move from here in dedicated class + document.addEventListener("closeDialog", (ev: CustomEventInit) => { + ev.detail._element.closest(".ol-dialog").classList.add("hide"); + }); + + /* Try and connect with the Olympus REST server */ + document.addEventListener("tryConnection", () => { + const form = document.querySelector("#splash-content")?.querySelector("#authentication-form"); + const username = (form?.querySelector("#username") as HTMLInputElement).value; + const password = (form?.querySelector("#password") as HTMLInputElement).value; + + /* Update the user credentials */ + setCredentials(username, password); + + /* Start periodically requesting updates */ + startUpdate(); + + this.setLoginStatus("connecting"); + }) + + /* Reload the page, used to mimic a restart of the app */ + document.addEventListener("reloadPage", () => { + location.reload(); + }) + + /* Inject the svgs with the corresponding svg code. This allows to dynamically manipulate the svg, like changing colors */ + document.querySelectorAll("[inject-svg]").forEach((el: Element) => { + var img = el as HTMLImageElement; + var isLoaded = img.complete; + if (isLoaded) + SVGInjector(img); + else + img.addEventListener("load", () => { SVGInjector(img); }); + }) } } \ No newline at end of file diff --git a/client/src/constants/constants.ts b/client/src/constants/constants.ts index 20bbbeeb..608dcd73 100644 --- a/client/src/constants/constants.ts +++ b/client/src/constants/constants.ts @@ -153,7 +153,6 @@ export const IADSDensities: {[key: string]: number}= {"AAA": 0.8, "MANPADS": 0.3 export const SHOW_CONTACT_LINES = "Show unit contact lines"; export const HIDE_GROUP_MEMBERS = "Hide group members when zoomed out"; -export const SHOW_CONTROL_TIPS = "Show control tips"; export const SHOW_UNIT_LABELS = "Show unit labels"; export const SHOW_UNIT_PATHS = "Show unit paths"; export const SHOW_UNIT_TARGETS = "Show unit targets"; diff --git a/client/src/controls/dropdown.ts b/client/src/controls/dropdown.ts index f203691f..c7823856 100644 --- a/client/src/controls/dropdown.ts +++ b/client/src/controls/dropdown.ts @@ -68,6 +68,10 @@ export class Dropdown { return this.#options.children; } + addOptionElement(optionElement: HTMLElement) { + this.#options.appendChild(optionElement); + } + selectText(text: string) { const index = [].slice.call(this.#options.children).findIndex((opt: Element) => opt.querySelector("button")?.innerText === text); if (index > -1) { diff --git a/client/src/index.ts b/client/src/index.ts index 23136d15..8d7d5cba 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -1,156 +1,30 @@ -import { getConfig, getPaused, setAddress, setCredentials, setPaused, startUpdate, toggleDemoEnabled } from "./server/server"; -import { SVGInjector } from "@tanem/svg-injector"; +import { getConfig, setAddress } from "./server/server"; import { OlympusApp } from "./app"; -import { ShortcutKeyboard } from "./shortcut/shortcut"; var app: OlympusApp; function setup() { /* Load the config file from the app server*/ - getConfig((config: ConfigurationOptions) => readConfig(config)); + getConfig((config: ConfigurationOptions) => { + if (config && config.address != undefined && config.port != undefined) { + const address = config.address; + const port = config.port; + if (typeof address === 'string' && typeof port == 'number') { + setAddress(address == "*" ? window.location.hostname : address, port); - app = new OlympusApp(); - app.start(); - - /* Setup event handlers */ - setupEvents(app); + /* If the configuration file was successfully loaded, start the app */ + app = new OlympusApp(); + app.start(); + } + } + else { + throw new Error('Could not read configuration file'); + } + }); } export function getApp() { return app; } -/** Loads the configuration parameters - * - * @param config ConfigParameters, defines the address and port of the Olympus REST server - */ -function readConfig(config: ConfigurationOptions) { - if (config && config.address != undefined && config.port != undefined) { - const address = config.address; - const port = config.port; - if (typeof address === 'string' && typeof port == 'number') - setAddress(address == "*" ? window.location.hostname : address, port); - } - else { - throw new Error('Could not read configuration file'); - } -} - -function setupEvents(app: OlympusApp) { - /* Generic clicks */ - document.addEventListener("click", (ev) => { - if (ev instanceof MouseEvent && ev.target instanceof HTMLElement) { - const target = ev.target; - - if (target.classList.contains("olympus-dialog-close")) { - target.closest("div.olympus-dialog")?.classList.add("hide"); - } - - const triggerElement = target.closest("[data-on-click]"); - - if (triggerElement instanceof HTMLElement) { - const eventName: string = triggerElement.dataset.onClick || ""; - let params = JSON.parse(triggerElement.dataset.onClickParams || "{}"); - params._element = triggerElement; - - if (eventName) { - document.dispatchEvent(new CustomEvent(eventName, { - detail: params - })); - } - } - } - }); - - const shortcutManager = app.getShortcutManager(); - shortcutManager.add("toggleDemo", new ShortcutKeyboard({ - "callback": () => { - toggleDemoEnabled(); - }, - "code": "KeyT" - }) - ) - .add("togglePause", new ShortcutKeyboard({ - "altKey": false, - "callback": () => { - setPaused(!getPaused()); - }, - "code": "Space", - "ctrlKey": false - }) - ); - - ["KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].forEach(code => { - shortcutManager.add(`pan${code}keydown`, new ShortcutKeyboard({ - "altKey": false, - "callback": (ev: KeyboardEvent) => { - getApp().getMap().handleMapPanning(ev); - }, - "code": code, - "ctrlKey": false, - "event": "keydown" - })); - }); - - ["KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].forEach(code => { - shortcutManager.add(`pan${code}keyup`, new ShortcutKeyboard({ - "callback": (ev: KeyboardEvent) => { - getApp().getMap().handleMapPanning(ev); - }, - "code": code - })); - }); - - ["Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9"].forEach(code => { - shortcutManager.add(`hotgroup${code}`, new ShortcutKeyboard({ - "callback": (ev: KeyboardEvent) => { - if (ev.ctrlKey && ev.shiftKey) - getApp().getUnitsManager().selectedUnitsAddToHotgroup(parseInt(ev.code.substring(5))); - else if (ev.ctrlKey && !ev.shiftKey) - getApp().getUnitsManager().selectedUnitsSetHotgroup(parseInt(ev.code.substring(5))); - else - getApp().getUnitsManager().selectUnitsByHotgroup(parseInt(ev.code.substring(5))); - }, - "code": code - })); - }); - - // TODO: move from here in dedicated class - document.addEventListener("closeDialog", (ev: CustomEventInit) => { - ev.detail._element.closest(".ol-dialog").classList.add("hide"); - }); - - /* Try and connect with the Olympus REST server */ - document.addEventListener("tryConnection", () => { - const form = document.querySelector("#splash-content")?.querySelector("#authentication-form"); - const username = (form?.querySelector("#username") as HTMLInputElement).value; - const password = (form?.querySelector("#password") as HTMLInputElement).value; - - /* Update the user credentials */ - setCredentials(username, password); - - /* Start periodically requesting updates */ - startUpdate(); - - getApp().setLoginStatus("connecting"); - }) - - /* Reload the page, used to mimic a restart of the app */ - document.addEventListener("reloadPage", () => { - location.reload(); - }) - - /* Inject the svgs with the corresponding svg code. This allows to dynamically manipulate the svg, like changing colors */ - document.querySelectorAll("[inject-svg]").forEach((el: Element) => { - var img = el as HTMLImageElement; - var isLoaded = img.complete; - if (isLoaded) - SVGInjector(img); - else - img.addEventListener("load", () => { - SVGInjector(img); - }); - }) -} - window.onload = setup; \ No newline at end of file diff --git a/client/src/map/map.ts b/client/src/map/map.ts index 6dc77a01..479bae5e 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./markers/destinationpreviewmarker"; import { TemporaryUnitMarker } from "./markers/temporaryunitmarker"; import { ClickableMiniMap } from "./clickableminimap"; import { SVGInjector } from '@tanem/svg-injector' -import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS, SHOW_CONTROL_TIPS } from "../constants/constants"; +import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants"; import { TargetMarker } from "./markers/targetmarker"; import { CoalitionArea } from "./coalitionarea/coalitionarea"; import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu"; @@ -161,7 +161,6 @@ export class Map extends L.Map { document.addEventListener("mapVisibilityOptionsChanged", () => { this.getContainer().toggleAttribute("data-hide-labels", !this.getVisibilityOptions()[SHOW_UNIT_LABELS]); - // TODO this.getControlTips().toggle( !this.getVisibilityOptions()[SHOW_CONTROL_TIPS] ); }); /* Pan interval */ @@ -180,20 +179,16 @@ export class Map extends L.Map { document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]); /* Create the checkboxes to select the advanced visibility options */ - this.#visibilityOptions[SHOW_CONTACT_LINES] = false; - this.#visibilityOptions[HIDE_GROUP_MEMBERS] = true; - this.#visibilityOptions[SHOW_UNIT_PATHS] = true; - this.#visibilityOptions[SHOW_UNIT_TARGETS] = true; - this.#visibilityOptions[SHOW_UNIT_LABELS] = true; - - // Manual until we use the App approach - this.#visibilityOptions[SHOW_CONTROL_TIPS] = JSON.parse( localStorage.getItem( "featureSwitches" ) || "{}" )?.controlTips || true; + this.addVisibilityOption(SHOW_CONTACT_LINES, false); + this.addVisibilityOption(HIDE_GROUP_MEMBERS, true); + this.addVisibilityOption(SHOW_UNIT_PATHS, true); + this.addVisibilityOption(SHOW_UNIT_TARGETS, true); + this.addVisibilityOption(SHOW_UNIT_LABELS, true); + } - this.#mapVisibilityOptionsDropdown.setOptionsElements(Object.keys(this.#visibilityOptions).map((option: string) => { - return createCheckboxOption(option, option, this.#visibilityOptions[option], (ev: any) => { - this.#setVisibilityOption(option, ev); - }); - })); + addVisibilityOption(option: string, defaultValue: boolean) { + this.#visibilityOptions[option] = defaultValue; + this.#mapVisibilityOptionsDropdown.addOptionElement(createCheckboxOption(option, option, defaultValue, (ev: any) => { this.#setVisibilityOption(option, ev); })); } setLayer(layerName: string) { diff --git a/client/src/plugin/pluginmanager.ts b/client/src/plugin/pluginmanager.ts index 3179786b..38119b69 100644 --- a/client/src/plugin/pluginmanager.ts +++ b/client/src/plugin/pluginmanager.ts @@ -2,6 +2,11 @@ import path from "path"; import { Manager } from "../other/manager"; import { getApp } from ".."; +/** The plugins manager is responsible for loading and initializing all the plugins. Plugins are located in the public/plugins folder. + * Each plugin must be comprised of a single folder containing a index.js file. Each plugin must set the globalThis.getOlympusPlugin variable to + * return a valid class implementing the OlympusPlugin interface. + */ + export class PluginsManager extends Manager { constructor() { super(); @@ -36,15 +41,28 @@ export class PluginsManager extends Manager { document.getElementsByTagName("head")[0].appendChild(link); /* Evaluate the plugin javascript */ - eval(xhr.response); - const plugin = globalThis.getOlympusPlugin() as OlympusPlugin; - console.log(plugin.getName() + " loaded correctly"); - - if (plugin.initialize(getApp())) { - console.log(plugin.getName() + " initialized correctly"); - this.add(pluginName, plugin); + var plugin: OlympusPlugin | null = null; + try { + eval(xhr.response); + plugin = globalThis.getOlympusPlugin() as OlympusPlugin; + console.log(plugin.getName() + " loaded correctly"); + } catch (error: any) { + console.log("An error occured while loading a plugin from " + pluginName); + console.log(error); + } + + /* If the plugin was loaded, try to initialize it */ + if (plugin != null) { + try { + if (plugin.initialize(getApp())) { + console.log(plugin.getName() + " initialized correctly"); + this.add(pluginName, plugin); + } + } catch (error: any) { + console.log("An error occured while initializing a plugin from " + pluginName); + console.log(error); + } } - } else { console.error(`Error retrieving plugin from ${pluginName}`) } From 44332a2004164cd48d8f89c1d3a733211a0d9dbe Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Mon, 18 Sep 2023 17:10:14 +0200 Subject: [PATCH 12/12] Moved server code to dedicated ServerManager class --- client/src/app.ts | 36 +- client/src/contextmenus/mapcontextmenu.ts | 5 +- client/src/index.ts | 20 +- client/src/map/markers/temporaryunitmarker.ts | 3 +- client/src/mission/missionmanager.ts | 7 +- client/src/server/server.ts | 492 ----------------- client/src/server/servermanager.ts | 493 ++++++++++++++++++ client/src/unit/unit.ts | 50 +- client/src/unit/unitsmanager.ts | 13 +- 9 files changed, 558 insertions(+), 561 deletions(-) delete mode 100644 client/src/server/server.ts create mode 100644 client/src/server/servermanager.ts diff --git a/client/src/app.ts b/client/src/app.ts index 0f7c611f..749fde68 100644 --- a/client/src/app.ts +++ b/client/src/app.ts @@ -14,12 +14,12 @@ import { CommandModeToolbar } from "./toolbars/commandmodetoolbar"; import { PrimaryToolbar } from "./toolbars/primarytoolbar"; import { UnitsManager } from "./unit/unitsmanager"; import { WeaponsManager } from "./weapon/weaponsmanager"; - -import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants"; import { Manager } from "./other/manager"; import { ShortcutKeyboard } from "./shortcut/shortcut"; -import { getPaused, setCredentials, setPaused, startUpdate, toggleDemoEnabled } from "./server/server"; import { SVGInjector } from "@tanem/svg-injector"; +import { ServerManager } from "./server/servermanager"; + +import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants"; export class OlympusApp { /* Global data */ @@ -29,6 +29,7 @@ export class OlympusApp { #map: Map | null = null; /* Managers */ + #serverManager: ServerManager | null = null; #unitsManager: UnitsManager | null = null; #weaponsManager: WeaponsManager | null = null; #missionManager: MissionManager | null = null; @@ -46,10 +47,15 @@ export class OlympusApp { } + // TODO add checks on null getMap() { return this.#map as Map; } + getServerManager() { + return this.#serverManager as ServerManager; + } + getPanelsManager() { return this.#panelsManager as Manager; } @@ -122,6 +128,7 @@ export class OlympusApp { /* Initialize base functionalitites */ this.#map = new Map('map-container'); + this.#serverManager = new ServerManager(); this.#unitsManager = new UnitsManager(); this.#weaponsManager = new WeaponsManager(); this.#missionManager = new MissionManager(); @@ -151,6 +158,21 @@ export class OlympusApp { this.#pluginsManager = new PluginsManager(); + /* Load the config file from the app server*/ + this.getServerManager().getConfig((config: ConfigurationOptions) => { + if (config && config.address != undefined && config.port != undefined) { + const address = config.address; + const port = config.port; + if (typeof address === 'string' && typeof port == 'number') { + this.getServerManager().setAddress(address == "*" ? window.location.hostname : address, port); + } + } + else { + throw new Error('Could not read configuration file'); + } + }); + + /* Setup all global events */ this.#setupEvents(); } @@ -183,13 +205,13 @@ export class OlympusApp { const shortcutManager = this.getShortcutManager(); shortcutManager.add("toggleDemo", new ShortcutKeyboard({ "callback": () => { - toggleDemoEnabled(); + this.getServerManager().toggleDemoEnabled(); }, "code": "KeyT" })).add("togglePause", new ShortcutKeyboard({ "altKey": false, "callback": () => { - setPaused(!getPaused()); + this.getServerManager().setPaused(!this.getServerManager().getPaused()); }, "code": "Space", "ctrlKey": false @@ -242,10 +264,10 @@ export class OlympusApp { const password = (form?.querySelector("#password") as HTMLInputElement).value; /* Update the user credentials */ - setCredentials(username, password); + this.getServerManager().setCredentials(username, password); /* Start periodically requesting updates */ - startUpdate(); + this.getServerManager().startUpdate(); this.setLoginStatus("connecting"); }) diff --git a/client/src/contextmenus/mapcontextmenu.ts b/client/src/contextmenus/mapcontextmenu.ts index 2d86772c..2f3c3689 100644 --- a/client/src/contextmenus/mapcontextmenu.ts +++ b/client/src/contextmenus/mapcontextmenu.ts @@ -1,6 +1,5 @@ import { LatLng } from "leaflet"; import { getApp } from ".."; -import { spawnExplosion, spawnSmoke } from "../server/server"; import { ContextMenu } from "./contextmenu"; import { Switch } from "../controls/switch"; import { GAME_MASTER } from "../constants/constants"; @@ -48,14 +47,14 @@ export class MapContextMenu extends ContextMenu { document.addEventListener("contextMenuDeploySmoke", (e: any) => { this.hide(); - spawnSmoke(e.detail.color, this.getLatLng()); + getApp().getServerManager().spawnSmoke(e.detail.color, this.getLatLng()); var marker = new SmokeMarker(this.getLatLng(), e.detail.color); marker.addTo(getApp().getMap()); }); document.addEventListener("contextMenuExplosion", (e: any) => { this.hide(); - spawnExplosion(e.detail.strength, this.getLatLng()); + getApp().getServerManager().spawnExplosion(e.detail.strength, this.getLatLng()); }); document.addEventListener("editCoalitionArea", (e: any) => { diff --git a/client/src/index.ts b/client/src/index.ts index 8d7d5cba..2b637448 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -1,26 +1,10 @@ -import { getConfig, setAddress } from "./server/server"; import { OlympusApp } from "./app"; var app: OlympusApp; function setup() { - /* Load the config file from the app server*/ - getConfig((config: ConfigurationOptions) => { - if (config && config.address != undefined && config.port != undefined) { - const address = config.address; - const port = config.port; - if (typeof address === 'string' && typeof port == 'number') { - setAddress(address == "*" ? window.location.hostname : address, port); - - /* If the configuration file was successfully loaded, start the app */ - app = new OlympusApp(); - app.start(); - } - } - else { - throw new Error('Could not read configuration file'); - } - }); + app = new OlympusApp(); + app.start(); } export function getApp() { diff --git a/client/src/map/markers/temporaryunitmarker.ts b/client/src/map/markers/temporaryunitmarker.ts index 1d480a13..bd538d86 100644 --- a/client/src/map/markers/temporaryunitmarker.ts +++ b/client/src/map/markers/temporaryunitmarker.ts @@ -2,7 +2,6 @@ import { CustomMarker } from "./custommarker"; import { DivIcon, LatLng } from "leaflet"; import { SVGInjector } from "@tanem/svg-injector"; import { getMarkerCategoryByName, getUnitDatabaseByCategory } from "../../other/utils"; -import { isCommandExecuted } from "../../server/server"; import { getApp } from "../.."; export class TemporaryUnitMarker extends CustomMarker { @@ -25,7 +24,7 @@ export class TemporaryUnitMarker extends CustomMarker { this.#commandHash = commandHash; this.#timer = window.setInterval(() => { if (this.#commandHash !== undefined) { - isCommandExecuted((res: any) => { + getApp().getServerManager().isCommandExecuted((res: any) => { if (res.commandExecuted) { this.removeFrom(getApp().getMap()); window.clearInterval(this.#timer); diff --git a/client/src/mission/missionmanager.ts b/client/src/mission/missionmanager.ts index 1b6f2c85..5acf3c96 100644 --- a/client/src/mission/missionmanager.ts +++ b/client/src/mission/missionmanager.ts @@ -3,7 +3,6 @@ import { getApp } from ".."; import { Airbase } from "./airbase"; import { Bullseye } from "./bullseye"; import { BLUE_COMMANDER, GAME_MASTER, NONE, RED_COMMANDER } from "../constants/constants"; -import { refreshAll, setCommandModeOptions } from "../server/server"; import { Dropdown } from "../controls/dropdown"; import { groundUnitDatabase } from "../unit/databases/groundunitdatabase"; import { createCheckboxOption, getCheckboxOptions } from "../other/utils"; @@ -30,7 +29,7 @@ export class MissionManager { document.addEventListener("applycommandModeOptions", () => this.#applycommandModeOptions()); /* command-mode settings dialog */ - this.#commandModeDialog = document.querySelector("#command-mode-settings-dialog"); + this.#commandModeDialog = document.querySelector("#command-mode-settings-dialog") as HTMLElement; this.#commandModeErasDropdown = new Dropdown("command-mode-era-options", () => {}); } @@ -191,7 +190,7 @@ export class MissionManager { var eras: string[] = []; const enabledEras = getCheckboxOptions(this.#commandModeErasDropdown); Object.keys(enabledEras).forEach((key: string) => {if (enabledEras[key]) eras.push(key)}); - setCommandModeOptions(restrictSpawnsCheckbox.checked, restrictToCoalitionCheckbox.checked, {blue: parseInt(blueSpawnPointsInput.value), red: parseInt(redSpawnPointsInput.value)}, eras, parseInt(setupTimeInput.value) * 60); + getApp().getServerManager().setCommandModeOptions(restrictSpawnsCheckbox.checked, restrictToCoalitionCheckbox.checked, {blue: parseInt(blueSpawnPointsInput.value), red: parseInt(redSpawnPointsInput.value)}, eras, parseInt(setupTimeInput.value) * 60); } #setcommandModeOptions(commandModeOptions: CommandModeOptions) { @@ -229,7 +228,7 @@ export class MissionManager { document.querySelector("#command-mode-settings-button")?.classList.toggle("hide", this.getCommandModeOptions().commandMode !== GAME_MASTER); if (requestRefresh) - refreshAll(); + getApp().getServerManager().refreshAll(); } #onAirbaseClick(e: any) { diff --git a/client/src/server/server.ts b/client/src/server/server.ts deleted file mode 100644 index 9087abfa..00000000 --- a/client/src/server/server.ts +++ /dev/null @@ -1,492 +0,0 @@ -import { LatLng } from 'leaflet'; -import { getApp } from '..'; -import { AIRBASES_URI, BULLSEYE_URI, COMMANDS_URI, LOGS_URI, MISSION_URI, NONE, ROEs, UNITS_URI, WEAPONS_URI, emissionsCountermeasures, reactionsToThreat } from '../constants/constants'; -import { ServerStatusPanel } from '../panels/serverstatuspanel'; -import { LogPanel } from '../panels/logpanel'; -import { Popup } from '../popups/popup'; -import { ConnectionStatusPanel } from '../panels/connectionstatuspanel'; - -var connected: boolean = false; -var paused: boolean = false; - -var REST_ADDRESS = "http://localhost:30000/olympus"; -var DEMO_ADDRESS = window.location.href + "demo"; - -var username = ""; -var password = ""; - -var sessionHash: string | null = null; -var lastUpdateTimes: {[key: string]: number} = {} -lastUpdateTimes[UNITS_URI] = Date.now(); -lastUpdateTimes[WEAPONS_URI] = Date.now(); -lastUpdateTimes[LOGS_URI] = Date.now(); -lastUpdateTimes[AIRBASES_URI] = Date.now(); -lastUpdateTimes[BULLSEYE_URI] = Date.now(); -lastUpdateTimes[MISSION_URI] = Date.now(); - -var demoEnabled = false; - -export function toggleDemoEnabled() { - demoEnabled = !demoEnabled; -} - -export function setCredentials(newUsername: string, newPassword: string) { - username = newUsername; - password = newPassword; -} - -export function GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType?: string) { - var xmlHttp = new XMLHttpRequest(); - - /* Assemble the request options string */ - var optionsString = ''; - if (options?.time != undefined) - optionsString = `time=${options.time}`; - if (options?.commandHash != undefined) - optionsString = `commandHash=${options.commandHash}`; - - /* On the connection */ - xmlHttp.open("GET", `${demoEnabled ? DEMO_ADDRESS : REST_ADDRESS}/${uri}${optionsString ? `?${optionsString}` : ''}`, true); - - /* If provided, set the credentials */ - if (username && password) - xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(`${username}:${password}`)); - - /* If specified, set the response type */ - if (responseType) - xmlHttp.responseType = responseType as XMLHttpRequestResponseType; - - xmlHttp.onload = function (e) { - if (xmlHttp.status == 200) { - /* Success */ - setConnected(true); - if (xmlHttp.responseType == 'arraybuffer') - lastUpdateTimes[uri] = callback(xmlHttp.response); - else { - const result = JSON.parse(xmlHttp.responseText); - lastUpdateTimes[uri] = callback(result); - - if (result.frameRate !== undefined && result.load !== undefined) - (getApp().getPanelsManager().get("serverStatus") as ServerStatusPanel).update(result.frameRate, result.load); - } - } else if (xmlHttp.status == 401) { - /* Bad credentials */ - console.error("Incorrect username/password"); - getApp().setLoginStatus("failed"); - } else { - /* Failure, probably disconnected */ - setConnected(false); - } - }; - xmlHttp.onerror = function (res) { - console.error("An error occurred during the XMLHttpRequest"); - setConnected(false); - }; - xmlHttp.send(null); -} - -export function POST(request: object, callback: CallableFunction) { - var xmlHttp = new XMLHttpRequest(); - xmlHttp.open("PUT", demoEnabled ? DEMO_ADDRESS : REST_ADDRESS); - xmlHttp.setRequestHeader("Content-Type", "application/json"); - if (username && password) - xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(`${username}:${password}`)); - xmlHttp.onload = (res: any) => { - var res = JSON.parse(xmlHttp.responseText); - callback(res); - }; - xmlHttp.send(JSON.stringify(request)); -} - -export function getConfig(callback: CallableFunction) { - var xmlHttp = new XMLHttpRequest(); - xmlHttp.open("GET", window.location.href + "config", true); - xmlHttp.onload = function (e) { - var data = JSON.parse(xmlHttp.responseText); - callback(data); - }; - xmlHttp.onerror = function () { - console.error("An error occurred during the XMLHttpRequest, could not retrieve configuration file"); - }; - xmlHttp.send(null); -} - -export function setAddress(address: string, port: number) { - REST_ADDRESS = `http://${address}:${port}/olympus` - console.log(`Setting REST address to ${REST_ADDRESS}`) -} - -export function getAirbases(callback: CallableFunction) { - GET(callback, AIRBASES_URI); -} - -export function getBullseye(callback: CallableFunction) { - GET(callback, BULLSEYE_URI); -} - -export function getLogs(callback: CallableFunction, refresh: boolean = false) { - GET(callback, LOGS_URI, { time: refresh ? 0 : lastUpdateTimes[LOGS_URI]}); -} - -export function getMission(callback: CallableFunction) { - GET(callback, MISSION_URI); -} - -export function getUnits(callback: CallableFunction, refresh: boolean = false) { - GET(callback, UNITS_URI, { time: refresh ? 0 : lastUpdateTimes[UNITS_URI] }, 'arraybuffer'); -} - -export function getWeapons(callback: CallableFunction, refresh: boolean = false) { - GET(callback, WEAPONS_URI, { time: refresh ? 0 : lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer'); -} - -export function isCommandExecuted(callback: CallableFunction, commandHash: string) { - GET(callback, COMMANDS_URI, { commandHash: commandHash}); -} - -export function addDestination(ID: number, path: any, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "path": path } - var data = { "setPath": command } - POST(data, callback); -} - -export function spawnSmoke(color: string, latlng: LatLng, callback: CallableFunction = () => {}) { - var command = { "color": color, "location": latlng }; - var data = { "smoke": command } - POST(data, callback); -} - -export function spawnExplosion(intensity: number, latlng: LatLng, callback: CallableFunction = () => {}) { - var command = { "intensity": intensity, "location": latlng }; - var data = { "explosion": command } - POST(data, callback); -} - -export function spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { - var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints }; - var data = { "spawnAircrafts": command } - POST(data, callback); -} - -export function spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { - var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints }; - var data = { "spawnHelicopters": command } - POST(data, callback); -} - -export function spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { - var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };; - var data = { "spawnGroundUnits": command } - POST(data, callback); -} - -export function spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { - var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints }; - var data = { "spawnNavyUnits": command } - POST(data, callback); -} - -export function attackUnit(ID: number, targetID: number, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "targetID": targetID }; - var data = { "attackUnit": command } - POST(data, callback); -} - -export function followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }, callback: CallableFunction = () => {}) { - // X: front-rear, positive front - // Y: top-bottom, positive bottom - // Z: left-right, positive right - - var command = { "ID": ID, "targetID": targetID, "offsetX": offset["x"], "offsetY": offset["y"], "offsetZ": offset["z"] }; - var data = { "followUnit": command } - POST(data, callback); -} - -export function cloneUnits(units: {ID: number, location: LatLng}[], deleteOriginal: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { - var command = { "units": units, "deleteOriginal": deleteOriginal, "spawnPoints": spawnPoints }; - var data = { "cloneUnits": command } - POST(data, callback); -} - -export function deleteUnit(ID: number, explosion: boolean, immediate: boolean, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "explosion": explosion, "immediate": immediate }; - var data = { "deleteUnit": command } - POST(data, callback); -} - -export function landAt(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "location": latlng }; - var data = { "landAt": command } - POST(data, callback); -} - -export function changeSpeed(ID: number, speedChange: string, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "change": speedChange } - var data = { "changeSpeed": command } - POST(data, callback); -} - -export function setSpeed(ID: number, speed: number, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "speed": speed } - var data = { "setSpeed": command } - POST(data, callback); -} - -export function setSpeedType(ID: number, speedType: string, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "speedType": speedType } - var data = { "setSpeedType": command } - POST(data, callback); -} - -export function changeAltitude(ID: number, altitudeChange: string, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "change": altitudeChange } - var data = { "changeAltitude": command } - POST(data, callback); -} - -export function setAltitudeType(ID: number, altitudeType: string, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "altitudeType": altitudeType } - var data = { "setAltitudeType": command } - POST(data, callback); -} - -export function setAltitude(ID: number, altitude: number, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "altitude": altitude } - var data = { "setAltitude": command } - POST(data, callback); -} - -export function createFormation(ID: number, isLeader: boolean, wingmenIDs: number[], callback: CallableFunction = () => {}) { - var command = { "ID": ID, "wingmenIDs": wingmenIDs, "isLeader": isLeader } - var data = { "setLeader": command } - POST(data, callback); -} - -export function setROE(ID: number, ROE: string, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "ROE": ROEs.indexOf(ROE) } - var data = { "setROE": command } - POST(data, callback); -} - -export function setReactionToThreat(ID: number, reactionToThreat: string, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "reactionToThreat": reactionsToThreat.indexOf(reactionToThreat) } - var data = { "setReactionToThreat": command } - POST(data, callback); -} - -export function setEmissionsCountermeasures(ID: number, emissionCountermeasure: string, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "emissionsCountermeasures": emissionsCountermeasures.indexOf(emissionCountermeasure) } - var data = { "setEmissionsCountermeasures": command } - POST(data, callback); -} - -export function setOnOff(ID: number, onOff: boolean, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "onOff": onOff } - var data = { "setOnOff": command } - POST(data, callback); -} - -export function setFollowRoads(ID: number, followRoads: boolean, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "followRoads": followRoads } - var data = { "setFollowRoads": command } - POST(data, callback); -} - -export function refuel(ID: number, callback: CallableFunction = () => {}) { - var command = { "ID": ID }; - var data = { "refuel": command } - POST(data, callback); -} - -export function bombPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "location": latlng } - var data = { "bombPoint": command } - POST(data, callback); -} - -export function carpetBomb(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "location": latlng } - var data = { "carpetBomb": command } - POST(data, callback); -} - -export function bombBuilding(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "location": latlng } - var data = { "bombBuilding": command } - POST(data, callback); -} - -export function fireAtArea(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { - var command = { "ID": ID, "location": latlng } - var data = { "fireAtArea": command } - POST(data, callback); -} - -export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) { - var command = { - "ID": ID, - "isTanker": isTanker, - "isAWACS": isAWACS, - "TACAN": TACAN, - "radio": radio, - "generalSettings": generalSettings - }; - - var data = { "setAdvancedOptions": command }; - POST(data, callback); -} - -export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number, callback: CallableFunction = () => {}) { - var command = { - "restrictSpawns": restrictSpawns, - "restrictToCoalition": restrictToCoalition, - "spawnPoints": spawnPoints, - "eras": eras, - "setupTime": setupTime - }; - - var data = { "setCommandModeOptions": command }; - POST(data, callback); -} - -export function startUpdate() { - window.setInterval(() => { - if (!getPaused()) { - getMission((data: MissionData) => { - checkSessionHash(data.sessionHash); - getApp().getMissionManager()?.updateMission(data); - return data.time; - }); - } - }, 1000); - - window.setInterval(() => { - if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { - getAirbases((data: AirbasesData) => { - checkSessionHash(data.sessionHash); - getApp().getMissionManager()?.updateAirbases(data); - return data.time; - }); - } - }, 10000); - - window.setInterval(() => { - if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE){ - getBullseye((data: BullseyesData) => { - checkSessionHash(data.sessionHash); - getApp().getMissionManager()?.updateBullseyes(data); - return data.time; - }); - } - }, 10000); - - window.setInterval(() => { - if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { - getLogs((data: any) => { - checkSessionHash(data.sessionHash); - (getApp().getPanelsManager().get("log") as LogPanel).appendLogs(data.logs) - return data.time; - }); - } - }, 1000); - - window.setInterval(() => { - if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { - getUnits((buffer: ArrayBuffer) => { - var time = getApp().getUnitsManager()?.update(buffer); - return time; - }, false); - } - }, 250); - - window.setInterval(() => { - if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { - getWeapons((buffer: ArrayBuffer) => { - var time = getApp().getWeaponsManager()?.update(buffer); - return time; - }, false); - } - }, 250); - - window.setInterval(() => { - if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { - getUnits((buffer: ArrayBuffer) => { - var time = getApp().getUnitsManager()?.update(buffer); - return time; - }, true); - (getApp().getPanelsManager().get("connectionStatus") as ConnectionStatusPanel).update(getConnected()); - } - }, 5000); - - window.setInterval(() => { - if (!getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { - getWeapons((buffer: ArrayBuffer) => { - var time = getApp().getWeaponsManager()?.update(buffer); - return time; - }, true); - } - }, 5000); -} - -export function refreshAll() { - getAirbases((data: AirbasesData) => { - checkSessionHash(data.sessionHash); - getApp().getMissionManager()?.updateAirbases(data); - return data.time; - }); - - getBullseye((data: BullseyesData) => { - checkSessionHash(data.sessionHash); - getApp().getMissionManager()?.updateBullseyes(data); - return data.time; - }); - - getLogs((data: any) => { - checkSessionHash(data.sessionHash); - (getApp().getPanelsManager().get("log") as LogPanel).appendLogs(data.logs) - return data.time; - }); - - getWeapons((buffer: ArrayBuffer) => { - var time = getApp().getWeaponsManager()?.update(buffer); - return time; - }, true); - - getUnits((buffer: ArrayBuffer) => { - var time = getApp().getUnitsManager()?.update(buffer); - return time; - }, true); -} - -export function checkSessionHash(newSessionHash: string) { - if (sessionHash != null) { - if (newSessionHash !== sessionHash) - location.reload(); - } - else - sessionHash = newSessionHash; -} - -export function setConnected(newConnected: boolean) { - if (connected != newConnected) - newConnected ? (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Connected to DCS Olympus server") : (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Disconnected from DCS Olympus server"); - connected = newConnected; - - if (connected) { - document.querySelector("#splash-screen")?.classList.add("hide"); - document.querySelector("#gray-out")?.classList.add("hide"); - } -} - -export function getConnected() { - return connected; -} - -export function setPaused(newPaused: boolean) { - paused = newPaused; - paused ? (getApp().getPopupsManager().get("infoPopup") as Popup).setText("View paused") : (getApp().getPopupsManager().get("infoPopup") as Popup).setText("View unpaused"); -} - -export function getPaused() { - return paused; -} \ No newline at end of file diff --git a/client/src/server/servermanager.ts b/client/src/server/servermanager.ts new file mode 100644 index 00000000..d2747e69 --- /dev/null +++ b/client/src/server/servermanager.ts @@ -0,0 +1,493 @@ +import { LatLng } from 'leaflet'; +import { getApp } from '..'; +import { AIRBASES_URI, BULLSEYE_URI, COMMANDS_URI, LOGS_URI, MISSION_URI, NONE, ROEs, UNITS_URI, WEAPONS_URI, emissionsCountermeasures, reactionsToThreat } from '../constants/constants'; +import { ServerStatusPanel } from '../panels/serverstatuspanel'; +import { LogPanel } from '../panels/logpanel'; +import { Popup } from '../popups/popup'; +import { ConnectionStatusPanel } from '../panels/connectionstatuspanel'; + +export class ServerManager { + #connected: boolean = false; + #paused: boolean = false; + #REST_ADDRESS = "http://localhost:30000/olympus"; + #DEMO_ADDRESS = window.location.href + "demo"; + #username = ""; + #password = ""; + #sessionHash: string | null = null; + #lastUpdateTimes: {[key: string]: number} = {} + #demoEnabled = false; + + constructor() { + this.#lastUpdateTimes[UNITS_URI] = Date.now(); + this.#lastUpdateTimes[WEAPONS_URI] = Date.now(); + this.#lastUpdateTimes[LOGS_URI] = Date.now(); + this.#lastUpdateTimes[AIRBASES_URI] = Date.now(); + this.#lastUpdateTimes[BULLSEYE_URI] = Date.now(); + this.#lastUpdateTimes[MISSION_URI] = Date.now(); + } + + toggleDemoEnabled() { + this.#demoEnabled = !this.#demoEnabled; + } + + setCredentials(newUsername: string, newPassword: string) { + this.#username = newUsername; + this.#password = newPassword; + } + + GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType?: string) { + var xmlHttp = new XMLHttpRequest(); + + /* Assemble the request options string */ + var optionsString = ''; + if (options?.time != undefined) + optionsString = `time=${options.time}`; + if (options?.commandHash != undefined) + optionsString = `commandHash=${options.commandHash}`; + + /* On the connection */ + xmlHttp.open("GET", `${this.#demoEnabled ? this.#DEMO_ADDRESS : this.#REST_ADDRESS}/${uri}${optionsString ? `?${optionsString}` : ''}`, true); + + /* If provided, set the credentials */ + if (this.#username && this.#password) + xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(`${this.#username}:${this.#password}`)); + + /* If specified, set the response type */ + if (responseType) + xmlHttp.responseType = responseType as XMLHttpRequestResponseType; + + xmlHttp.onload = (e) => { + if (xmlHttp.status == 200) { + /* Success */ + this.setConnected(true); + if (xmlHttp.responseType == 'arraybuffer') + this.#lastUpdateTimes[uri] = callback(xmlHttp.response); + else { + const result = JSON.parse(xmlHttp.responseText); + this.#lastUpdateTimes[uri] = callback(result); + + if (result.frameRate !== undefined && result.load !== undefined) + (getApp().getPanelsManager().get("serverStatus") as ServerStatusPanel).update(result.frameRate, result.load); + } + } else if (xmlHttp.status == 401) { + /* Bad credentials */ + console.error("Incorrect username/password"); + getApp().setLoginStatus("failed"); + } else { + /* Failure, probably disconnected */ + this.setConnected(false); + } + }; + xmlHttp.onerror = (res) => { + console.error("An error occurred during the XMLHttpRequest"); + this.setConnected(false); + }; + xmlHttp.send(null); + } + + POST(request: object, callback: CallableFunction) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open("PUT", this.#demoEnabled ? this.#DEMO_ADDRESS : this.#REST_ADDRESS); + xmlHttp.setRequestHeader("Content-Type", "application/json"); + if (this.#username && this.#password) + xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(`${this.#username}:${this.#password}`)); + xmlHttp.onload = (res: any) => { + var res = JSON.parse(xmlHttp.responseText); + callback(res); + }; + xmlHttp.send(JSON.stringify(request)); + } + + getConfig(callback: CallableFunction) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open("GET", window.location.href + "config", true); + xmlHttp.onload = function (e) { + var data = JSON.parse(xmlHttp.responseText); + callback(data); + }; + xmlHttp.onerror = function () { + console.error("An error occurred during the XMLHttpRequest, could not retrieve configuration file"); + }; + xmlHttp.send(null); + } + + setAddress(address: string, port: number) { + this.#REST_ADDRESS = `http://${address}:${port}/olympus` + console.log(`Setting REST address to ${this.#REST_ADDRESS}`) + } + + getAirbases(callback: CallableFunction) { + this.GET(callback, AIRBASES_URI); + } + + getBullseye(callback: CallableFunction) { + this.GET(callback, BULLSEYE_URI); + } + + getLogs(callback: CallableFunction, refresh: boolean = false) { + this.GET(callback, LOGS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[LOGS_URI]}); + } + + getMission(callback: CallableFunction) { + this.GET(callback, MISSION_URI); + } + + getUnits(callback: CallableFunction, refresh: boolean = false) { + this.GET(callback, UNITS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[UNITS_URI] }, 'arraybuffer'); + } + + getWeapons(callback: CallableFunction, refresh: boolean = false) { + this.GET(callback, WEAPONS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer'); + } + + isCommandExecuted(callback: CallableFunction, commandHash: string) { + this.GET(callback, COMMANDS_URI, { commandHash: commandHash}); + } + + addDestination(ID: number, path: any, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "path": path } + var data = { "setPath": command } + this.POST(data, callback); + } + + spawnSmoke(color: string, latlng: LatLng, callback: CallableFunction = () => {}) { + var command = { "color": color, "location": latlng }; + var data = { "smoke": command } + this.POST(data, callback); + } + + spawnExplosion(intensity: number, latlng: LatLng, callback: CallableFunction = () => {}) { + var command = { "intensity": intensity, "location": latlng }; + var data = { "explosion": command } + this.POST(data, callback); + } + + spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { + var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints }; + var data = { "spawnAircrafts": command } + this.POST(data, callback); + } + + spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { + var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints }; + var data = { "spawnHelicopters": command } + this.POST(data, callback); + } + + spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { + var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };; + var data = { "spawnGroundUnits": command } + this.POST(data, callback); + } + + spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { + var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints }; + var data = { "spawnNavyUnits": command } + this.POST(data, callback); + } + + attackUnit(ID: number, targetID: number, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "targetID": targetID }; + var data = { "attackUnit": command } + this.POST(data, callback); + } + + followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }, callback: CallableFunction = () => {}) { + // X: front-rear, positive front + // Y: top-bottom, positive bottom + // Z: left-right, positive right + + var command = { "ID": ID, "targetID": targetID, "offsetX": offset["x"], "offsetY": offset["y"], "offsetZ": offset["z"] }; + var data = { "followUnit": command } + this.POST(data, callback); + } + + cloneUnits(units: {ID: number, location: LatLng}[], deleteOriginal: boolean, spawnPoints: number, callback: CallableFunction = () => {}) { + var command = { "units": units, "deleteOriginal": deleteOriginal, "spawnPoints": spawnPoints }; + var data = { "cloneUnits": command } + this.POST(data, callback); + } + + deleteUnit(ID: number, explosion: boolean, immediate: boolean, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "explosion": explosion, "immediate": immediate }; + var data = { "deleteUnit": command } + this.POST(data, callback); + } + + landAt(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "location": latlng }; + var data = { "landAt": command } + this.POST(data, callback); + } + + changeSpeed(ID: number, speedChange: string, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "change": speedChange } + var data = { "changeSpeed": command } + this.POST(data, callback); + } + + setSpeed(ID: number, speed: number, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "speed": speed } + var data = { "setSpeed": command } + this.POST(data, callback); + } + + setSpeedType(ID: number, speedType: string, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "speedType": speedType } + var data = { "setSpeedType": command } + this.POST(data, callback); + } + + changeAltitude(ID: number, altitudeChange: string, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "change": altitudeChange } + var data = { "changeAltitude": command } + this.POST(data, callback); + } + + setAltitudeType(ID: number, altitudeType: string, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "altitudeType": altitudeType } + var data = { "setAltitudeType": command } + this.POST(data, callback); + } + + setAltitude(ID: number, altitude: number, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "altitude": altitude } + var data = { "setAltitude": command } + this.POST(data, callback); + } + + createFormation(ID: number, isLeader: boolean, wingmenIDs: number[], callback: CallableFunction = () => {}) { + var command = { "ID": ID, "wingmenIDs": wingmenIDs, "isLeader": isLeader } + var data = { "setLeader": command } + this.POST(data, callback); + } + + setROE(ID: number, ROE: string, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "ROE": ROEs.indexOf(ROE) } + var data = { "setROE": command } + this.POST(data, callback); + } + + setReactionToThreat(ID: number, reactionToThreat: string, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "reactionToThreat": reactionsToThreat.indexOf(reactionToThreat) } + var data = { "setReactionToThreat": command } + this.POST(data, callback); + } + + setEmissionsCountermeasures(ID: number, emissionCountermeasure: string, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "emissionsCountermeasures": emissionsCountermeasures.indexOf(emissionCountermeasure) } + var data = { "setEmissionsCountermeasures": command } + this.POST(data, callback); + } + + setOnOff(ID: number, onOff: boolean, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "onOff": onOff } + var data = { "setOnOff": command } + this.POST(data, callback); + } + + setFollowRoads(ID: number, followRoads: boolean, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "followRoads": followRoads } + var data = { "setFollowRoads": command } + this.POST(data, callback); + } + + refuel(ID: number, callback: CallableFunction = () => {}) { + var command = { "ID": ID }; + var data = { "refuel": command } + this.POST(data, callback); + } + + bombPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "location": latlng } + var data = { "bombPoint": command } + this.POST(data, callback); + } + + carpetBomb(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "location": latlng } + var data = { "carpetBomb": command } + this.POST(data, callback); + } + + bombBuilding(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "location": latlng } + var data = { "bombBuilding": command } + this.POST(data, callback); + } + + fireAtArea(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) { + var command = { "ID": ID, "location": latlng } + var data = { "fireAtArea": command } + this.POST(data, callback); + } + + setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) { + var command = { + "ID": ID, + "isTanker": isTanker, + "isAWACS": isAWACS, + "TACAN": TACAN, + "radio": radio, + "generalSettings": generalSettings + }; + + var data = { "setAdvancedOptions": command }; + this.POST(data, callback); + } + + setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number, callback: CallableFunction = () => {}) { + var command = { + "restrictSpawns": restrictSpawns, + "restrictToCoalition": restrictToCoalition, + "spawnPoints": spawnPoints, + "eras": eras, + "setupTime": setupTime + }; + + var data = { "setCommandModeOptions": command }; + this.POST(data, callback); + } + + startUpdate() { + window.setInterval(() => { + if (!this.getPaused()) { + this.getMission((data: MissionData) => { + this.checkSessionHash(data.sessionHash); + getApp().getMissionManager()?.updateMission(data); + return data.time; + }); + } + }, 1000); + + window.setInterval(() => { + if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { + this.getAirbases((data: AirbasesData) => { + this.checkSessionHash(data.sessionHash); + getApp().getMissionManager()?.updateAirbases(data); + return data.time; + }); + } + }, 10000); + + window.setInterval(() => { + if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE){ + this.getBullseye((data: BullseyesData) => { + this.checkSessionHash(data.sessionHash); + getApp().getMissionManager()?.updateBullseyes(data); + return data.time; + }); + } + }, 10000); + + window.setInterval(() => { + if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { + this.getLogs((data: any) => { + this.checkSessionHash(data.sessionHash); + (getApp().getPanelsManager().get("log") as LogPanel).appendLogs(data.logs) + return data.time; + }); + } + }, 1000); + + window.setInterval(() => { + if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { + this.getUnits((buffer: ArrayBuffer) => { + var time = getApp().getUnitsManager()?.update(buffer); + return time; + }, false); + } + }, 250); + + window.setInterval(() => { + if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { + this.getWeapons((buffer: ArrayBuffer) => { + var time = getApp().getWeaponsManager()?.update(buffer); + return time; + }, false); + } + }, 250); + + window.setInterval(() => { + if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { + this.getUnits((buffer: ArrayBuffer) => { + var time = getApp().getUnitsManager()?.update(buffer); + return time; + }, true); + (getApp().getPanelsManager().get("connectionStatus") as ConnectionStatusPanel).update(this.getConnected()); + } + }, 5000); + + window.setInterval(() => { + if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) { + this.getWeapons((buffer: ArrayBuffer) => { + var time = getApp().getWeaponsManager()?.update(buffer); + return time; + }, true); + } + }, 5000); + } + + refreshAll() { + this.getAirbases((data: AirbasesData) => { + this.checkSessionHash(data.sessionHash); + getApp().getMissionManager()?.updateAirbases(data); + return data.time; + }); + + this.getBullseye((data: BullseyesData) => { + this.checkSessionHash(data.sessionHash); + getApp().getMissionManager()?.updateBullseyes(data); + return data.time; + }); + + this.getLogs((data: any) => { + this.checkSessionHash(data.sessionHash); + (getApp().getPanelsManager().get("log") as LogPanel).appendLogs(data.logs) + return data.time; + }); + + this.getWeapons((buffer: ArrayBuffer) => { + var time = getApp().getWeaponsManager()?.update(buffer); + return time; + }, true); + + this.getUnits((buffer: ArrayBuffer) => { + var time = getApp().getUnitsManager()?.update(buffer); + return time; + }, true); + } + + checkSessionHash(newSessionHash: string) { + if (this.#sessionHash != null) { + if (newSessionHash !== this.#sessionHash) + location.reload(); + } + else + this.#sessionHash = newSessionHash; + } + + setConnected(newConnected: boolean) { + if (this.#connected != newConnected) + newConnected ? (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Connected to DCS Olympus server") : (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Disconnected from DCS Olympus server"); + this.#connected = newConnected; + + if (this.#connected) { + document.querySelector("#splash-screen")?.classList.add("hide"); + document.querySelector("#gray-out")?.classList.add("hide"); + } + } + + getConnected() { + return this.#connected; + } + + setPaused(newPaused: boolean) { + this.#paused = newPaused; + this.#paused ? (getApp().getPopupsManager().get("infoPopup") as Popup).setText("View paused") : (getApp().getPopupsManager().get("infoPopup") as Popup).setText("View unpaused"); + } + + getPaused() { + return this.#paused; + } +} diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index 7ca1d5d8..60b801f8 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -1,7 +1,6 @@ import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point } from 'leaflet'; import { getApp } from '..'; import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad, ftToM } from '../other/utils'; -import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures, setSpeedType, setAltitudeType, setOnOff, setFollowRoads, bombPoint, carpetBomb, bombBuilding, fireAtArea } from '../server/server'; import { CustomMarker } from '../map/markers/custommarker'; import { SVGInjector } from '@tanem/svg-injector'; import { UnitDatabase } from './databases/unitdatabase'; @@ -610,7 +609,7 @@ export class Unit extends CustomMarker { else { path = [latlng]; } - addDestination(this.ID, path); + getApp().getServerManager().addDestination(this.ID, path); } } @@ -623,109 +622,104 @@ export class Unit extends CustomMarker { /* Units can't attack themselves */ if (!this.#human) if (this.ID != targetID) - attackUnit(this.ID, targetID); + getApp().getServerManager().attackUnit(this.ID, targetID); } followUnit(targetID: number, offset: { "x": number, "y": number, "z": number }) { /* Units can't follow themselves */ if (!this.#human) if (this.ID != targetID) - followUnit(this.ID, targetID, offset); + getApp().getServerManager().followUnit(this.ID, targetID, offset); } landAt(latlng: LatLng) { if (!this.#human) - landAt(this.ID, latlng); + getApp().getServerManager().landAt(this.ID, latlng); } changeSpeed(speedChange: string) { if (!this.#human) - changeSpeed(this.ID, speedChange); + getApp().getServerManager().changeSpeed(this.ID, speedChange); } changeAltitude(altitudeChange: string) { if (!this.#human) - changeAltitude(this.ID, altitudeChange); + getApp().getServerManager().changeAltitude(this.ID, altitudeChange); } setSpeed(speed: number) { if (!this.#human) - setSpeed(this.ID, speed); + getApp().getServerManager().setSpeed(this.ID, speed); } setSpeedType(speedType: string) { if (!this.#human) - setSpeedType(this.ID, speedType); + getApp().getServerManager().setSpeedType(this.ID, speedType); } setAltitude(altitude: number) { if (!this.#human) - setAltitude(this.ID, altitude); + getApp().getServerManager().setAltitude(this.ID, altitude); } setAltitudeType(altitudeType: string) { if (!this.#human) - setAltitudeType(this.ID, altitudeType); + getApp().getServerManager().setAltitudeType(this.ID, altitudeType); } setROE(ROE: string) { if (!this.#human) - setROE(this.ID, ROE); + getApp().getServerManager().setROE(this.ID, ROE); } setReactionToThreat(reactionToThreat: string) { if (!this.#human) - setReactionToThreat(this.ID, reactionToThreat); + getApp().getServerManager().setReactionToThreat(this.ID, reactionToThreat); } setEmissionsCountermeasures(emissionCountermeasure: string) { if (!this.#human) - setEmissionsCountermeasures(this.ID, emissionCountermeasure); - } - - setLeader(isLeader: boolean, wingmenIDs: number[] = []) { - if (!this.#human) - setLeader(this.ID, isLeader, wingmenIDs); + getApp().getServerManager().setEmissionsCountermeasures(this.ID, emissionCountermeasure); } setOnOff(onOff: boolean) { if (!this.#human) - setOnOff(this.ID, onOff); + getApp().getServerManager().setOnOff(this.ID, onOff); } setFollowRoads(followRoads: boolean) { if (!this.#human) - setFollowRoads(this.ID, followRoads); + getApp().getServerManager().setFollowRoads(this.ID, followRoads); } delete(explosion: boolean, immediate: boolean) { - deleteUnit(this.ID, explosion, immediate); + getApp().getServerManager().deleteUnit(this.ID, explosion, immediate); } refuel() { if (!this.#human) - refuel(this.ID); + getApp().getServerManager().refuel(this.ID); } setAdvancedOptions(isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings) { if (!this.#human) - setAdvacedOptions(this.ID, isTanker, isAWACS, TACAN, radio, generalSettings); + getApp().getServerManager().setAdvacedOptions(this.ID, isTanker, isAWACS, TACAN, radio, generalSettings); } bombPoint(latlng: LatLng) { - bombPoint(this.ID, latlng); + getApp().getServerManager().bombPoint(this.ID, latlng); } carpetBomb(latlng: LatLng) { - carpetBomb(this.ID, latlng); + getApp().getServerManager().carpetBomb(this.ID, latlng); } bombBuilding(latlng: LatLng) { - bombBuilding(this.ID, latlng); + getApp().getServerManager().bombBuilding(this.ID, latlng); } fireAtArea(latlng: LatLng) { - fireAtArea(this.ID, latlng); + getApp().getServerManager().fireAtArea(this.ID, latlng); } /***********************************************/ diff --git a/client/src/unit/unitsmanager.ts b/client/src/unit/unitsmanager.ts index c0a0f6d5..4feda9e4 100644 --- a/client/src/unit/unitsmanager.ts +++ b/client/src/unit/unitsmanager.ts @@ -1,7 +1,6 @@ import { LatLng, LatLngBounds } from "leaflet"; import { getApp } from ".."; import { Unit } from "./unit"; -import { cloneUnits, spawnAircrafts, spawnGroundUnits, spawnHelicopters, spawnNavyUnits } from "../server/server"; import { bearingAndDistanceToLatLng, deg2rad, getUnitDatabaseByCategory, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polyContains, polygonArea, randomPointInPoly, randomUnitBlueprint } from "../other/utils"; import { CoalitionArea } from "../map/coalitionarea/coalitionarea"; import { groundUnitDatabase } from "./databases/groundunitdatabase"; @@ -635,7 +634,7 @@ export class UnitsManager { var unit = selectedUnits[idx]; units.push({ ID: unit.ID, location: unit.getPosition() }); } - cloneUnits(units, true, 0 /* No spawn points, we delete the original units */); + getApp().getServerManager().cloneUnits(units, true, 0 /* No spawn points, we delete the original units */); } else { (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Groups can only be created from units of the same category`); } @@ -790,7 +789,7 @@ export class UnitsManager { units.push({ ID: unit.ID, location: position }); }); - cloneUnits(units, false, spawnPoints, (res: any) => { + getApp().getServerManager().cloneUnits(units, false, spawnPoints, (res: any) => { if (res.commandHash !== undefined) { markers.forEach((marker: TemporaryUnitMarker) => { marker.setCommandHash(res.commandHash); @@ -920,14 +919,14 @@ export class UnitsManager { return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + aircraftDatabase.getSpawnPointsByName(unit.unitType)}, 0); - spawnFunction = () => spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints, callback); + spawnFunction = () => getApp().getServerManager().spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints, callback); } else if (category === "Helicopter") { if (airbase == "" && spawnsRestricted) { (getApp().getPopupsManager().get("infoPopup") as Popup).setText("Helicopters can be air spawned during the SETUP phase only"); return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + helicopterDatabase.getSpawnPointsByName(unit.unitType)}, 0); - spawnFunction = () => spawnHelicopters(units, coalition, airbase, country, immediate, spawnPoints, callback); + spawnFunction = () => getApp().getServerManager().spawnHelicopters(units, coalition, airbase, country, immediate, spawnPoints, callback); } else if (category === "GroundUnit") { if (spawnsRestricted) { @@ -935,7 +934,7 @@ export class UnitsManager { return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0); - spawnFunction = () => spawnGroundUnits(units, coalition, country, immediate, spawnPoints, callback); + spawnFunction = () => getApp().getServerManager().spawnGroundUnits(units, coalition, country, immediate, spawnPoints, callback); } else if (category === "NavyUnit") { if (spawnsRestricted) { @@ -943,7 +942,7 @@ export class UnitsManager { return false; } spawnPoints = units.reduce((points: number, unit: UnitSpawnTable) => {return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0); - spawnFunction = () => spawnNavyUnits(units, coalition, country, immediate, spawnPoints, callback); + spawnFunction = () => getApp().getServerManager().spawnNavyUnits(units, coalition, country, immediate, spawnPoints, callback); } if (spawnPoints <= getApp().getMissionManager().getAvailableSpawnPoints()) {