From b3f8ea7961aa65dc3f5aa64aaa1bd11241d5eda6 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Sun, 8 Sep 2024 17:34:21 -0300 Subject: [PATCH 01/20] wip --- .build/main.js | 12447 ++++++++++++++++ .build/main.js.map | 1 + build-ghpages.bat | 10 - index.html | 14 +- package-lock.json | 7010 +++------ package.json | 44 +- run_local_server.bat | 5 - src/App.tsx | 140 - src/main.tsx | 34 + src/playback/instrumentSflib.ts | 256 - src/prefs.ts | 97 + src/project/elem.ts | 188 +- src/project/index.ts | 10 +- src/project/jsonExport.ts | 8 +- src/project/jsonImport.ts | 8 +- src/project/measures.ts | 20 +- src/project/root.ts | 142 +- src/state.ts | 40 + src/theory/chord.ts | 8 +- src/theory/index.ts | 14 +- src/theory/key.ts | 8 +- src/theory/meter.ts | 2 +- src/theory/pitch.ts | 4 +- src/theory/pitchName.ts | 2 +- src/theory/scale.ts | 2 +- src/theory/utils.ts | 1 + src/timeline/Element.tsx | 504 +- src/timeline/draw.ts | 361 + src/timeline/index.ts | 30 +- src/timeline/key_down.ts | 9 + src/timeline/key_up.ts | 9 + src/timeline/layout.ts | 222 + src/timeline/layout_notes.ts | 211 + src/timeline/mouse_down.ts | 121 + src/timeline/mouse_drag.ts | 194 + src/timeline/mouse_move.ts | 44 + src/timeline/mouse_up.ts | 18 + src/timeline/mouse_wheel.ts | 49 + src/timeline/timeline.ts | 440 + src/{util => utils}/binarySearch.ts | 0 src/{util => utils}/listOfPoints.ts | 8 +- src/{util => utils}/listOfRanges.ts | 8 +- src/{util => utils}/mathUtils.ts | 0 src/{util => utils}/midi.ts | 4 +- src/{util => utils}/range.ts | 2 +- src/{util => utils}/rational.ts | 0 src/{util => utils}/rect.ts | 0 src_old/App.tsx | 243 +- src_old/AppContext.ts | 17 - src_old/AppState.ts | 429 - {src => src_old}/MenuEdit.tsx | 0 {src => src_old}/MenuFile.tsx | 0 {src => src_old}/MenuWindow.tsx | 0 {src => src_old}/PlaybackToolbar.tsx | 0 {src => src_old}/command/command.ts | 0 .../command/convertNotesToChords.ts | 0 {src => src_old}/command/file.ts | 0 {src => src_old}/command/history.ts | 0 {src => src_old}/command/index.ts | 0 {src => src_old}/command/playback.ts | 0 {src => src_old}/dockable/Container.tsx | 0 {src => src_old}/dockable/_global.ts | 0 {src => src_old}/dockable/index.ts | 0 {src => src_old}/dockable/state.ts | 0 src_old/editor/editor.js | 1896 --- src_old/editor/track.js | 310 - src_old/editor/trackChords.js | 456 - src_old/editor/trackMarkers.js | 477 - src_old/editor/trackNotes.js | 591 - src_old/editor2/EditorContent.tsx | 228 - src_old/editor2/InspectorContent.tsx | 195 - src_old/editor2/TrackInstrumentContent.tsx | 159 - src_old/editor2/TrackPopup.tsx | 21 - src_old/editor2/editor.ts | 1392 -- src_old/editor2/editorState.ts | 101 - src_old/editor2/track.ts | 67 - src_old/editor2/trackKeyChanges.ts | 249 - src_old/editor2/trackKeyChangesState.ts | 11 - src_old/editor2/trackMeterChanges.ts | 236 - src_old/editor2/trackMeterChangesState.ts | 11 - src_old/editor2/trackNotes.ts | 391 - src_old/editor2/trackNotesPreview.ts | 207 - src_old/editor2/trackNotesPreviewState.ts | 8 - src_old/editor2/trackNotesState.ts | 15 - src_old/editor2/trackState.ts | 12 - src_old/editor2/trackStateManager.ts | 74 - {src => src_old}/main.js | 0 {src => src_old}/menubar/Item.tsx | 0 {src => src_old}/menubar/Root.tsx | 0 {src => src_old}/menubar/index.ts | 0 src_old/playback/PlaybackController.ts | 90 - {src => src_old}/playback/_global.ts | 0 {src => src_old}/playback/index.ts | 0 {src => src_old}/playback/instrument.ts | 0 {src => src_old}/playback/instrumentBasic.ts | 0 src_old/playback/instrumentSflib.ts | 276 +- src_old/playback/library.ts | 91 - src_old/playback/libraryCache.ts | 34 - {src => src_old}/playback/projectFeed.ts | 0 {src => src_old}/playback/sflib.ts | 0 src_old/playback/sflibWorklet.ts | 267 - src_old/playback/synth.ts | 168 - src_old/playback/synthFeed.ts | 56 - {src => src_old}/playback/synthManager.ts | 0 {src => src_old}/popup/Button.tsx | 0 {src => src_old}/popup/Divider.tsx | 0 src_old/popup/MenuBar.tsx | 79 - src_old/popup/MenuFilePopup.tsx | 80 - src_old/popup/PlaybackToolbox.tsx | 56 - {src => src_old}/popup/Root.tsx | 0 {src => src_old}/popup/_global.ts | 0 {src => src_old}/popup/index.ts | 0 {src => src_old}/prefs/_global.ts | 0 {src => src_old}/prefs/index.ts | 0 {src => src_old}/prefs/prefs.ts | 0 src_old/project/ioCompressedStr.js | 333 - src_old/project/ioJson.js | 191 - src_old/project/ioMidi.js | 110 - src_old/project/ioMidi.ts | 120 - src_old/project/playbackSynth.js | 174 - src_old/project/project.js | 280 - src_old/project/project2.ts | 329 - src_old/synth/instrument.js | 168 - src_old/synth/synth.js | 111 - src_old/test.ts | 8 - src_old/timeline/Element.tsx | 393 + src_old/timeline/index.ts | 18 + {src => src_old}/timeline/state.ts | 0 {src => src_old}/timeline/state_keyDown.ts | 0 {src => src_old}/timeline/state_keyUp.ts | 0 {src => src_old}/timeline/state_mouseDown.ts | 0 {src => src_old}/timeline/state_mouseDrag.ts | 0 {src => src_old}/timeline/state_mouseMove.ts | 0 {src => src_old}/timeline/state_mouseUp.tsx | 0 {src => src_old}/timeline/state_mouseWheel.ts | 0 {src => src_old}/timeline/state_render.ts | 0 {src => src_old}/timeline/track.tsx | 0 {src => src_old}/timeline/trackChords.tsx | 0 {src => src_old}/timeline/trackKeyChanges.tsx | 0 .../timeline/trackMeterChanges.tsx | 0 {src => src_old}/timeline/trackNoteBlocks.tsx | 0 .../timeline/trackNoteVelocities.tsx | 0 .../timeline/trackNoteVolumes.tsx | 0 {src => src_old}/timeline/trackNotes.tsx | 0 src_old/toolbox/App.js | 256 - src_old/toolbox/ButtonList.tsx | 67 - src_old/toolbox/DropdownMenu.tsx | 59 - src_old/toolbox/ListBox.tsx | 70 - src_old/toolbox/PlaybackController.js | 129 - src_old/toolbox/Ribbon.js | 400 - src_old/toolbox/ToolboxChord.js | 178 - src_old/toolbox/ToolboxEdit.js | 44 - src_old/toolbox/ToolboxFile.js | 180 - src_old/toolbox/ToolboxInput.js | 26 - src_old/toolbox/ToolboxMarkers.js | 170 - src_old/toolbox/ToolboxNote.js | 58 - src_old/toolbox/ToolboxPlayback.js | 45 - {src => src_old}/types.ts | 0 {src => src_old}/ui/Button.tsx | 0 {src => src_old}/ui/ButtonList.tsx | 0 {src => src_old}/ui/ChordButton.tsx | 0 {src => src_old}/ui/Dial.tsx | 0 {src => src_old}/ui/DropdownMenu.tsx | 0 {src => src_old}/ui/Input.tsx | 0 {src => src_old}/ui/ListBox.tsx | 0 {src => src_old}/ui/LoadingBar.tsx | 0 {src => src_old}/ui/index.ts | 0 {src => src_old}/util/async.ts | 0 {src => src_old}/util/binaryReader.ts | 0 {src => src_old}/util/binaryWriter.ts | 0 {src => src_old}/util/canvasUtils.ts | 0 {src => src_old}/util/globalObservable.ts | 0 {src => src_old}/util/misc.ts | 0 {src => src_old}/util/refState.ts | 0 {src => src_old}/util/wavEncode.ts | 0 {src => src_old}/windows/Inspector.tsx | 0 {src => src_old}/windows/InspectorChord.tsx | 0 .../windows/InspectorKeyChange.tsx | 0 .../windows/InspectorMeterChange.tsx | 0 .../windows/InspectorMultitype.tsx | 0 {src => src_old}/windows/InspectorTrack.tsx | 0 {src => src_old}/windows/InstrumentSelect.tsx | 0 {src => src_old}/windows/Render.tsx | 0 {src => src_old}/windows/Test.tsx | 0 {src => src_old}/windows/Timeline.tsx | 0 {src => src_old}/windows/index.ts | 0 tsconfig.json | 26 +- watch.bat | 1 - webpack.config.cjs | 54 +- 189 files changed, 17563 insertions(+), 18177 deletions(-) create mode 100644 .build/main.js create mode 100644 .build/main.js.map delete mode 100644 build-ghpages.bat delete mode 100644 run_local_server.bat delete mode 100644 src/App.tsx create mode 100644 src/main.tsx delete mode 100644 src/playback/instrumentSflib.ts create mode 100644 src/prefs.ts create mode 100644 src/state.ts create mode 100644 src/timeline/draw.ts create mode 100644 src/timeline/key_down.ts create mode 100644 src/timeline/key_up.ts create mode 100644 src/timeline/layout.ts create mode 100644 src/timeline/layout_notes.ts create mode 100644 src/timeline/mouse_down.ts create mode 100644 src/timeline/mouse_drag.ts create mode 100644 src/timeline/mouse_move.ts create mode 100644 src/timeline/mouse_up.ts create mode 100644 src/timeline/mouse_wheel.ts create mode 100644 src/timeline/timeline.ts rename src/{util => utils}/binarySearch.ts (100%) rename src/{util => utils}/listOfPoints.ts (98%) rename src/{util => utils}/listOfRanges.ts (99%) rename src/{util => utils}/mathUtils.ts (100%) rename src/{util => utils}/midi.ts (98%) rename src/{util => utils}/range.ts (99%) rename src/{util => utils}/rational.ts (100%) rename src/{util => utils}/rect.ts (100%) delete mode 100644 src_old/AppContext.ts delete mode 100644 src_old/AppState.ts rename {src => src_old}/MenuEdit.tsx (100%) rename {src => src_old}/MenuFile.tsx (100%) rename {src => src_old}/MenuWindow.tsx (100%) rename {src => src_old}/PlaybackToolbar.tsx (100%) rename {src => src_old}/command/command.ts (100%) rename {src => src_old}/command/convertNotesToChords.ts (100%) rename {src => src_old}/command/file.ts (100%) rename {src => src_old}/command/history.ts (100%) rename {src => src_old}/command/index.ts (100%) rename {src => src_old}/command/playback.ts (100%) rename {src => src_old}/dockable/Container.tsx (100%) rename {src => src_old}/dockable/_global.ts (100%) rename {src => src_old}/dockable/index.ts (100%) rename {src => src_old}/dockable/state.ts (100%) delete mode 100644 src_old/editor/editor.js delete mode 100644 src_old/editor/track.js delete mode 100644 src_old/editor/trackChords.js delete mode 100644 src_old/editor/trackMarkers.js delete mode 100644 src_old/editor/trackNotes.js delete mode 100644 src_old/editor2/EditorContent.tsx delete mode 100644 src_old/editor2/InspectorContent.tsx delete mode 100644 src_old/editor2/TrackInstrumentContent.tsx delete mode 100644 src_old/editor2/TrackPopup.tsx delete mode 100644 src_old/editor2/editor.ts delete mode 100644 src_old/editor2/editorState.ts delete mode 100644 src_old/editor2/track.ts delete mode 100644 src_old/editor2/trackKeyChanges.ts delete mode 100644 src_old/editor2/trackKeyChangesState.ts delete mode 100644 src_old/editor2/trackMeterChanges.ts delete mode 100644 src_old/editor2/trackMeterChangesState.ts delete mode 100644 src_old/editor2/trackNotes.ts delete mode 100644 src_old/editor2/trackNotesPreview.ts delete mode 100644 src_old/editor2/trackNotesPreviewState.ts delete mode 100644 src_old/editor2/trackNotesState.ts delete mode 100644 src_old/editor2/trackState.ts delete mode 100644 src_old/editor2/trackStateManager.ts rename {src => src_old}/main.js (100%) rename {src => src_old}/menubar/Item.tsx (100%) rename {src => src_old}/menubar/Root.tsx (100%) rename {src => src_old}/menubar/index.ts (100%) delete mode 100644 src_old/playback/PlaybackController.ts rename {src => src_old}/playback/_global.ts (100%) rename {src => src_old}/playback/index.ts (100%) rename {src => src_old}/playback/instrument.ts (100%) rename {src => src_old}/playback/instrumentBasic.ts (100%) delete mode 100644 src_old/playback/library.ts delete mode 100644 src_old/playback/libraryCache.ts rename {src => src_old}/playback/projectFeed.ts (100%) rename {src => src_old}/playback/sflib.ts (100%) delete mode 100644 src_old/playback/sflibWorklet.ts delete mode 100644 src_old/playback/synth.ts delete mode 100644 src_old/playback/synthFeed.ts rename {src => src_old}/playback/synthManager.ts (100%) rename {src => src_old}/popup/Button.tsx (100%) rename {src => src_old}/popup/Divider.tsx (100%) delete mode 100644 src_old/popup/MenuBar.tsx delete mode 100644 src_old/popup/MenuFilePopup.tsx delete mode 100644 src_old/popup/PlaybackToolbox.tsx rename {src => src_old}/popup/Root.tsx (100%) rename {src => src_old}/popup/_global.ts (100%) rename {src => src_old}/popup/index.ts (100%) rename {src => src_old}/prefs/_global.ts (100%) rename {src => src_old}/prefs/index.ts (100%) rename {src => src_old}/prefs/prefs.ts (100%) delete mode 100644 src_old/project/ioCompressedStr.js delete mode 100644 src_old/project/ioJson.js delete mode 100644 src_old/project/ioMidi.js delete mode 100644 src_old/project/ioMidi.ts delete mode 100644 src_old/project/playbackSynth.js delete mode 100644 src_old/project/project.js delete mode 100644 src_old/project/project2.ts delete mode 100644 src_old/synth/instrument.js delete mode 100644 src_old/synth/synth.js delete mode 100644 src_old/test.ts create mode 100644 src_old/timeline/Element.tsx create mode 100644 src_old/timeline/index.ts rename {src => src_old}/timeline/state.ts (100%) rename {src => src_old}/timeline/state_keyDown.ts (100%) rename {src => src_old}/timeline/state_keyUp.ts (100%) rename {src => src_old}/timeline/state_mouseDown.ts (100%) rename {src => src_old}/timeline/state_mouseDrag.ts (100%) rename {src => src_old}/timeline/state_mouseMove.ts (100%) rename {src => src_old}/timeline/state_mouseUp.tsx (100%) rename {src => src_old}/timeline/state_mouseWheel.ts (100%) rename {src => src_old}/timeline/state_render.ts (100%) rename {src => src_old}/timeline/track.tsx (100%) rename {src => src_old}/timeline/trackChords.tsx (100%) rename {src => src_old}/timeline/trackKeyChanges.tsx (100%) rename {src => src_old}/timeline/trackMeterChanges.tsx (100%) rename {src => src_old}/timeline/trackNoteBlocks.tsx (100%) rename {src => src_old}/timeline/trackNoteVelocities.tsx (100%) rename {src => src_old}/timeline/trackNoteVolumes.tsx (100%) rename {src => src_old}/timeline/trackNotes.tsx (100%) delete mode 100644 src_old/toolbox/App.js delete mode 100644 src_old/toolbox/ButtonList.tsx delete mode 100644 src_old/toolbox/DropdownMenu.tsx delete mode 100644 src_old/toolbox/ListBox.tsx delete mode 100644 src_old/toolbox/PlaybackController.js delete mode 100644 src_old/toolbox/Ribbon.js delete mode 100644 src_old/toolbox/ToolboxChord.js delete mode 100644 src_old/toolbox/ToolboxEdit.js delete mode 100644 src_old/toolbox/ToolboxFile.js delete mode 100644 src_old/toolbox/ToolboxInput.js delete mode 100644 src_old/toolbox/ToolboxMarkers.js delete mode 100644 src_old/toolbox/ToolboxNote.js delete mode 100644 src_old/toolbox/ToolboxPlayback.js rename {src => src_old}/types.ts (100%) rename {src => src_old}/ui/Button.tsx (100%) rename {src => src_old}/ui/ButtonList.tsx (100%) rename {src => src_old}/ui/ChordButton.tsx (100%) rename {src => src_old}/ui/Dial.tsx (100%) rename {src => src_old}/ui/DropdownMenu.tsx (100%) rename {src => src_old}/ui/Input.tsx (100%) rename {src => src_old}/ui/ListBox.tsx (100%) rename {src => src_old}/ui/LoadingBar.tsx (100%) rename {src => src_old}/ui/index.ts (100%) rename {src => src_old}/util/async.ts (100%) rename {src => src_old}/util/binaryReader.ts (100%) rename {src => src_old}/util/binaryWriter.ts (100%) rename {src => src_old}/util/canvasUtils.ts (100%) rename {src => src_old}/util/globalObservable.ts (100%) rename {src => src_old}/util/misc.ts (100%) rename {src => src_old}/util/refState.ts (100%) rename {src => src_old}/util/wavEncode.ts (100%) rename {src => src_old}/windows/Inspector.tsx (100%) rename {src => src_old}/windows/InspectorChord.tsx (100%) rename {src => src_old}/windows/InspectorKeyChange.tsx (100%) rename {src => src_old}/windows/InspectorMeterChange.tsx (100%) rename {src => src_old}/windows/InspectorMultitype.tsx (100%) rename {src => src_old}/windows/InspectorTrack.tsx (100%) rename {src => src_old}/windows/InstrumentSelect.tsx (100%) rename {src => src_old}/windows/Render.tsx (100%) rename {src => src_old}/windows/Test.tsx (100%) rename {src => src_old}/windows/Timeline.tsx (100%) rename {src => src_old}/windows/index.ts (100%) delete mode 100644 watch.bat diff --git a/.build/main.js b/.build/main.js new file mode 100644 index 0000000..3774c83 --- /dev/null +++ b/.build/main.js @@ -0,0 +1,12447 @@ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "./src/prefs.ts": +/*!**********************!*\ + !*** ./src/prefs.ts ***! + \**********************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ makeNew: () => (/* binding */ makeNew) +/* harmony export */ }); +function makeNew() { + return { + timeline: { + bkgColor: "#202225", + bkgAlternateMeasureColor: "#1a1c1f", + bkgInactiveOverlayColor: "#0008", + trackVBorderColor: "#888", + trackHBorderColor: "#888", + selectionCursorColor: "#0af", + selectionBkgColor: "#8cf8", + playbackCursorColor: "#f00", + trackSeparatorColor: "#aaa", + measureColor: "#040404", + submeasureColor: "#080808", + halfSubmeasureColor: "#181818", + measureLabelColor: "#aaa", + octaveLabelColor: "#aaa", + meterChangeColor: "#0cf", + keyChangeColor: "#f0c", + noteVelocityMarkerColor: "#0c4", + noteVelocityMarkerInactiveColor: "#063", + keyPan: " ", + keyPencil: "a", + keySelectMultiple: "control", + keySelectRange: "shift", + keySelectRect: "shift", + keySelectClone: "alt", + keyDisplaceCursor2: "shift", + keyDisplaceFast: "control", + keyDisplaceChromatically: "shift", + keyDisplaceStretch: "shift", + mouseDoubleClickThresholdMs: 300, + mouseDragXLockedDistance: 10, + mouseDragYLockedDistance: 10, + mouseEdgeScrollThreshold: 10, + mouseEdgeScrollSpeed: 1 + } + }; +} + +/***/ }), + +/***/ "./src/project/elem.ts": +/*!*****************************!*\ + !*** ./src/project/elem.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ DefaultChordVolumeDb: () => (/* binding */ DefaultChordVolumeDb), +/* harmony export */ DefaultVolumeDb: () => (/* binding */ DefaultVolumeDb), +/* harmony export */ MaxVolumeDb: () => (/* binding */ MaxVolumeDb), +/* harmony export */ MinVolumeDb: () => (/* binding */ MinVolumeDb), +/* harmony export */ elemModify: () => (/* binding */ elemModify), +/* harmony export */ makeChord: () => (/* binding */ makeChord), +/* harmony export */ makeKeyChange: () => (/* binding */ makeKeyChange), +/* harmony export */ makeMeterChange: () => (/* binding */ makeMeterChange), +/* harmony export */ makeNote: () => (/* binding */ makeNote), +/* harmony export */ makeTrackChords: () => (/* binding */ makeTrackChords), +/* harmony export */ makeTrackKeyChanges: () => (/* binding */ makeTrackKeyChanges), +/* harmony export */ makeTrackMeterChanges: () => (/* binding */ makeTrackMeterChanges), +/* harmony export */ makeTrackNotes: () => (/* binding */ makeTrackNotes), +/* harmony export */ trackDisplayName: () => (/* binding */ trackDisplayName) +/* harmony export */ }); +/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); + +const MinVolumeDb = -30; +const MaxVolumeDb = 0; +const DefaultVolumeDb = 0; +const DefaultChordVolumeDb = -4; +function elemModify(original, changes) { + return { + ...original, + ...changes + }; +} +function makeTrackNotes() { + return { + type: "track", + trackType: "notes", + id: -1, + parentId: 0, + range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), + name: "", + mute: false, + solo: false + }; +} +function makeTrackChords() { + return { + type: "track", + trackType: "chords", + id: -1, + parentId: 0, + range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), + name: "Chords", + mute: false, + solo: false + }; +} +function trackDisplayName(track) { + if (track.name) return track.name; + return "New Track"; +} +function makeTrackKeyChanges() { + return { + type: "track", + trackType: "keyChanges", + id: -1, + parentId: 0, + range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), + name: "Key Changes" + }; +} +function makeTrackMeterChanges() { + return { + type: "track", + trackType: "meterChanges", + id: -1, + parentId: 0, + range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), + name: "Meter Changes" + }; +} +function makeMeterChange(parentId, time, meter) { + return { + type: "meterChange", + id: -1, + parentId, + range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromPoint(time), + meter + }; +} +function makeKeyChange(parentId, time, key) { + return { + type: "keyChange", + id: -1, + parentId, + range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromPoint(time), + key + }; +} +function makeNote(parentId, range, midiPitch) { + return { + type: "note", + id: -1, + parentId, + range, + midiPitch + }; +} +function makeChord(parentId, range, chord) { + return { + type: "chord", + id: -1, + parentId, + range, + chord + }; +} + +/***/ }), + +/***/ "./src/project/index.ts": +/*!******************************!*\ + !*** ./src/project/index.ts ***! + \******************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ DefaultChordVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.DefaultChordVolumeDb), +/* harmony export */ DefaultVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.DefaultVolumeDb), +/* harmony export */ MAX_RATIONAL_DENOMINATOR: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR), +/* harmony export */ MaxVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.MaxVolumeDb), +/* harmony export */ MinVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.MinVolumeDb), +/* harmony export */ cloneElem: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.cloneElem), +/* harmony export */ defaultKey: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.defaultKey), +/* harmony export */ defaultMeter: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.defaultMeter), +/* harmony export */ elemModify: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.elemModify), +/* harmony export */ ensureMeasureCacheRefreshed: () => (/* reexport safe */ _measures__WEBPACK_IMPORTED_MODULE_1__.ensureMeasureCacheRefreshed), +/* harmony export */ getAbsoluteRange: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange), +/* harmony export */ getAbsoluteTime: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteTime), +/* harmony export */ getElem: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getElem), +/* harmony export */ getMillisecondsAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getMillisecondsAt), +/* harmony export */ getRangeForElems: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getRangeForElems), +/* harmony export */ getRelativeRange: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getRelativeRange), +/* harmony export */ getRelativeTime: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getRelativeTime), +/* harmony export */ getTrack: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getTrack), +/* harmony export */ iterMeasuresAtRange: () => (/* reexport safe */ _measures__WEBPACK_IMPORTED_MODULE_1__.iterMeasuresAtRange), +/* harmony export */ keyAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.keyAt), +/* harmony export */ keyChangeTrackId: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.keyChangeTrackId), +/* harmony export */ makeChord: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeChord), +/* harmony export */ makeEmpty: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.makeEmpty), +/* harmony export */ makeKeyChange: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeKeyChange), +/* harmony export */ makeMeterChange: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeMeterChange), +/* harmony export */ makeNew: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.makeNew), +/* harmony export */ makeNote: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeNote), +/* harmony export */ makeTest: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.makeTest), +/* harmony export */ makeTrackChords: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackChords), +/* harmony export */ makeTrackKeyChanges: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackKeyChanges), +/* harmony export */ makeTrackMeterChanges: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackMeterChanges), +/* harmony export */ makeTrackNotes: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackNotes), +/* harmony export */ meterAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.meterAt), +/* harmony export */ meterChangeAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.meterChangeAt), +/* harmony export */ meterChangeTrackId: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.meterChangeTrackId), +/* harmony export */ parentTrackFor: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.parentTrackFor), +/* harmony export */ splitElem: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.splitElem), +/* harmony export */ trackDisplayName: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.trackDisplayName), +/* harmony export */ upsertElement: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.upsertElement), +/* harmony export */ upsertTrack: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.upsertTrack), +/* harmony export */ withRefreshedRange: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.withRefreshedRange) +/* harmony export */ }); +/* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./root */ "./src/project/root.ts"); +/* harmony import */ var _measures__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./measures */ "./src/project/measures.ts"); +/* harmony import */ var _elem__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./elem */ "./src/project/elem.ts"); +//export * from "./_global" + + + +//export * from "./midiImport" +//export * from "./midiExport" +//export * from "./jsonExport" +//export * from "./jsonImport" + +/***/ }), + +/***/ "./src/project/measures.ts": +/*!*********************************!*\ + !*** ./src/project/measures.ts ***! + \*********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ensureMeasureCacheRefreshed: () => (/* binding */ ensureMeasureCacheRefreshed), +/* harmony export */ iterMeasuresAtRange: () => (/* binding */ iterMeasuresAtRange) +/* harmony export */ }); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/project/index.ts"); +/* harmony import */ var _utils_binarySearch_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/binarySearch.ts */ "./src/utils/binarySearch.ts"); + + +let measureCacheKey = null; +let measureCache = []; +let firstMeterCh = null; +let lastMeterCh = null; +function ensureMeasureCacheRefreshed(project) { + const meterChangeTrackId = _index_ts__WEBPACK_IMPORTED_MODULE_0__.meterChangeTrackId(project); + const meterChangeList = project.lists.get(meterChangeTrackId); + if (meterChangeList === measureCacheKey) return; + measureCacheKey = meterChangeList; + measureCache = []; + if (!meterChangeList) return; + let num = 0; + for (const [elem1, elem2] of meterChangeList.iterAllPairwise()) { + if (!elem1) firstMeterCh = elem2; + if (!elem2) lastMeterCh = elem1; + if (!elem1 || !elem2) continue; + const meterCh1 = elem1; + const meterCh2 = elem2; + let numLocal = 0; + for (const [measureN, measureD, time1, time2] of meterCh1.meter.iterMeasuresPairwise(meterCh1.range.start)) { + if (meterCh2 && time1.compare(meterCh2.range.start) >= 0) break; + measureCache.push({ + num, + numLocal, + time1, + time2: time2.min(meterCh2 ? meterCh2.range.start : time2), + meterCh: meterCh1 + }); + num++; + numLocal++; + } + } +} +function* iterMeasuresAtRange(project, range) { + ensureMeasureCacheRefreshed(project); + const measureStart = _utils_binarySearch_ts__WEBPACK_IMPORTED_MODULE_1__["default"].findPreviousOrEqual(measureCache, m => range.start.compare(m.time1)); + if (measureStart === null && firstMeterCh) { + let time = firstMeterCh.range.start; + let num = 0; + while (time.compare(range.start) > 0) { + time = time.subtract(firstMeterCh.meter.fullCycleDuration); + num--; + } + while (time.compare(firstMeterCh.range.start) < 0) { + const time2 = time.add(firstMeterCh.meter.fullCycleDuration); + if (time2.compare(range.start) >= 0) { + yield { + meterCh: firstMeterCh, + num, + numLocal: num, + time1: time, + time2 + }; + } + time = time2; + num++; + } + } + let lastMeasureNum = -1; + let measureIndex = measureStart ?? 0; + while (true) { + if (measureIndex >= measureCache.length) break; + const measure = measureCache[measureIndex]; + if (measure.time1.compare(range.end) >= 0) break; + yield measure; + lastMeasureNum = measure.num; + measureIndex++; + } + if (lastMeterCh) { + let num = lastMeasureNum + 1; + let time = lastMeterCh.range.start; + while (time.compare(range.end) < 0) { + const time2 = time.add(lastMeterCh.meter.fullCycleDuration); + if (time2.compare(range.start) >= 0) { + yield { + meterCh: lastMeterCh, + num, + numLocal: num, + time1: time, + time2 + }; + } + time = time2; + num++; + } + } +} + +/***/ }), + +/***/ "./src/project/root.ts": +/*!*****************************!*\ + !*** ./src/project/root.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MAX_RATIONAL_DENOMINATOR: () => (/* binding */ MAX_RATIONAL_DENOMINATOR), +/* harmony export */ cloneElem: () => (/* binding */ cloneElem), +/* harmony export */ defaultKey: () => (/* binding */ defaultKey), +/* harmony export */ defaultMeter: () => (/* binding */ defaultMeter), +/* harmony export */ getAbsoluteRange: () => (/* binding */ getAbsoluteRange), +/* harmony export */ getAbsoluteTime: () => (/* binding */ getAbsoluteTime), +/* harmony export */ getElem: () => (/* binding */ getElem), +/* harmony export */ getMillisecondsAt: () => (/* binding */ getMillisecondsAt), +/* harmony export */ getRangeForElems: () => (/* binding */ getRangeForElems), +/* harmony export */ getRelativeRange: () => (/* binding */ getRelativeRange), +/* harmony export */ getRelativeTime: () => (/* binding */ getRelativeTime), +/* harmony export */ getTrack: () => (/* binding */ getTrack), +/* harmony export */ keyAt: () => (/* binding */ keyAt), +/* harmony export */ keyChangeTrackId: () => (/* binding */ keyChangeTrackId), +/* harmony export */ makeEmpty: () => (/* binding */ makeEmpty), +/* harmony export */ makeNew: () => (/* binding */ makeNew), +/* harmony export */ makeTest: () => (/* binding */ makeTest), +/* harmony export */ meterAt: () => (/* binding */ meterAt), +/* harmony export */ meterChangeAt: () => (/* binding */ meterChangeAt), +/* harmony export */ meterChangeTrackId: () => (/* binding */ meterChangeTrackId), +/* harmony export */ parentTrackFor: () => (/* binding */ parentTrackFor), +/* harmony export */ splitElem: () => (/* binding */ splitElem), +/* harmony export */ upsertElement: () => (/* binding */ upsertElement), +/* harmony export */ upsertTrack: () => (/* binding */ upsertTrack), +/* harmony export */ withRefreshedRange: () => (/* binding */ withRefreshedRange) +/* harmony export */ }); +/* harmony import */ var immutable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! immutable */ "./node_modules/immutable/dist/immutable.es.js"); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/project/index.ts"); +/* harmony import */ var _theory__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../theory */ "./src/theory/index.ts"); +/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); +/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); +/* harmony import */ var _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/listOfRanges.ts */ "./src/utils/listOfRanges.ts"); + + + + + + + +// Least Common Multiple of 2, 3, 4, 5, 6, 7, 8, 9, and 10. +const MAX_RATIONAL_DENOMINATOR = 2520; +function makeEmpty() { + return { + nextId: 1, + range: new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](4)), + baseBpm: 120, + tracks: [], + lists: immutable__WEBPACK_IMPORTED_MODULE_5__["default"].Map(), + elems: immutable__WEBPACK_IMPORTED_MODULE_5__["default"].Map(), + keyChangeTrackId: -1, + meterChangeTrackId: -1, + chordTrackId: -1, + noteTrackId: -1 + }; +} +function makeNew() { + let project = makeEmpty(); + const track1Id = project.nextId; + project.keyChangeTrackId = track1Id; + project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackKeyChanges()); + const track2Id = project.nextId; + project.meterChangeTrackId = track2Id; + project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackMeterChanges()); + project = upsertElement(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeKeyChange(track1Id, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), _theory__WEBPACK_IMPORTED_MODULE_1__.Key.parse("C Major"))); + project = upsertElement(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeMeterChange(track2Id, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), new _theory__WEBPACK_IMPORTED_MODULE_1__.Meter(4, 4))); + const track3Id = project.nextId; + project.chordTrackId = track3Id; + project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackChords()); + const track4Id = project.nextId; + project.noteTrackId = track4Id; + project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackNotes()); + return project; +} +function makeTest() { + let project = makeNew(); + for (let i = 0; i < 24; i++) project = upsertElement(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeNote(project.noteTrackId, _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"].fromStartDuration(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](i, 4), new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](1, 4)), _theory__WEBPACK_IMPORTED_MODULE_1__.Utils.midiMiddleC + i)); + return project; +} +function upsertTrack(project, track, remove = false, insertBefore = -1) { + let nextId = project.nextId; + let tracks = project.tracks; + if (track.id < 0) { + track = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(track, { + id: nextId + }); + nextId++; + } + if (remove) { + const trackIndex = tracks.findIndex(t => t.id === track.id); + if (trackIndex >= 0) tracks = [...tracks.slice(0, trackIndex), ...tracks.slice(trackIndex + 1)]; + } else { + const trackIndex = tracks.findIndex(t => t.id === track.id); + if (trackIndex < 0) { + if (insertBefore < 0) tracks = [...tracks, track];else tracks = [...tracks.slice(0, insertBefore), track, ...tracks.slice(insertBefore)]; + } else { + tracks = [...tracks.slice(0, trackIndex), track, ...tracks.slice(trackIndex + 1)]; + } + } + let elems = project.elems; + if (remove) elems = elems.delete(track.id);else elems = elems.set(track.id, track); + return { + ...project, + nextId, + elems, + tracks + }; +} +function upsertElement(project, elem) { + let nextId = project.nextId; + if (elem.id < 0) { + elem = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, { + id: nextId + }); + nextId++; + } + const prevElem = project.elems.get(elem.id); + const changeParent = !!prevElem && prevElem.parentId != elem.parentId; + if (!changeParent) { + let list = project.lists.get(elem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); + list = list.upsert(elem); + let elems = project.elems.set(elem.id, elem); + let lists = project.lists.set(elem.parentId, list); + return { + ...project, + nextId, + elems, + lists + }; + } else if (elem.parentId < 0) { + let prevList = project.lists.get(prevElem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); + prevList = prevList.removeById(prevElem.id); + let elems = project.elems.delete(elem.id); + let lists = project.lists.set(prevElem.parentId, prevList); + return { + ...project, + nextId, + elems, + lists + }; + } else { + let prevList = project.lists.get(prevElem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); + prevList = prevList.removeById(prevElem.id); + let nextList = project.lists.get(elem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); + nextList = nextList.upsert(elem); + let elems = project.elems.set(elem.id, elem); + let lists = project.lists.set(prevElem.parentId, prevList).set(elem.parentId, nextList); + return { + ...project, + nextId, + elems, + lists + }; + } +} +function keyChangeTrackId(project) { + return project.keyChangeTrackId; +} +function meterChangeTrackId(project) { + return project.meterChangeTrackId; +} +function keyAt(project, trackId, time) { + const keyChangeTrackId = _index_ts__WEBPACK_IMPORTED_MODULE_0__.keyChangeTrackId(project); + const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId); + if (!keyChangeTrackTimedElems) return defaultKey(); + const keyCh = keyChangeTrackTimedElems.findActiveAt(time); + if (keyCh) return keyCh.key; + const firstKeyCh = keyChangeTrackTimedElems.findFirst(); + if (firstKeyCh) return firstKeyCh.key; + return defaultKey(); +} +function meterChangeAt(project, trackId, time) { + const meterChangeTrackId = _index_ts__WEBPACK_IMPORTED_MODULE_0__.meterChangeTrackId(project); + const meterChangeTrackTimedElems = project.lists.get(meterChangeTrackId); + if (!meterChangeTrackTimedElems) return null; + const meterCh = meterChangeTrackTimedElems.findActiveAt(time); + if (meterCh) return meterCh; + const firstMeterCh = meterChangeTrackTimedElems.findFirst(); + if (firstMeterCh) return firstMeterCh; + return null; +} +function meterAt(project, trackId, time) { + const meterCh = meterChangeAt(project, trackId, time); + if (meterCh) return meterCh.meter; + return defaultMeter(); +} +function withRefreshedRange(project) { + let range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](4)); + for (const track of project.tracks) { + const list = project.lists.get(track.id); + if (list) range = range.merge(list.getTotalRange()); + } + if (range.start.compare(project.range.start) == 0 && range.end.compare(project.range.end) == 0) return project; + return { + ...project, + range + }; +} +function getElem(project, id, type) { + const elem = project.elems.get(id); + if (!elem || elem.type != type) return null; + return elem; +} +function getTrack(project, id, trackType) { + const elem = project.elems.get(id); + if (!elem || elem.type != "track" || elem.trackType != trackType) return null; + return elem; +} +function cloneElem(fromProject, elem, toProject) { + const newElem = { + ...elem + }; + newElem.id = -1; + const newId = toProject.nextId; + toProject = _index_ts__WEBPACK_IMPORTED_MODULE_0__.upsertElement(toProject, newElem); + const innerList = fromProject.lists.get(elem.id); + if (innerList) { + for (const innerElem of innerList.iterAll()) { + const newInnerElem = { + ...innerElem + }; + newInnerElem.parentId = newId; + toProject = cloneElem(fromProject, newInnerElem, toProject); + } + } + return toProject; +} +function splitElem(project, elem, splitRange) { + const origProject = project; + const absRange = getAbsoluteRange(origProject, elem.parentId, elem.range); + if (!absRange.overlapsRange(splitRange)) return project; + const removeElem = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, { + parentId: -1 + }); + project = _index_ts__WEBPACK_IMPORTED_MODULE_0__.upsertElement(project, removeElem); + project = splitInnerElem(origProject, project, elem.parentId, elem, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), splitRange, absRange); + return project; +} +function splitInnerElem(origProject, project, newParentId, elem, relativeDisplace, splitRange, keepRange) { + const innerList = origProject.lists.get(elem.id); + + // FIXME: Also keep inner elements that were outside parent's range + const absRange = getAbsoluteRange(origProject, elem.parentId, elem.range); + if (!absRange.overlapsRange(keepRange)) return project; + for (const slice of absRange.iterSlices(splitRange)) { + const newElemPart = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, { + id: -1, + parentId: newParentId, + range: getRelativeRange(origProject, elem.parentId, slice).subtract(relativeDisplace) + }); + const newElemPartId = project.nextId; + project = _index_ts__WEBPACK_IMPORTED_MODULE_0__.upsertElement(project, newElemPart); + if (innerList) { + const innerRelativeDisplace = slice.start.subtract(absRange.start); + for (const innerElem of innerList.iterAll()) { + project = splitInnerElem(origProject, project, newElemPartId, innerElem, innerRelativeDisplace, splitRange, slice); + } + } + } + return project; +} +function parentTrackFor(project, elemId) { + while (true) { + const elem = project.elems.get(elemId); + if (!elem) return null; + if (elem.type == "track") return elem; + elemId = elem.parentId; + } +} +function getAbsoluteTime(project, parentId, time) { + while (true) { + const elem = project.elems.get(parentId); + if (!elem) return time; + if (elem.type == "track") return time; + time = time.add(elem.range.start); + parentId = elem.parentId; + } +} +function getRelativeTime(project, parentId, time) { + while (true) { + const elem = project.elems.get(parentId); + if (!elem) return time; + if (elem.type == "track") return time; + time = time.subtract(elem.range.start); + parentId = elem.parentId; + } +} +function getAbsoluteRange(project, parentId, range) { + while (true) { + const elem = project.elems.get(parentId); + if (!elem) return range; + if (elem.type == "track") return range; + range = range.displace(elem.range.start); + parentId = elem.parentId; + } +} +function getRelativeRange(project, parentId, range) { + while (true) { + const elem = project.elems.get(parentId); + if (!elem) return range; + if (elem.type == "track") return range; + range = range.subtract(elem.range.start); + parentId = elem.parentId; + } +} +function getRangeForElems(project, elemIds) { + let range = null; + for (const id of elemIds) { + const elem = project.elems.get(id); + if (!elem) continue; + if (elem.type == "track") continue; + const absRange = _index_ts__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange(project, elem.parentId, elem.range); + range = _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"].merge(range, absRange); + } + return range; +} +function getMillisecondsAt(project, time) { + const measuresPerSecond = project.baseBpm / 4 / 60; + return time.subtract(project.range.start).asFloat() / measuresPerSecond * 1000; +} +function defaultKey() { + return _theory__WEBPACK_IMPORTED_MODULE_1__.Key.parse("C Major"); +} +function defaultMeter() { + return new _theory__WEBPACK_IMPORTED_MODULE_1__.Meter(4, 4); +} + +/***/ }), + +/***/ "./src/state.ts": +/*!**********************!*\ + !*** ./src/state.ts ***! + \**********************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ get: () => (/* binding */ get), +/* harmony export */ makeNew: () => (/* binding */ makeNew), +/* harmony export */ refresh: () => (/* binding */ refresh) +/* harmony export */ }); +/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./project */ "./src/project/index.ts"); +/* harmony import */ var _timeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./timeline */ "./src/timeline/index.ts"); +/* harmony import */ var _prefs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./prefs */ "./src/prefs.ts"); + + + + +const [state, setState] = solid_js__WEBPACK_IMPORTED_MODULE_3__.createSignal(makeNew()); +function makeNew() { + return { + test: 0, + prefs: _prefs__WEBPACK_IMPORTED_MODULE_2__.makeNew(), + project: { + root: _project__WEBPACK_IMPORTED_MODULE_0__.makeTest() + }, + timeline: _timeline__WEBPACK_IMPORTED_MODULE_1__.makeNew() + }; +} +function get() { + return state(); +} +function refresh() { + setState({ + ...state() + }); +} + +/***/ }), + +/***/ "./src/theory/chord.ts": +/*!*****************************!*\ + !*** ./src/theory/chord.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ chordKinds: () => (/* binding */ chordKinds), +/* harmony export */ "default": () => (/* binding */ Chord) +/* harmony export */ }); +/* harmony import */ var _utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/mathUtils.ts */ "./src/utils/mathUtils.ts"); +/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); + + +const chordKinds = [{ + pitches: [0, 4, 7], + id: "M", + symbol: [false, "", null], + name: "Major", + startGroup: "Triads" +}, { + pitches: [0, 3, 7], + id: "m", + symbol: [true, "", null], + name: "Minor" +}, { + pitches: [0, 4, 8], + id: "+", + symbol: [false, "", "+"], + name: "Augmented" +}, { + pitches: [0, 3, 6], + id: "o", + symbol: [true, "", "o"], + name: "Diminished" +}, { + pitches: [0, 2, 6], + id: "oo", + symbol: [true, "", "oo"], + name: "Doubly-Diminished" +}, { + pitches: [0, 4, 6], + id: "b5", + symbol: [false, "", "(b5)"], + name: "Flat-Fifth" +}, { + pitches: [0, 7], + id: "5", + symbol: [false, "", "5"], + name: "Power" +}, { + pitches: [0, 4, 7, 9], + id: "6", + symbol: [false, "", "6"], + name: "Major Sixth", + startGroup: "Sixths" +}, { + pitches: [0, 3, 7, 9], + id: "m6", + symbol: [true, "", "6"], + name: "Minor Sixth" +}, { + pitches: [0, 4, 7, 10], + id: "7", + symbol: [false, "", "7"], + name: "Dominant Seventh", + startGroup: "Sevenths" +}, { + pitches: [0, 4, 7, 11], + id: "maj7", + symbol: [false, "", "M7"], + name: "Major Seventh" +}, { + pitches: [0, 3, 7, 10], + id: "m7", + symbol: [true, "", "7"], + name: "Minor Seventh" +}, { + pitches: [0, 3, 7, 11], + id: "mmaj7", + symbol: [true, "", "M7"], + name: "Minor-Major Seventh" +}, { + pitches: [0, 4, 8, 10], + id: "+7", + symbol: [false, "+", "7"], + name: "Augmented Seventh" +}, { + pitches: [0, 4, 8, 11], + id: "+maj7", + symbol: [false, "+", "M7"], + name: "Augmented Major Seventh" +}, { + pitches: [0, 3, 6, 9], + id: "o7", + symbol: [true, "", "o7"], + name: "Diminished Seventh" +}, { + pitches: [0, 3, 6, 10], + id: "%7", + symbol: [true, "", "ø7"], + name: "Half-Diminished Seventh" +}, { + pitches: [0, 4, 7, 10, 14], + id: "9", + symbol: [false, "", "9"], + name: "Dominant Ninth", + startGroup: "Ninths" +}, { + pitches: [0, 4, 7, 11, 14], + id: "maj9", + symbol: [false, "", "M9"], + name: "Major Ninth" +}, { + pitches: [0, 3, 7, 10, 14], + id: "m9", + symbol: [true, "", "9"], + name: "Minor Ninth" +}, { + pitches: [0, 3, 7, 11, 14], + id: "mmaj9", + symbol: [true, "", "M9"], + name: "Minor-Major Ninth" +}, { + pitches: [0, 3, 7, 10, 13], + id: "9?", + symbol: [true, "", "9?"], + name: "???" +}, { + pitches: [0, 4, 8, 10, 14], + id: "+9", + symbol: [false, "+", "9"], + name: "Augmented Ninth" +}, { + pitches: [0, 4, 8, 11, 14], + id: "+maj9", + symbol: [false, "+", "M9"], + name: "Augmented Major Ninth" +}, { + pitches: [0, 3, 6, 9, 14], + id: "o9", + symbol: [true, "", "o9"], + name: "Diminished Ninth" +}, { + pitches: [0, 3, 6, 9, 13], + id: "ob9", + symbol: [true, "", "o♭9"], + name: "Diminished Minor Ninth" +}, { + pitches: [0, 3, 6, 10, 14], + id: "%9", + symbol: [true, "", "ø9"], + name: "Half-Diminished Ninth" +}, { + pitches: [0, 3, 6, 10, 13], + id: "%b9", + symbol: [true, "", "ø♭9"], + name: "Half-Diminished Minor Ninth" +}]; +class Chord { + static kinds = chordKinds; + constructor(rootChroma, kind, inversion = 0, modifiers = []) { + this.rootChroma = rootChroma; + this.kind = kind; + this.inversion = inversion; + this.modifiers = modifiers; + } + withChanges(obj) { + return Object.assign(new Chord(this.rootChroma, this.kind, this.inversion, this.modifiers), obj); + } + static kindFromId(id) { + return chordKinds.findIndex(k => k.id === id); + } + static kindFromPitches(pitches) { + return chordKinds.findIndex(k => k.pitches.length === pitches.length && k.pitches.every((p, i) => pitches[i] === p)); + } + static suggestChordsForPitches(pitches) { + const suggestions = []; + for (let k = 0; k < chordKinds.length; k++) { + const kind = chordKinds[k]; + for (let root = 0; root < pitches.length; root++) { + const rootPitch = pitches[root]; + const matches = new Set(); + let misses = 0; + for (let i = 0; i < pitches.length; i++) { + const pitch = pitches[(root + i) % pitches.length]; + const relPitch = _utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__.mod(pitch - rootPitch, 12); + const kindMatch = kind.pitches.findIndex(p => p === relPitch); + if (kindMatch >= 0) matches.add(kindMatch);else misses++; + } + suggestions.push({ + chord: new Chord(_utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__.mod(rootPitch, 12), k, 0, []), + matches: matches.size, + misses + }); + } + } + suggestions.sort((a, b) => { + if (a.misses != b.misses) return a.misses - b.misses; + return b.matches - a.matches; + }); + + //console.log("suggestions", pitches, suggestions) + return suggestions.slice(0, 10); + } + get kindId() { + return chordKinds[this.kind].id; + } + romanBase(key) { + const degree = key.degreeForMidi(this.rootChroma); + const chordKind = chordKinds[this.kind] || { + symbol: [false, "", "?"] + }; + let roman = Math.floor(degree); + let accidental = 0; + if (Math.floor(degree) != degree) { + roman = _utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__.mod(roman + 1, 7); + accidental = -1; + } + let baseStr = _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].accidentalToStr(accidental, true) + _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].degreeToRomanStr(roman); + if (chordKind.symbol[0]) baseStr = baseStr.toLowerCase(); + return baseStr + chordKind.symbol[1]; + } + romanSup(key) { + const chordKind = chordKinds[this.kind] || { + symbol: [false, "", "?"] + }; + let supStr = chordKind.symbol[2] || ""; + if (this.modifiers) { + if (this.modifiers.add9) supStr += "(add9)"; + if (this.modifiers.add11) supStr += "(add11)"; + if (this.modifiers.add13) supStr += "(add13)"; + if (this.modifiers.no3) supStr += "(no3)"; + if (this.modifiers.no5) supStr += "(no5)"; + } + return supStr; + } + romanSub(key) { + let subStr = ""; + if (this.modifiers) { + if (this.modifiers.sus2) { + if (this.modifiers.sus4) subStr += "sus24";else subStr += "sus2"; + } else if (this.modifiers.sus4) subStr += "sus4"; + } + return subStr; + } + get pitches() { + const chordData = chordKinds[this.kind]; + if (!chordData) return []; + const rootMidi = _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].mod(this.rootChroma, 12); + const pitches = []; + for (let i = 0; i < chordData.pitches.length; i++) pitches.push(rootMidi + chordData.pitches[i]); + if (this.modifiers.sus2) pitches[1] = rootMidi + 2; + if (this.modifiers.sus4) { + if (this.modifiers.sus2) pitches.splice(2, 0, rootMidi + 5);else pitches[1] = rootMidi + 5; + } + return pitches; + } + get strummingPitches() { + const rootMidi = _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].mod(this.rootChroma, 12); + let pitches = this.pitches; + if (pitches.length == 0) return []; + let octave = 12 * 4; + if (rootMidi >= 6) octave -= 12; + pitches = pitches.map(p => p + octave); + if (pitches.length <= 3) pitches.push(pitches[0] + 12); + pitches = pitches.sort((x, y) => x - y); + let sum = pitches.reduce((x, y) => x + y) / pitches.length; + while (sum < 60) { + const x = pitches.shift(); + pitches.push(x + 12); + sum += 12 / pitches.length; + } + if (pitches.length >= 4) { + pitches[0] += 12; + pitches[3] -= 12; + } + pitches.unshift(octave + rootMidi); + return pitches; + } +} + +/***/ }), + +/***/ "./src/theory/index.ts": +/*!*****************************!*\ + !*** ./src/theory/index.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Chord: () => (/* reexport safe */ _chord_ts__WEBPACK_IMPORTED_MODULE_5__["default"]), +/* harmony export */ Key: () => (/* reexport safe */ _key_ts__WEBPACK_IMPORTED_MODULE_3__["default"]), +/* harmony export */ Meter: () => (/* reexport safe */ _meter_ts__WEBPACK_IMPORTED_MODULE_4__["default"]), +/* harmony export */ Pitch: () => (/* reexport safe */ _pitch_ts__WEBPACK_IMPORTED_MODULE_0__["default"]), +/* harmony export */ PitchName: () => (/* reexport safe */ _pitchName_ts__WEBPACK_IMPORTED_MODULE_1__["default"]), +/* harmony export */ Scale: () => (/* reexport safe */ _scale_ts__WEBPACK_IMPORTED_MODULE_2__["default"]), +/* harmony export */ Utils: () => (/* reexport safe */ _utils_ts__WEBPACK_IMPORTED_MODULE_6__["default"]) +/* harmony export */ }); +/* harmony import */ var _pitch_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitch.ts */ "./src/theory/pitch.ts"); +/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); +/* harmony import */ var _scale_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./scale.ts */ "./src/theory/scale.ts"); +/* harmony import */ var _key_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./key.ts */ "./src/theory/key.ts"); +/* harmony import */ var _meter_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./meter.ts */ "./src/theory/meter.ts"); +/* harmony import */ var _chord_ts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./chord.ts */ "./src/theory/chord.ts"); +/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); + + + + + + + + +/***/ }), + +/***/ "./src/theory/key.ts": +/*!***************************!*\ + !*** ./src/theory/key.ts ***! + \***************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Key) +/* harmony export */ }); +/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); +/* harmony import */ var _pitch_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pitch.ts */ "./src/theory/pitch.ts"); +/* harmony import */ var _scale_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./scale.ts */ "./src/theory/scale.ts"); +/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); + + + + +class Key { + constructor(tonic, scale) { + this.tonic = tonic; + this.scale = scale; + this._chromaToDegree = []; + for (let degree = 0; degree < this.scale.chromas.length; degree++) { + let chroma = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.tonic.midi + this.scale.chromas[degree], 12); + this._chromaToDegree[chroma] = degree; + const nextDegree = (degree + 1) % this.scale.chromas.length; + let nextChroma = chroma + 1; + while (true) { + let testNextChroma = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.tonic.midi + this.scale.chromas[nextDegree], 12); + while (testNextChroma < chroma) testNextChroma += 12; + if (nextChroma >= testNextChroma) break; + this._chromaToDegree[nextChroma % 12] = (degree + 0.5) % this.scale.chromas.length; + nextChroma += 1; + } + } + } + static fromTonicAndScale(tonic, scale) { + return new Key(tonic, scale); + } + static parse(str) { + str = str.toLowerCase().trim(); + const separator = str.indexOf(" "); + if (separator < 1) throw "invalid key string"; + const tonicStr = str.substr(0, separator); + const scaleStr = str.substr(separator); + const tonic = _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].parse(tonicStr); + const scale = _scale_ts__WEBPACK_IMPORTED_MODULE_2__["default"].parse(scaleStr); + return new Key(tonic, scale); + } + get str() { + const scaleStr = this.scale.name || "Unknown Scale"; + const tonicStr = this.tonic.str; + return tonicStr + " " + scaleStr; + } + toString() { + return this.str; + } + degreeForChroma(chroma) { + return _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this._chromaToDegree[chroma], this.scale.chromas.length); + } + degreeForMidi(midi) { + return this.degreeForChroma(_utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi, 12)); + } + degreeForPitch(pitch) { + return this.degreeForMidi(pitch.midi); + } + octavedDegreeForMidi(midi) { + const degree = this.degreeForMidi(midi); + const degreeOctave = Math.floor((midi - this.tonic.midi) / 12); + return degree + this.scale.chromas.length * degreeOctave; + } + octavedDegreeForPitch(pitch) { + return this.octavedDegreeForMidi(pitch.midi); + } + midiForDegree(octavedDegree) { + const degree = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(octavedDegree, this.scale.chromas.length); + const degreeOctave = Math.floor(octavedDegree / this.scale.chromas.length); + return this.tonic.midi + this.scale.chromas[degree] + degreeOctave * 12; + } + pitchForDegree(octavedDegree) { + return _pitch_ts__WEBPACK_IMPORTED_MODULE_1__["default"].fromMidi(this.midiForDegree(octavedDegree)); + } + chromaForDegree(octavedDegree) { + return _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.midiForDegree(octavedDegree), 12); + } + nameForMidi(midi) { + const degree = this.degreeForMidi(midi); + const letter1 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.tonic.letter + Math.floor(degree), 7); + const accidental1 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi - _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].letterToChroma(letter1) + 6, 12) - 6; + if (degree == Math.floor(degree)) return new _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"](letter1, accidental1); + const letter2 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(letter1 + 1, 7); + const accidental2 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi - _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].letterToChroma(letter2) + 6, 12) - 6; + const letter3 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(letter1 - 1, 7); + const accidental3 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi - _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].letterToChroma(letter3) + 6, 12) - 6; + const attempts = [[letter1, accidental1], [letter2, accidental2], [letter3, accidental3]]; + attempts.sort((a, b) => Math.abs(a[1]) - Math.abs(b[1])); + return new _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"](attempts[0][0], attempts[0][1]); + } + nameForPitch(pitch) { + return this.nameForMidi(pitch.midi); + } + nameForChroma(chroma) { + return this.nameForMidi(chroma); + } + nameForDegree(degree) { + return this.nameForMidi(this.midiForDegree(degree)); + } + get midi() { + return this.scale.chromas.map(chroma => chroma + this.tonic.midi); + } + get chroma() { + return this.scale.chromas.map(chroma => _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(chroma + this.tonic.midi, 12)); + } + get namedPitches() { + return this.scale.chromas.map(chroma => this.nameForMidi(chroma + this.tonic.midi)); + } +} + +/***/ }), + +/***/ "./src/theory/meter.ts": +/*!*****************************!*\ + !*** ./src/theory/meter.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Meter) +/* harmony export */ }); +/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); + +class Meter { + constructor(numerator, denominator) { + this.numerator = numerator; + this.denominator = denominator; + } + withChanges(obj) { + return Object.assign(new Meter(this.numerator, this.denominator), obj); + } + *iterMeasuresPairwise(time = null) { + time = time || new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0); + while (true) { + const nextTime = time.add(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](this.numerator, this.denominator)); + yield [this.numerator, this.denominator, time, nextTime]; + time = nextTime; + } + } + get fullCycleDuration() { + return new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](this.numerator, this.denominator); + } + get alternatingMeasureCount() { + return 1; + } + get str() { + return this.numerator + " / " + this.denominator; + } + static parse(src) { + const split = src.split("/"); + if (split.length != 2) throw "invalid meter syntax"; + const numerator = parseInt(split[0].trim()); + const denominator = parseInt(split[1].trim()); + if (!isFinite(numerator) || !isFinite(denominator)) throw "invalid meter syntax"; + return new Meter(numerator, denominator); + } +} + +/***/ }), + +/***/ "./src/theory/pitch.ts": +/*!*****************************!*\ + !*** ./src/theory/pitch.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Pitch) +/* harmony export */ }); +/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); +/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); + + +class Pitch { + constructor(midi) { + this.midi = midi; + } + static fromMidi(midi) { + return new Pitch(midi); + } + static fromOctaveAndChroma(octave, chroma) { + return Pitch.fromMidi(12 * octave + chroma); + } + static fromOctaveAndName(octave, pitchName) { + return Pitch.fromMidi(12 * octave + pitchName.midi); + } + static parse(str) { + const pitchName = _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].parse(str); + str = str.toLowerCase().trim(); + + // Determine octave + let octave = 0; + for (let i = 1; i < str.length; i++) { + const c = str.charCodeAt(i); + if (c == "-".charCodeAt(0) || c >= "0".charCodeAt(0) && c <= "9".charCodeAt(0)) { + octave = parseInt(str.substr(i)); + break; + } + } + if (octave === undefined || octave === null || isNaN(octave) || !isFinite(octave)) throw "invalid pitch string"; + return Pitch.fromOctaveAndName(octave, pitchName); + } + get frequency() { + return Math.pow(2, (this.midi - 69) / 12) * 440; + } + get octave() { + return Math.floor(this.midi / 12); + } + get chroma() { + return _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].mod(this.midi, 12); + } + get name() { + return _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromMidi(this.midi); + } + get str() { + return this.name.str + this.octave.toString(); + } + toString() { + return this.str; + } +} + +/***/ }), + +/***/ "./src/theory/pitchName.ts": +/*!*********************************!*\ + !*** ./src/theory/pitchName.ts ***! + \*********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ PitchName) +/* harmony export */ }); +/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); + +class PitchName { + constructor(letter, accidental) { + this.letter = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].mod(letter, 7); + this.accidental = accidental; + } + static fromMidi(midi) { + const chroma = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].mod(midi, 12); + const letter = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].chromaToLetter(chroma); + const accidental = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].chromaToAccidental(chroma); + return new PitchName(letter, accidental); + } + static fromChroma(chroma) { + return PitchName.fromMidi(chroma); + } + static parse(str) { + if (str.length < 1) throw "invalid pitch string"; + str = str.toLowerCase().trim(); + + // Determine letter + const letterStr = str[0]; + const letter = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].strToLetter(letterStr); + if (letter === undefined) throw "invalid pitch string"; + + // Determine accidental + let accidental = 0; + for (let i = 1; i < str.length; i++) { + const c = str.charCodeAt(i); + if (c == "b".charCodeAt(0) || c == "♭".charCodeAt(0)) accidental -= 1;else if (c == "#".charCodeAt(0) || c == "♯".charCodeAt(0)) accidental += 1; + } + return new PitchName(letter, accidental); + } + get midi() { + return _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].letterToChroma(this.letter) + this.accidental; + } + get chroma() { + return _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].mod(this.midi, 12); + } + altered(additionalAccidental) { + return new PitchName(this.letter, this.accidental + additionalAccidental); + } + get simplified() { + if (this.accidental === 0) return this;else return PitchName.fromMidi(this.midi); + } + get str() { + const letterStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].letterToStr(this.letter); + const accidentalStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].accidentalToStr(this.accidental); + return letterStr + accidentalStr; + } + get strUnicode() { + const letterStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].letterToStr(this.letter); + const accidentalStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].accidentalToStr(this.accidental, true); + return letterStr + accidentalStr; + } + toString() { + return this.str; + } +} + +/***/ }), + +/***/ "./src/theory/scale.ts": +/*!*****************************!*\ + !*** ./src/theory/scale.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Scale), +/* harmony export */ knownScales: () => (/* binding */ knownScales) +/* harmony export */ }); +/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); + +const knownScales = [{ + chromas: [0, 2, 4, 5, 7, 9, 11], + mode: 0, + id: "maj", + names: ["Major", "Ionian"] +}, { + chromas: [0, 2, 3, 5, 7, 9, 10], + mode: 1, + id: "dor", + names: ["Dorian"] +}, { + chromas: [0, 1, 3, 5, 7, 8, 10], + mode: 2, + id: "phr", + names: ["Phrygian"] +}, { + chromas: [0, 2, 4, 6, 7, 9, 11], + mode: 3, + id: "lyd", + names: ["Lydian"] +}, { + chromas: [0, 2, 4, 5, 7, 9, 10], + mode: 4, + id: "mix", + names: ["Mixolydian"] +}, { + chromas: [0, 2, 3, 5, 7, 8, 10], + mode: 5, + id: "min", + names: ["Natural Minor", "Minor", "Aeolian"] +}, { + chromas: [0, 1, 3, 5, 6, 8, 10], + mode: 6, + id: "loc", + names: ["Locrian"] +}, { + chromas: [0, 1, 4, 5, 7, 8, 11], + mode: 0, + id: "dharmaj", + names: ["Double Harmonic Major"] +}]; +class Scale { + static list = knownScales; + constructor(chromas) { + if (chromas.length <= 1 || chromas.length > 12) throw "invalid scale length"; + this.chromas = chromas; + this.metadata = knownScales.find(s => s.chromas.length == this.chromas.length && s.chromas.every((p, index) => p == this.chromas[index])); + } + static fromChromas(chromas) { + return new Scale(chromas); + } + static fromId(id) { + return new Scale(knownScales.find(s => s.id === id).chromas); + } + static parse(str) { + str = str.toLowerCase().trim(); + const knownScale = knownScales.find(s => s.names.some(n => n.toLowerCase() == str)); + if (!knownScale) throw "no known scale with given name"; + return new Scale(knownScale.chromas); + } + get id() { + if (!this.metadata) return null; + return this.metadata.id; + } + get name() { + if (!this.metadata) return null; + return this.metadata.names[0]; + } + get alterationsFromMajor() { + if (this.chromas.length != 7) throw "not a seven-note scale"; + return this.chromas.map((pitch, i) => pitch - knownScales[0].chromas[i]); + } + get str() { + return this.name || "[" + this.chromas.map(chroma => _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromChroma(chroma).str).join(", ") + "]"; + } + toString() { + return this.str; + } +} + +/***/ }), + +/***/ "./src/theory/utils.ts": +/*!*****************************!*\ + !*** ./src/theory/utils.ts ***! + \*****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Utils) +/* harmony export */ }); +class Utils { + static mod(x, m) { + return (x % m + m) % m; + } + static midiMiddleC = 60; + static chromaToLetter = chroma => [0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][chroma]; + static chromaToAccidental = chroma => [0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0][chroma]; + static chromaToDegreeInCMajor = chroma => [0, 0.5, 1, 1.5, 2, 3, 3.5, 4, 4.5, 5, 5.5, 6][chroma]; + static letterToChroma = letter => [0, 2, 4, 5, 7, 9, 11][letter]; + static letterToStr = letter => ["C", "D", "E", "F", "G", "A", "B"][letter]; + static strToLetter = str => { + const map = { + c: 0, + d: 1, + e: 2, + f: 3, + g: 4, + a: 5, + b: 6 + }; + return map[str]; + }; + static degreeToRomanStr = degree => ["I", "II", "III", "IV", "V", "VI", "VII"][degree]; + static degreeToColor = degree => ["#f00", "#f80", "#fd0", "#0d0", "#00f", "#80f", "#f0f"][degree]; + static degreeToColorFaded = degree => ["#400", "#420", "#430", "#030", "#004", "#204", "#404"][degree]; + static accidentalToStr(accidental, useUnicode = false) { + if (accidental < 0) return (useUnicode ? "\u{266d}" : "b").repeat(-accidental);else return (useUnicode ? "\u{266f}" : "#").repeat(accidental); + } +} + +/***/ }), + +/***/ "./src/timeline/Element.tsx": +/*!**********************************!*\ + !*** ./src/timeline/Element.tsx ***! + \**********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Element: () => (/* binding */ Element) +/* harmony export */ }); +/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/web/dist/dev.js"); +/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); +/* harmony import */ var _state_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../state.ts */ "./src/state.ts"); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); + + +var _tmpl$ = /*#__PURE__*/(0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.template)(`
`); + + + + +function Element(props) { + let div = undefined; + let canvas = undefined; + solid_js__WEBPACK_IMPORTED_MODULE_4__.createEffect(() => { + if (!div || !canvas) return; + const cleanup = registerHandlers(div, canvas); + solid_js__WEBPACK_IMPORTED_MODULE_4__.onCleanup(cleanup); + }); + return (() => { + var _el$ = _tmpl$(), + _el$2 = _el$.firstChild; + var _ref$ = div; + typeof _ref$ === "function" ? (0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.use)(_ref$, _el$) : div = _el$; + _el$.style.setProperty("width", "100%"); + _el$.style.setProperty("height", "100%"); + var _ref$2 = canvas; + typeof _ref$2 === "function" ? (0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.use)(_ref$2, _el$2) : canvas = _el$2; + return _el$; + })(); +} +function canvasResize(div, canvas, timeline) { + const pixelRatio = window.devicePixelRatio || 1; + const domRect = div.getBoundingClientRect(); + const x = Math.floor(domRect.x); + const y = Math.floor(domRect.y); + const w = Math.floor(domRect.width * pixelRatio); + const h = Math.floor(domRect.height * pixelRatio); + canvas.style.width = domRect.width + "px"; + canvas.style.height = domRect.height + "px"; + canvas.width = w; + canvas.height = h; + const rect = new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0, 0, w, h); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.resize(timeline, pixelRatio, rect); +} +function registerHandlers(div, canvas) { + const ctx = canvas.getContext("2d"); + const transformMousePos = (canvas, ev) => { + const rect = canvas.getBoundingClientRect(); + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + return { + x: (ev.clientX - rect.left) * timeline.pixelRatio, + y: (ev.clientY - rect.top) * timeline.pixelRatio + }; + }; + const setCursor = () => { + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + const action = timeline.mouse.down ? timeline.mouse.action : timeline.hover?.action; + canvas.style.cursor = action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.DragTime || action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.DragRow || action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.DragTimeAndRow ? timeline.mouse.down ? "grabbing" : "grab" : action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.StretchTimeStart || action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.StretchTimeEnd ? "col-resize" : "inherit"; + }; + const onResize = () => { + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; + canvasResize(div, canvas, timeline); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.layout(timeline, project.root); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); + }; + const onMouseMove = ev => { + ev.preventDefault(); + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; + const mouse = transformMousePos(canvas, ev); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseMove(timeline, project.root, mouse.x, mouse.y); + if (_index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseDrag(timeline, project)) _index_ts__WEBPACK_IMPORTED_MODULE_2__.layout(timeline, project.root); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); + setCursor(); + }; + const onMouseDown = ev => { + ev.preventDefault(); + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; + const prefs = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().prefs; + const mouse = transformMousePos(canvas, ev); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseMove(timeline, project.root, mouse.x, mouse.y); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseDown(timeline, project.root, prefs, ev.button !== 0); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); + setCursor(); + }; + const onMouseUp = ev => { + ev.preventDefault(); + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; + const mouse = transformMousePos(canvas, ev); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseMove(timeline, project.root, mouse.x, mouse.y); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseUp(timeline, project.root, ev.button !== 0); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); + setCursor(); + }; + const onMouseWheel = ev => { + ev.preventDefault(); + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; + _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseWheel(timeline, ev.deltaX, ev.deltaY); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.layout(timeline, project.root); + _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); + }; + const onKeyDown = ev => { + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + _index_ts__WEBPACK_IMPORTED_MODULE_2__.keyDown(timeline, ev.key.toLowerCase()); + }; + const onKeyUp = ev => { + const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; + _index_ts__WEBPACK_IMPORTED_MODULE_2__.keyUp(timeline, ev.key.toLowerCase()); + }; + const preventDefault = ev => { + ev.preventDefault(); + }; + onResize(); + canvas.addEventListener("resize", onResize); + window.addEventListener("mousemove", onMouseMove); + canvas.addEventListener("mousedown", onMouseDown); + window.addEventListener("mouseup", onMouseUp); + canvas.addEventListener("wheel", onMouseWheel); + canvas.addEventListener("contextmenu", preventDefault); + window.addEventListener("keydown", onKeyDown); + window.addEventListener("keyup", onKeyUp); + return () => { + canvas.removeEventListener("resize", onResize); + window.removeEventListener("mousemove", onMouseMove); + canvas.removeEventListener("mousedown", onMouseDown); + window.removeEventListener("mouseup", onMouseUp); + canvas.removeEventListener("wheel", onMouseWheel); + canvas.removeEventListener("contextmenu", preventDefault); + window.removeEventListener("keydown", onKeyDown); + window.removeEventListener("keyup", onKeyUp); + }; +} + +/***/ }), + +/***/ "./src/timeline/draw.ts": +/*!******************************!*\ + !*** ./src/timeline/draw.ts ***! + \******************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ draw: () => (/* binding */ draw), +/* harmony export */ drawLaneBkgCenterStroke: () => (/* binding */ drawLaneBkgCenterStroke), +/* harmony export */ drawLaneBkgMeasures: () => (/* binding */ drawLaneBkgMeasures), +/* harmony export */ drawLaneBkgOctaves: () => (/* binding */ drawLaneBkgOctaves), +/* harmony export */ drawLaneBkgSolid: () => (/* binding */ drawLaneBkgSolid), +/* harmony export */ drawLaneFrgOutline: () => (/* binding */ drawLaneFrgOutline) +/* harmony export */ }); +/* harmony import */ var _state_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../state.ts */ "./src/state.ts"); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _theory__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../theory */ "./src/theory/index.ts"); +/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); + + + + +function draw(timeline, ctx) { + ctx.save(); + ctx.translate(0.5, 0.5); + ctx.fillStyle = "#fff"; + ctx.fillRect(0, 0, timeline.renderRect.w, timeline.renderRect.h); + drawElements(timeline, ctx, timeline.layout.elements); + if (timeline.cursor.visible) { + const timeMin = timeline.cursor.time1.min(timeline.cursor.time2); + const timeMax = timeline.cursor.time1.max(timeline.cursor.time2); + drawCursorBeam(timeline, ctx, timeMin, false); + drawCursorBeam(timeline, ctx, timeMax, true); + } + ctx.restore(); +} +function drawElements(timeline, ctx, elements) { + for (const element of elements) { + if (element.kind === "lane") { + ctx.save(); + ctx.beginPath(); + ctx.rect(element.rect.x, element.rect.y, element.rect.w, element.rect.h); + ctx.clip(); + drawLaneBkgSolid(timeline, ctx, element); + drawLaneBkgMeasures(timeline, ctx, element, false); + drawLaneBkgMeasures(timeline, ctx, element, true); + drawCursorBkg(timeline, ctx, element); + if (element.subElements) drawElements(timeline, ctx, element.subElements); + drawLaneFrgOutline(timeline, ctx, element); + ctx.restore(); + } + if (element.kind === "laneNotes") { + ctx.save(); + ctx.beginPath(); + ctx.rect(element.rect.x, element.rect.y, element.rect.w, element.rect.h); + ctx.clip(); + drawLaneBkgSolid(timeline, ctx, element); + drawLaneBkgOctaves(timeline, ctx, element, false); + drawLaneBkgMeasures(timeline, ctx, element, false); + drawLaneBkgOctaves(timeline, ctx, element, true); + drawLaneBkgMeasures(timeline, ctx, element, true); + drawCursorBkg(timeline, ctx, element); + if (element.subElements) drawElements(timeline, ctx, element.subElements); + drawLaneFrgOutline(timeline, ctx, element); + ctx.restore(); + } + if (element.kind === "note") { + ctx.fillStyle = timeline.hover?.id === element.id ? "#f88" : "#f00"; + ctx.beginPath(); + ctx.roundRect(element.rect.x, element.rect.y, element.rect.w, element.rect.h, timeline.noteRowH / 4); + ctx.fill(); + if (element.id !== undefined && timeline.selection.has(element.id)) { + ctx.strokeStyle = "#fbb"; + ctx.lineWidth = 4; + ctx.stroke(); + } + } + } +} +function drawLaneBkgCenterStroke(timeline, ctx, lane) { + const yCenter = Math.floor(lane.rect.y + lane.rect.h / 2) + 0.5; + ctx.strokeStyle = "#fff"; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.moveTo(lane.rect.x, yCenter); + ctx.lineTo(lane.rect.x + lane.rect.w, yCenter); + ctx.stroke(); +} +function drawLaneBkgSolid(timeline, ctx, lane) { + ctx.fillStyle = "#eee"; + ctx.fillRect(lane.rect.x, lane.rect.y, lane.rect.w, lane.rect.h); +} +function drawLaneFrgOutline(timeline, ctx, lane) { + ctx.strokeStyle = "#000"; + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.moveTo(lane.rect.x, lane.rect.y); + ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y); + ctx.moveTo(lane.rect.x, lane.rect.y + lane.rect.h); + ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y + lane.rect.h); + ctx.stroke(); +} +function drawLaneBkgMeasures(timeline, ctx, lane, mainLinePass) { + // Render alternating measure background and sub-measure dividers. + const measureHalfH = lane.rect.h / 2; + const submeasureHalfH = lane.rect.h / 2; + for (const measure of timeline.layout.measures) { + const x1 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time1)); + const x2 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time2)); + const submeasureSize = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](1, measure.meterCh.meter.denominator)) - _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0)); + if (mainLinePass) { + ctx.strokeStyle = "#444"; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.moveTo(x1 + 0.5, lane.rect.y); + ctx.lineTo(x1 + 0.5, lane.rect.y + lane.rect.h); + ctx.stroke(); + } + if (!mainLinePass && submeasureSize > 8) { + ctx.strokeStyle = "#fff"; + ctx.lineWidth = 1; + ctx.beginPath(); + for (let n = 1; n < measure.meterCh.meter.numerator; n++) { + const submeasureX = x1 + Math.round(submeasureSize * n); + if (submeasureX >= x2) break; + ctx.moveTo(submeasureX, lane.rect.y); + ctx.lineTo(submeasureX, lane.rect.y + lane.rect.h); + } + ctx.stroke(); + } + } +} +function drawLaneBkgOctaves(timeline, ctx, lane, mainLinePass) { + const rowAtTop = _index_ts__WEBPACK_IMPORTED_MODULE_1__.rowAtY(timeline, lane, lane.rect.y); + const rowAtBottom = _index_ts__WEBPACK_IMPORTED_MODULE_1__.rowAtY(timeline, lane, lane.rect.y + lane.rect.h); + const octaveAtTop = Math.ceil(rowAtTop / 7) + 1; + const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1; + ctx.fillStyle = "#444"; + ctx.font = Math.floor(timeline.noteRowH - 4) + "px system-ui"; + ctx.textAlign = "left"; + ctx.textBaseline = "bottom"; + for (const keyRegion of timeline.layout.keyRegions) { + const tonicRowOffset = _theory__WEBPACK_IMPORTED_MODULE_2__.Utils.chromaToDegreeInCMajor(keyRegion.keyCh1.key.tonic.chroma); + let needsOctaveLabels = true; + let drewOctaveLabels = false; + for (const measure of timeline.layout.measures) { + /*if (measure.time1.lessThan(keyRegion.keyCh1.range.start) || + measure.time2.greaterThan(keyRegion.keyCh2.range.start)) + continue*/ + + const x1 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time1)); + const x2 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time2)); + for (let i = octaveAtBottom; i <= octaveAtTop; i++) { + const y = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.yForRow(timeline, lane, tonicRowOffset + i * 7) + timeline.noteRowH); + if (mainLinePass) { + const labelX = Math.max(x1 + 5, 5); + if (needsOctaveLabels && labelX + 30 < x2) { + ctx.fillText(keyRegion.keyCh1.key.tonic.str + (i + 5).toString(), labelX, y - 1); + drewOctaveLabels = true; + } + ctx.strokeStyle = "#444"; + ctx.beginPath(); + ctx.moveTo(x1, y); + ctx.lineTo(x2, y); + ctx.moveTo(x1, y + 1); + ctx.lineTo(x2, y + 1); + ctx.stroke(); + } + if (!mainLinePass) { + ctx.strokeStyle = "#fff"; + ctx.beginPath(); + for (let j = 1; j < 7; j += 1) { + const ySuboctave = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.yForRow(timeline, lane, tonicRowOffset + i * 7 + j) + timeline.noteRowH); + ctx.moveTo(x1, ySuboctave); + ctx.lineTo(x2, ySuboctave); + } + ctx.stroke(); + } + } + if (drewOctaveLabels) needsOctaveLabels = false; + } + } +} +function drawCursorBeam(timeline, ctx, time, tipOffsetSide) { + const prefs = _state_ts__WEBPACK_IMPORTED_MODULE_0__.get().prefs; + const laneIndexMin = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMin(timeline); + const laneIndexMax = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMax(timeline); + const laneMin = timeline.layout.lanes[laneIndexMin]; + const laneMax = timeline.layout.lanes[laneIndexMax]; + const x = 0.5 + Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, time)); + ctx.strokeStyle = prefs.timeline.selectionCursorColor; + ctx.fillStyle = prefs.timeline.selectionCursorColor; + ctx.lineCap = "square"; + ctx.lineWidth = 2; + const headYSize = 10; + const headXSize = headYSize * (tipOffsetSide ? -1 : 1); + const y1 = Math.floor(laneMin.rect.y); + const y2 = Math.floor(laneMax.rect.y2); + ctx.beginPath(); + ctx.moveTo(x, y1 + headYSize); + ctx.lineTo(x + headXSize, y1); + ctx.lineTo(x, y1); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(x, y2 - headYSize); + ctx.lineTo(x + headXSize, y2); + ctx.lineTo(x, y2); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(x, y1 + 1); + ctx.lineTo(x, y2 - 1); + ctx.stroke(); +} +function drawCursorBkg(timeline, ctx, lane) { + if (!timeline.cursor.visible) return; + const prefs = _state_ts__WEBPACK_IMPORTED_MODULE_0__.get().prefs; + const timeMin = timeline.cursor.time1.min(timeline.cursor.time2); + const timeMax = timeline.cursor.time1.max(timeline.cursor.time2); + const laneIndexMin = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMin(timeline); + const laneIndexMax = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMax(timeline); + if (laneIndexMin > lane.laneIndex || laneIndexMax < lane.laneIndex) return; + const y1 = Math.floor(lane.rect.y); + const y2 = Math.floor(lane.rect.y2); + const x1 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, timeMin); + const x2 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, timeMax); + ctx.fillStyle = prefs.timeline.selectionBkgColor; + ctx.fillRect(x1, y1, x2 - x1, y2 - y1); +} + +/***/ }), + +/***/ "./src/timeline/index.ts": +/*!*******************************!*\ + !*** ./src/timeline/index.ts ***! + \*******************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Element: () => (/* reexport safe */ _Element_tsx__WEBPACK_IMPORTED_MODULE_0__.Element), +/* harmony export */ Layout: () => (/* reexport safe */ _layout_ts__WEBPACK_IMPORTED_MODULE_2__.Layout), +/* harmony export */ MouseAction: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction), +/* harmony export */ cursorGetLaneIndexMax: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMax), +/* harmony export */ cursorGetLaneIndexMin: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMin), +/* harmony export */ cursorSetTime: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorSetTime), +/* harmony export */ cursorSetTrack: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorSetTrack), +/* harmony export */ draw: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.draw), +/* harmony export */ drawLaneBkgCenterStroke: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgCenterStroke), +/* harmony export */ drawLaneBkgMeasures: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgMeasures), +/* harmony export */ drawLaneBkgOctaves: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgOctaves), +/* harmony export */ drawLaneBkgSolid: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgSolid), +/* harmony export */ drawLaneFrgOutline: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneFrgOutline), +/* harmony export */ keyDown: () => (/* reexport safe */ _key_down_ts__WEBPACK_IMPORTED_MODULE_9__.keyDown), +/* harmony export */ keyUp: () => (/* reexport safe */ _key_up_ts__WEBPACK_IMPORTED_MODULE_10__.keyUp), +/* harmony export */ laneIndexAtY: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.laneIndexAtY), +/* harmony export */ layout: () => (/* reexport safe */ _layout_ts__WEBPACK_IMPORTED_MODULE_2__.layout), +/* harmony export */ layoutLaneNotes: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.layoutLaneNotes), +/* harmony export */ makeNew: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.makeNew), +/* harmony export */ mouseDown: () => (/* reexport safe */ _mouse_down_ts__WEBPACK_IMPORTED_MODULE_5__.mouseDown), +/* harmony export */ mouseDrag: () => (/* reexport safe */ _mouse_drag_ts__WEBPACK_IMPORTED_MODULE_6__.mouseDrag), +/* harmony export */ mouseMove: () => (/* reexport safe */ _mouse_move_ts__WEBPACK_IMPORTED_MODULE_4__.mouseMove), +/* harmony export */ mouseUp: () => (/* reexport safe */ _mouse_up_ts__WEBPACK_IMPORTED_MODULE_7__.mouseUp), +/* harmony export */ mouseWheel: () => (/* reexport safe */ _mouse_wheel_ts__WEBPACK_IMPORTED_MODULE_8__.mouseWheel), +/* harmony export */ pitchForRow: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.pitchForRow), +/* harmony export */ pointAt: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.pointAt), +/* harmony export */ resize: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.resize), +/* harmony export */ rowAtY: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.rowAtY), +/* harmony export */ rowForPitch: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.rowForPitch), +/* harmony export */ selectionAdd: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionAdd), +/* harmony export */ selectionAddAtCursor: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionAddAtCursor), +/* harmony export */ selectionClear: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionClear), +/* harmony export */ selectionRange: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionRange), +/* harmony export */ selectionToggle: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionToggle), +/* harmony export */ timeAtX: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.timeAtX), +/* harmony export */ timeRangeAtX: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.timeRangeAtX), +/* harmony export */ visibleTimeRange: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.visibleTimeRange), +/* harmony export */ xAtTime: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime), +/* harmony export */ yForRow: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.yForRow) +/* harmony export */ }); +/* harmony import */ var _Element_tsx__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Element.tsx */ "./src/timeline/Element.tsx"); +/* harmony import */ var _timeline_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./timeline.ts */ "./src/timeline/timeline.ts"); +/* harmony import */ var _layout_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./layout.ts */ "./src/timeline/layout.ts"); +/* harmony import */ var _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./layout_notes.ts */ "./src/timeline/layout_notes.ts"); +/* harmony import */ var _mouse_move_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./mouse_move.ts */ "./src/timeline/mouse_move.ts"); +/* harmony import */ var _mouse_down_ts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mouse_down.ts */ "./src/timeline/mouse_down.ts"); +/* harmony import */ var _mouse_drag_ts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./mouse_drag.ts */ "./src/timeline/mouse_drag.ts"); +/* harmony import */ var _mouse_up_ts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./mouse_up.ts */ "./src/timeline/mouse_up.ts"); +/* harmony import */ var _mouse_wheel_ts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./mouse_wheel.ts */ "./src/timeline/mouse_wheel.ts"); +/* harmony import */ var _key_down_ts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./key_down.ts */ "./src/timeline/key_down.ts"); +/* harmony import */ var _key_up_ts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./key_up.ts */ "./src/timeline/key_up.ts"); +/* harmony import */ var _draw_ts__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./draw.ts */ "./src/timeline/draw.ts"); + + + + + + + + + + + + + +/***/ }), + +/***/ "./src/timeline/key_down.ts": +/*!**********************************!*\ + !*** ./src/timeline/key_down.ts ***! + \**********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ keyDown: () => (/* binding */ keyDown) +/* harmony export */ }); +function keyDown(timeline, key) { + timeline.keysDown.add(key); +} + +/***/ }), + +/***/ "./src/timeline/key_up.ts": +/*!********************************!*\ + !*** ./src/timeline/key_up.ts ***! + \********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ keyUp: () => (/* binding */ keyUp) +/* harmony export */ }); +function keyUp(timeline, key) { + timeline.keysDown.delete(key); +} + +/***/ }), + +/***/ "./src/timeline/layout.ts": +/*!********************************!*\ + !*** ./src/timeline/layout.ts ***! + \********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Layout: () => (/* binding */ Layout), +/* harmony export */ layout: () => (/* binding */ layout) +/* harmony export */ }); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../project */ "./src/project/index.ts"); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); + + + +class Layout { + lanes = []; + elements = []; + elementCount = 0; + measures = []; + keyRegions = []; + constructor() {} + add(parent, elem) { + this.elementCount++; + if (parent !== undefined) { + if (parent.subElements === undefined) parent.subElements = []; + parent.subElements.push(elem); + } else { + this.elements.push(elem); + if (elem.kind === "lane" || elem.kind === "laneNotes") this.lanes.push(elem); + } + } +} +function layout(timeline, project) { + const layout = new Layout(); + layout.range = _index_ts__WEBPACK_IMPORTED_MODULE_1__.visibleTimeRange(timeline); + layout.measures = [..._project__WEBPACK_IMPORTED_MODULE_0__.iterMeasuresAtRange(project, layout.range)]; + layout.keyRegions = [...iterKeyChangePairsAtRange(timeline, project, layout.range)]; + const laneMarkerH = 32; + const laneChordH = 60; + const laneMarginH = 8; + const laneKeyChanges = { + kind: "lane", + laneIndex: 0, + rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, 0, timeline.renderRect.w, laneMarkerH) + }; + const laneMeterChanges = { + kind: "lane", + laneIndex: 1, + rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, laneMarkerH + laneMarginH, timeline.renderRect.w, laneMarkerH) + }; + const laneChords = { + kind: "lane", + laneIndex: 2, + rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, laneMarkerH + laneMarginH + laneMarkerH + laneMarginH, timeline.renderRect.w, laneChordH) + }; + const laneNotesY = laneMarkerH + laneMarginH + laneMarkerH + laneMarginH + laneChordH + laneMarginH; + const laneNotes = { + kind: "laneNotes", + laneIndex: 3, + rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, laneNotesY, timeline.renderRect.w, timeline.renderRect.h - laneNotesY) + }; + layout.add(undefined, laneKeyChanges); + layout.add(undefined, laneMeterChanges); + layout.add(undefined, laneChords); + layout.add(undefined, laneNotes); + layout.laneNotes = laneNotes; + _index_ts__WEBPACK_IMPORTED_MODULE_1__.layoutLaneNotes(timeline, project, layout, laneNotes); + timeline.layout = layout; + console.log(layout.elementCount, layout); +} +function* iterKeyChangePairsAtRange(timeline, project, range) { + const keyChangeTrackId = _project__WEBPACK_IMPORTED_MODULE_0__.keyChangeTrackId(project); + const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId); + if (!keyChangeTrackTimedElems) return; + const firstKeyCh = keyChangeTrackTimedElems.findFirst(); + const defaultKey = firstKeyCh?.key ?? _project__WEBPACK_IMPORTED_MODULE_0__.defaultKey(); + for (const pair of keyChangeTrackTimedElems.iterActiveAtRangePairwise(range)) { + const keyCh1 = pair[0] ?? _project__WEBPACK_IMPORTED_MODULE_0__.makeKeyChange(-1, range.start, defaultKey); + const keyCh2 = pair[1] ?? _project__WEBPACK_IMPORTED_MODULE_0__.makeKeyChange(-1, range.end, defaultKey); + const x1 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, keyCh1.range.start); + const x2 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, keyCh2.range.start); + yield { + keyCh1, + keyCh2, + x1, + x2 + }; + } +} + +/***/ }), + +/***/ "./src/timeline/layout_notes.ts": +/*!**************************************!*\ + !*** ./src/timeline/layout_notes.ts ***! + \**************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ layoutLaneNotes: () => (/* binding */ layoutLaneNotes), +/* harmony export */ pitchForRow: () => (/* binding */ pitchForRow), +/* harmony export */ rowAtY: () => (/* binding */ rowAtY), +/* harmony export */ rowForPitch: () => (/* binding */ rowForPitch), +/* harmony export */ yForRow: () => (/* binding */ yForRow) +/* harmony export */ }); +/* harmony import */ var _theory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../theory */ "./src/theory/index.ts"); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); +/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); + + + + +function layoutLaneNotes(timeline, project, layout, laneNotes) { + laneNotes.iterElementsAtRegion = (timeline, project, range, verticalRegion) => iterNotesAtRegion(timeline, project, laneNotes, range, verticalRegion); + for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, layout)) { + const key = keyChPair.keyCh1.key; + const row = rowForPitch(note.midiPitch, key); + const [rect, cutStart, cutEnd] = rectForNote(timeline, laneNotes, note.range, row, keyChPair.x1, keyChPair.x2, true); + if (!cutStart) { + const rectStretchStart = rect.withX1(rect.x1 - 8); + layout.add(laneNotes, { + kind: "hidden", + id: note.id, + action: _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeStart, + rect: rectStretchStart + }); + } + if (!cutEnd) { + const rectStretchEnd = rect.withX2(rect.x2 + 8); + layout.add(laneNotes, { + kind: "hidden", + id: note.id, + action: _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeEnd, + rect: rectStretchEnd + }); + } + layout.add(laneNotes, { + kind: "note", + id: note.id, + action: _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow, + rect, + priority: 1 + }); + } +} +function* iterNotesAndKeyChanges(timeline, project, layout) { + for (const keyRegion of layout.keyRegions) { + const time1 = keyRegion.keyCh1.range.start.max(layout.range.start); + const time2 = keyRegion.keyCh2.range.start.min(layout.range.end); + for (const note of iterNotes(timeline, project, new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](time1, time2))) yield [note, keyRegion]; + } +} +function* iterNotes(timeline, project, range) { + const list = project.lists.get(project.noteTrackId); + if (!list) return; + for (const elem of list.iterAtRange(range)) yield elem; +} +function rowForPitch(pitch, key) { + const tonicRowOffset = _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.chromaToDegreeInCMajor(key.tonic.chroma); + return key.octavedDegreeForMidi(pitch - _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.midiMiddleC) + tonicRowOffset; +} +function pitchForRow(row, key) { + const tonicRowOffset = _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.chromaToDegreeInCMajor(key.tonic.chroma); + return key.midiForDegree(row - Math.floor(tonicRowOffset)) + _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.midiMiddleC; +} +function yForRow(timeline, lane, row) { + return lane.rect.y + lane.rect.h / 2 - (row + 1) * timeline.noteRowH - timeline.yScroll; +} +function rowAtY(timeline, lane, y) { + return -Math.floor((y - lane.rect.y + timeline.yScroll - lane.rect.h / 2) / timeline.noteRowH) - 1; +} +function rectForNote(timeline, lane, noteRange, noteRow, keyChXStart, keyChXEnd, clampY) { + const noteOrigX1 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, noteRange.start); + const noteOrigX2 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, noteRange.end); + let noteY = 0.5 + Math.floor(yForRow(timeline, lane, noteRow)); + if (clampY) { + noteY = Math.max(lane.rect.y - timeline.noteRowH / 2, Math.min(lane.rect.y + lane.rect.h - timeline.noteRowH / 2, noteY)); + } + let noteX1 = Math.max(noteOrigX1, keyChXStart); + let noteX2 = Math.min(noteOrigX2, keyChXEnd); + const cutStart = noteOrigX1 < noteX1; + const cutEnd = noteOrigX2 > noteX2; + + //if (!cutStart) noteX1 += 1 + //if (!cutEnd) noteX2 -= 1 + + noteX1 = 0.5 + Math.floor(noteX1); + noteX2 = 0.5 + Math.floor(noteX2); + const noteW = Math.max(2, noteX2 - noteX1); + return [new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](noteX1, noteY, noteW, timeline.noteRowH), cutStart, cutEnd]; +} +function* iterNotesAtRegion(timeline, project, lane, range, verticalRegion) { + for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, timeline.layout)) { + if (!note.range.overlapsRange(range)) continue; + if (verticalRegion !== undefined) { + const [rect] = rectForNote(timeline, lane, note.range, rowForPitch(note.midiPitch, keyChPair.keyCh1.key), keyChPair.x1, keyChPair.x2, false); + if (verticalRegion.y1 > rect.y2 || verticalRegion.y2 < rect.y1) continue; + } + yield note.id; + } +} + +/***/ }), + +/***/ "./src/timeline/mouse_down.ts": +/*!************************************!*\ + !*** ./src/timeline/mouse_down.ts ***! + \************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ mouseDown: () => (/* binding */ mouseDown) +/* harmony export */ }); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); + + +function mouseDown(timeline, project, prefs, rightButton) { + if (timeline.mouse.down) return; + const prevDownDate = timeline.mouse.downDate; + timeline.mouse.down = true; + timeline.mouse.downDate = new Date(); + timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.None; + const selectMultiple = timeline.keysDown.has(prefs.timeline.keySelectMultiple); + const selectRange = timeline.keysDown.has(prefs.timeline.keySelectRange); + const selectClone = timeline.keysDown.has(prefs.timeline.keySelectClone); + const selectRect = timeline.keysDown.has(prefs.timeline.keySelectRect); + const forcePan = timeline.keysDown.has(prefs.timeline.keyPan); + const doubleClick = timeline.mouse.downDate.getTime() - prevDownDate.getTime() < prefs.timeline.mouseDoubleClickThresholdMs; + timeline.drag = { + origin: { + point: { + ...timeline.mouse.point + }, + range: null, + timeScroll: timeline.timeScroll, + yScroll: timeline.yScroll, + project + }, + xLocked: true, + yLocked: true, + posDelta: { + x: 0, + y: 0 + }, + timeDelta: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](0), + rowDelta: 0, + trackDelta: 0, + trackInsertionBefore: -1, + elemId: -1, + notePreviewLast: null + }; + if (rightButton || forcePan) { + timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.Pan; + return; + } + const hoverIsSelected = timeline.hover !== undefined && timeline.hover.id !== undefined && timeline.selection.has(timeline.hover.id); + if (!selectMultiple && !hoverIsSelected) _index_ts__WEBPACK_IMPORTED_MODULE_0__.selectionClear(timeline); + if (timeline.hover === undefined || timeline.hover.action === undefined) { + timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.SelectCursor; + timeline.cursor.visible = true; //!selectRect + _index_ts__WEBPACK_IMPORTED_MODULE_0__.cursorSetTime(timeline, timeline.mouse.point.time, timeline.mouse.point.time); + timeline.cursor.rectY1 = timeline.cursor.rectY2 = timeline.mouse.point.trackPos.y; + timeline.cursor.laneIndex1 = timeline.cursor.laneIndex2 = timeline.mouse.point.laneIndex; + + /*if (doubleClick) + { + const anchor = Timeline.findPreviousAnchor( + timeline, timeline.mouse.point.time, + timeline.mouse.point.trackIndex, timeline.mouse.point.trackIndex) + + Timeline.cursorSetTime(timeline, anchor, anchor) + Timeline.scrollTimeIntoView(timeline, anchor) + }*/ + + return; + } + if (timeline.hover !== undefined) { + timeline.cursor.visible = false; + if (!hoverIsSelected) _index_ts__WEBPACK_IMPORTED_MODULE_0__.selectionToggle(timeline, project, timeline.hover); + timeline.drag.origin.range = _index_ts__WEBPACK_IMPORTED_MODULE_0__.selectionRange(timeline, project); + timeline.mouse.action = timeline.hover.action; + return; + } +} + +/***/ }), + +/***/ "./src/timeline/mouse_drag.ts": +/*!************************************!*\ + !*** ./src/timeline/mouse_drag.ts ***! + \************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ mouseDrag: () => (/* binding */ mouseDrag) +/* harmony export */ }); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../project */ "./src/project/index.ts"); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); + + + +function mouseDrag(timeline, project) { + if (!timeline.mouse.down) return false; + timeline.mouse.pointPrev = timeline.mouse.point; + timeline.mouse.point = _index_ts__WEBPACK_IMPORTED_MODULE_1__.pointAt(timeline, timeline.mouse.point.pos.x, timeline.mouse.point.pos.y); + timeline.drag.posDelta = { + x: timeline.mouse.point.pos.x - timeline.drag.origin.point.pos.x, + y: timeline.mouse.point.pos.y - timeline.drag.origin.point.pos.y + }; + timeline.drag.timeDelta = timeline.mouse.point.time.subtract(timeline.drag.origin.point.time); + timeline.drag.rowDelta = timeline.mouse.point.row - timeline.drag.origin.point.row; + timeline.drag.xLocked = timeline.drag.xLocked && Math.abs(timeline.drag.posDelta.x) < 10; + timeline.drag.yLocked = timeline.drag.yLocked && Math.abs(timeline.drag.posDelta.y) < 10; + if (timeline.mouse.action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.Pan) return handlePanning(timeline, project);else if (timeline.mouse.action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.SelectCursor) return handleSelectCursor(timeline, project);else return handleDragElements(timeline, project); +} +function handlePanning(timeline, project) { + timeline.timeScroll = timeline.drag.origin.timeScroll - timeline.drag.posDelta.x / timeline.timeScale; + timeline.yScroll = timeline.drag.origin.yScroll - timeline.drag.posDelta.y; + return true; +} +function handleSelectCursor(timeline, project) { + timeline.cursor.time2 = timeline.mouse.point.time; + timeline.cursor.laneIndex2 = timeline.mouse.point.laneIndex; + _index_ts__WEBPACK_IMPORTED_MODULE_1__.selectionClear(timeline); + _index_ts__WEBPACK_IMPORTED_MODULE_1__.selectionAddAtCursor(timeline, project.root); + return true; +} +function handleDragElements(timeline, project) { + let action = timeline.mouse.action; + if (timeline.drag.xLocked) { + if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTime || action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeStart || action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeEnd) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.None;else if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragRow; + } + if (timeline.drag.yLocked) { + if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTime;else if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragRow) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.None; + } + const origProject = timeline.drag.origin.project; + let newProject = origProject; + for (const id of timeline.selection) { + const elem = origProject.elems.get(id); + if (!elem) continue; + if (elem.type === "track") continue; + const changes = {}; + if (action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTime || action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) { + changes.range = elem.range.displace(timeline.drag.timeDelta).quantize(_project__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR); + } + if (action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeStart && timeline.drag.origin.range) { + changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange(origProject, elem.parentId, elem.range); + changes.range = changes.range.stretch(timeline.drag.timeDelta, timeline.drag.origin.range.end, timeline.drag.origin.range.start); + if (elem.range.start.compare(timeline.drag.origin.range.start) == 0) changes.range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](changes.range.start.snap(timeline.timeSnap), changes.range.end).quantize(_project__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR); + changes.range = changes.range.sorted(); + changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getRelativeRange(origProject, elem.parentId, changes.range); + } + if (action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeEnd && timeline.drag.origin.range) { + changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange(origProject, elem.parentId, elem.range); + changes.range = changes.range.stretch(timeline.drag.timeDelta, timeline.drag.origin.range.start, timeline.drag.origin.range.end); + if (elem.range.end.compare(timeline.drag.origin.range.end) == 0) changes.range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](changes.range.start, changes.range.end.snap(timeline.timeSnap)).quantize(_project__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR); + changes.range = changes.range.sorted(); + changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getRelativeRange(origProject, elem.parentId, changes.range); + } + if ((action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragRow || action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) && elem.type === "note") { + const note = elem; + const trackId = project.root.noteTrackId; + const key = _project__WEBPACK_IMPORTED_MODULE_0__.keyAt(project.root, trackId, note.range.start); + const degree = key.octavedDegreeForMidi(note.midiPitch); + const newPitch = key.midiForDegree(Math.floor(degree + timeline.drag.rowDelta)); + changes.midiPitch = newPitch; + } + newProject = _project__WEBPACK_IMPORTED_MODULE_0__.upsertElement(newProject, _project__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, changes)); + } + project.root = newProject; + return newProject !== origProject; +} + +/***/ }), + +/***/ "./src/timeline/mouse_move.ts": +/*!************************************!*\ + !*** ./src/timeline/mouse_move.ts ***! + \************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ mouseMove: () => (/* binding */ mouseMove) +/* harmony export */ }); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); + +function mouseMove(timeline, project, x, y) { + timeline.mouse.point = _index_ts__WEBPACK_IMPORTED_MODULE_0__.pointAt(timeline, x, y); + if (!timeline.mouse.down) { + timeline.hover = undefined; + hoverRecursive(timeline, timeline.layout.elements, x, y); + } +} +function hoverRecursive(timeline, elements, x, y) { + for (const elem of elements) { + if (x >= elem.rect.x && x < elem.rect.x + elem.rect.w && y >= elem.rect.y && y < elem.rect.y + elem.rect.h) { + if (timeline.hover === undefined || (elem.priority ?? 0) >= (timeline.hover.priority ?? 0)) timeline.hover = elem; + if (elem.subElements) hoverRecursive(timeline, elem.subElements, x, y); + } + } +} + +/***/ }), + +/***/ "./src/timeline/mouse_up.ts": +/*!**********************************!*\ + !*** ./src/timeline/mouse_up.ts ***! + \**********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ mouseUp: () => (/* binding */ mouseUp) +/* harmony export */ }); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); + +function mouseUp(timeline, project, rightButton) { + if (!timeline.mouse.down) return; + timeline.mouse.down = false; + timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.None; +} + +/***/ }), + +/***/ "./src/timeline/mouse_wheel.ts": +/*!*************************************!*\ + !*** ./src/timeline/mouse_wheel.ts ***! + \*************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ mouseWheel: () => (/* binding */ mouseWheel) +/* harmony export */ }); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); + + +function mouseWheel(timeline, deltaX, deltaY) { + if (Math.abs(deltaX) > 0) { + timeline.timeScroll = timeline.timeScroll + 0.01 / (timeline.timeScale / 100) * deltaX; + timeline.mouse.wheelDate = new Date(); + } else if (new Date().getTime() - timeline.mouse.wheelDate.getTime() > 250) { + const snap = new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](1, 1024); + const prevMouseTime = _index_ts__WEBPACK_IMPORTED_MODULE_0__.timeAtX(timeline, timeline.mouse.point.pos.x, snap); + let newTimeScale = timeline.timeScale * (deltaY > 0 ? 0.8 : 1.25); + newTimeScale = Math.max(4, Math.min(2048, newTimeScale)); + timeline.timeScale = newTimeScale; + const newMouseTime = _index_ts__WEBPACK_IMPORTED_MODULE_0__.timeAtX(timeline, timeline.mouse.point.pos.x, snap); + const newTimeScroll = timeline.timeScroll - newMouseTime.subtract(prevMouseTime).asFloat(); + const timeSnapAdjustThresholdUpper = 24; + const timeSnapAdjustThresholdLower = 8; + let newTimeSnap = timeline.timeSnapBase; + if (newTimeSnap.asFloat() * newTimeScale > timeSnapAdjustThresholdUpper) while (newTimeSnap.asFloat() * newTimeScale > timeSnapAdjustThresholdUpper) newTimeSnap = newTimeSnap.divide(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](2));else if (newTimeSnap.asFloat() * newTimeScale < timeSnapAdjustThresholdLower) while (newTimeSnap.asFloat() * newTimeScale < timeSnapAdjustThresholdLower) newTimeSnap = newTimeSnap.divide(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](1, 2)); + timeline.timeScroll = newTimeScroll; + timeline.timeSnap = newTimeSnap; + } +} + +/***/ }), + +/***/ "./src/timeline/timeline.ts": +/*!**********************************!*\ + !*** ./src/timeline/timeline.ts ***! + \**********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MouseAction: () => (/* binding */ MouseAction), +/* harmony export */ cursorGetLaneIndexMax: () => (/* binding */ cursorGetLaneIndexMax), +/* harmony export */ cursorGetLaneIndexMin: () => (/* binding */ cursorGetLaneIndexMin), +/* harmony export */ cursorSetTime: () => (/* binding */ cursorSetTime), +/* harmony export */ cursorSetTrack: () => (/* binding */ cursorSetTrack), +/* harmony export */ laneIndexAtY: () => (/* binding */ laneIndexAtY), +/* harmony export */ makeNew: () => (/* binding */ makeNew), +/* harmony export */ pointAt: () => (/* binding */ pointAt), +/* harmony export */ resize: () => (/* binding */ resize), +/* harmony export */ selectionAdd: () => (/* binding */ selectionAdd), +/* harmony export */ selectionAddAtCursor: () => (/* binding */ selectionAddAtCursor), +/* harmony export */ selectionClear: () => (/* binding */ selectionClear), +/* harmony export */ selectionRange: () => (/* binding */ selectionRange), +/* harmony export */ selectionToggle: () => (/* binding */ selectionToggle), +/* harmony export */ timeAtX: () => (/* binding */ timeAtX), +/* harmony export */ timeRangeAtX: () => (/* binding */ timeRangeAtX), +/* harmony export */ visibleTimeRange: () => (/* binding */ visibleTimeRange), +/* harmony export */ xAtTime: () => (/* binding */ xAtTime) +/* harmony export */ }); +/* harmony import */ var immutable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! immutable */ "./node_modules/immutable/dist/immutable.es.js"); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../project */ "./src/project/index.ts"); +/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); +/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); +/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); +/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); + + + + + + +let MouseAction = /*#__PURE__*/function (MouseAction) { + MouseAction[MouseAction["None"] = 0] = "None"; + MouseAction[MouseAction["Pan"] = 1] = "Pan"; + MouseAction[MouseAction["DragTime"] = 2] = "DragTime"; + MouseAction[MouseAction["DragRow"] = 3] = "DragRow"; + MouseAction[MouseAction["DragTimeAndRow"] = 4] = "DragTimeAndRow"; + MouseAction[MouseAction["StretchTimeStart"] = 5] = "StretchTimeStart"; + MouseAction[MouseAction["StretchTimeEnd"] = 6] = "StretchTimeEnd"; + MouseAction[MouseAction["SelectCursor"] = 7] = "SelectCursor"; + return MouseAction; +}({}); +function makeNew() { + return { + pixelRatio: 1, + renderRect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_4__["default"](0, 0, 0, 0), + trackMeasuresH: 20, + trackControlX: 10, + trackControlY: 25, + trackControlSize: 20, + layout: new _index_ts__WEBPACK_IMPORTED_MODULE_1__.Layout(), + hover: undefined, + yScroll: 0, + timeScroll: -2.5, + timeScale: 100, + timeSnap: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](1, 8), + timeSnapBase: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](1, 16), + noteRowH: 16, + cursor: { + visible: true, + time1: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), + time2: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), + laneIndex1: 0, + laneIndex2: 0, + rectY1: 0, + rectY2: 0 + }, + keysDown: new Set(), + mouse: { + down: false, + downDate: new Date(), + action: MouseAction.None, + point: { + pos: { + x: 0, + y: 0 + }, + time: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), + row: 0, + laneIndex: 0, + trackPos: { + x: 0, + y: 0 + }, + originTrackPos: { + x: 0, + y: 0 + } + }, + pointPrev: { + pos: { + x: 0, + y: 0 + }, + time: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), + row: 0, + laneIndex: 0, + trackPos: { + x: 0, + y: 0 + }, + originTrackPos: { + x: 0, + y: 0 + } + }, + wheelDate: new Date() + }, + drag: { + origin: null, + xLocked: true, + yLocked: true, + posDelta: { + x: 0, + y: 0 + }, + timeDelta: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), + rowDelta: 0, + trackDelta: 0, + trackInsertionBefore: -1, + elemId: -1, + notePreviewLast: null + }, + insertion: { + nearMidiPitch: 60, + duration: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](1, 4) + }, + selection: immutable__WEBPACK_IMPORTED_MODULE_5__["default"].Set(), + needsKeyFinish: false, + rangeSelectOriginTrackIndex: -1 + }; +} +function resize(state, pixelRatio, rect) { + state.pixelRatio = pixelRatio; + state.renderRect = rect; +} +function xAtTime(timeline, time) { + return (time.asFloat() - timeline.timeScroll) * timeline.timeScale; +} +function timeAtX(timeline, x, timeSnap) { + timeSnap = timeSnap || timeline.timeSnap; + const time = x / timeline.timeScale + timeline.timeScroll; + return _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"].fromFloat(time, timeSnap.denominator); +} +function timeRangeAtX(timeline, x1, x2, timeSnap) { + timeSnap = timeSnap || timeline.timeSnap; + return new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](timeAtX(timeline, x1, timeSnap).subtract(timeSnap), timeAtX(timeline, x2, timeSnap).add(timeSnap)); +} +function visibleTimeRange(timeline) { + return new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](timeAtX(timeline, 0).subtract(timeline.timeSnap), timeAtX(timeline, timeline.renderRect.w).add(timeline.timeSnap)); +} +function laneIndexAtY(timeline, y) { + if (y < 0) return -1; + for (let i = 0; i < timeline.layout.lanes.length; i++) { + const lane = timeline.layout.lanes[i]; + if (y < lane.rect.y2) return i; + } + return timeline.layout.lanes.length; +} +function pointAt(timeline, x, y) { + const time = timeAtX(timeline, x); + const row = timeline.layout.laneNotes ? _index_ts__WEBPACK_IMPORTED_MODULE_1__.rowAtY(timeline, timeline.layout.laneNotes, y) : 0; + const laneIndex = laneIndexAtY(timeline, y); + + /*const trackPosY = pos.y - trackY(state, state.mouse.point.trackIndex) + const trackPos = { x: pos.x, y: trackPosY } + let originTrackPos = trackPos + if (state.drag.origin) + { + const originTrackPosY = pos.y - trackY(state, state.drag.origin.point.trackIndex) + originTrackPos = { x: pos.x, y: originTrackPosY } + }*/ + + return { + pos: { + x, + y + }, + time, + laneIndex, + trackPos: { + x: 0, + y: 0 + }, + row, + originTrackPos: { + x: 0, + y: 0 + } + }; +} +function selectionClear(timeline) { + timeline.selection = timeline.selection.clear(); +} +function selectionRange(state, project) { + return _project__WEBPACK_IMPORTED_MODULE_0__.getRangeForElems(project, state.selection); +} +function selectionToggle(timeline, project, element) { + if (element.id === undefined || element.action === undefined) return; + const alreadySelected = timeline.selection.has(element.id); + if (!alreadySelected) timeline.selection = timeline.selection.add(element.id);else timeline.selection = timeline.selection.remove(element.id); +} +function selectionAdd(timeline, id) { + timeline.selection = timeline.selection.add(id); +} +function selectionAddAtCursor(timeline, project, verticalRegion) { + const time1 = timeline.cursor.time1; + const time2 = timeline.cursor.time2; + if (time1.compare(time2) === 0) return; + const range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](time1, time2, false, false).sorted(); + const laneIndexMin = cursorGetLaneIndexMin(timeline); + const laneIndexMax = cursorGetLaneIndexMax(timeline); + for (let l = laneIndexMin; l <= laneIndexMax; l++) { + const lane = timeline.layout.lanes[l]; + if (lane.iterElementsAtRegion === undefined) continue; + for (const id of lane.iterElementsAtRegion(timeline, project, range, verticalRegion)) selectionAdd(timeline, id); + } +} +function cursorSetTime(timeline, time1, time2) { + timeline.cursor.time1 = time1 ?? timeline.cursor.time1; + timeline.cursor.time2 = time2 ?? timeline.cursor.time2; +} +function cursorSetTrack(timeline, trackIndex1, trackIndex2) { + timeline.cursor.laneIndex1 = Math.max(0, Math.min(timeline.layout.lanes.length - 1, trackIndex1 ?? timeline.cursor.laneIndex1)); + timeline.cursor.laneIndex2 = Math.max(0, Math.min(timeline.layout.lanes.length - 1, trackIndex2 ?? timeline.cursor.laneIndex2)); +} +function cursorGetLaneIndexMin(timeline) { + return Math.max(0, Math.min(timeline.cursor.laneIndex1, timeline.cursor.laneIndex2)); +} +function cursorGetLaneIndexMax(timeline) { + return Math.min(timeline.layout.lanes.length - 1, Math.max(timeline.cursor.laneIndex1, timeline.cursor.laneIndex2)); +} + +/***/ }), + +/***/ "./src/utils/binarySearch.ts": +/*!***********************************!*\ + !*** ./src/utils/binarySearch.ts ***! + \***********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ BinarySearch) +/* harmony export */ }); +class BinarySearch { + static find(array, compareFn) { + /*for (let i = 0; i < array.length; i++) + { + const comparison = compareFn(value, array[i]) + + if (comparison <= 0) + return i + } + + return array.length*/ + + let lo = -1; + let hi = array.length; + while (1 + lo < hi) { + const mi = lo + (hi - lo >> 1); + if (compareFn(array[mi]) <= 0) hi = mi;else lo = mi; + } + return hi; + } + static findExact(array, value, compareFn) { + let i = BinarySearch.find(array, compareFn); + while (i < array.length) { + if (array[i] === value) return i; + i += 1; + } + return null; + } + static findPreviousOrEqual(array, compareFn) { + if (array.length == 0) return null; + const i = BinarySearch.find(array, compareFn); + if (i < array.length && compareFn(array[i]) == 0) return i; + if (i > 0) return i - 1; + return null; + } + static findPreviousNotEqual(array, compareFn) { + if (array.length == 0) return null; + const i = BinarySearch.find(array, compareFn); + if (i > 0) return i - 1; + return null; + } + static findNextNotEqual(array, compareFn) { + if (array.length == 0) return null; + let i = BinarySearch.find(array, compareFn); + while (i < array.length) { + if (compareFn(array[i]) != 0) break; + i += 1; + } + if (i < array.length) return i; + return null; + } + static *iterEqual(array, compareFn) { + let i = BinarySearch.find(array, compareFn); + while (i < array.length) { + if (compareFn(array[i]) != 0) break; + yield i; + i += 1; + } + } +} + +/***/ }), + +/***/ "./src/utils/listOfRanges.ts": +/*!***********************************!*\ + !*** ./src/utils/listOfRanges.ts ***! + \***********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ ListOfRanges) +/* harmony export */ }); +/* harmony import */ var assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! assert */ "?1e65"); +/* harmony import */ var assert__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(assert__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var immutable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! immutable */ "./node_modules/immutable/dist/immutable.es.js"); +/* harmony import */ var _rational_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./rational.ts */ "./src/utils/rational.ts"); +/* harmony import */ var _range_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./range.ts */ "./src/utils/range.ts"); +/* harmony import */ var _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./binarySearch.ts */ "./src/utils/binarySearch.ts"); + + + + + +class Bucket { + constructor(start) { + this.start = start; + this.elems = []; + } +} +class ListOfRanges { + constructor() { + this.idMap = immutable__WEBPACK_IMPORTED_MODULE_4__["default"].Map(); + this.buckets = []; + this.bucketFn = t => t.asFloat(); + } + clone() { + let cloned = new ListOfRanges(); + cloned.idMap = this.idMap; + cloned.buckets = this.buckets; + cloned.bucketFn = this.bucketFn; + return cloned; + } + clear() { + return Object.assign(new ListOfRanges(), { + bucketFn: this.bucketFn + }); + } + _ensureBucketsAtRange(range) { + let newBuckets = [...this.buckets]; + if (this.buckets.length == 0) newBuckets = [new Bucket(0)]; + const start = this.bucketFn(range.start); + while (start < newBuckets[0].start) { + const newBucket = new Bucket(newBuckets[0].start - 1); + newBuckets = [newBucket, ...newBuckets]; + } + const end = this.bucketFn(range.end); + while (end >= newBuckets[newBuckets.length - 1].start + 1) { + const newBucket = new Bucket(newBuckets[newBuckets.length - 1].start + 1); + newBuckets = [...newBuckets, newBucket]; + } + const cloned = this.clone(); + cloned.buckets = newBuckets; + return cloned; + } + *_iterBucketIndicesAtRange(range) { + const start = this.bucketFn(range.start); + const end = this.bucketFn(range.end); + let b = _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].find(this.buckets, bucket => start - bucket.start); + if (b > 0 && start < this.buckets[b - 1].start + 1) b -= 1; + while (true) { + if (b >= this.buckets.length || this.buckets[b].start > end) break; + yield b; + b += 1; + } + } + get size() { + return this.idMap.size; + } + update(elem) { + if (!this.idMap.get(elem.id)) return this; + return this.upsert(elem); + } + upsert(elem) { + //console.log("upsert id", elem.id, "buckets", this.bucketFn(elem.range.start), this.bucketFn(elem.range.end),) + + let newList = this._ensureBucketsAtRange(elem.range); + newList = newList.removeById(elem.id, false); + for (const b of newList._iterBucketIndicesAtRange(elem.range)) { + newList.buckets[b] = Object.assign({}, newList.buckets[b]); + const newElemIndex = _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].find(newList.buckets[b].elems, e => elem.range.start.compare(e.range.start)); + //console.log("- add to bucket", b, "at elem", newElemIndex) + + newList.buckets[b].elems = [...newList.buckets[b].elems.slice(0, newElemIndex), elem, ...newList.buckets[b].elems.slice(newElemIndex)]; + } + newList.idMap = newList.idMap.set(elem.id, elem); + return newList; + } + upsertMany(elems) { + let newList = this; + for (const elem of elems) newList = newList.upsert(elem); + return newList; + } + removeById(id, removeId = true) { + let newList = this; + const elem = this.idMap.get(id); + if (elem) { + newList = this.clone(); + newList.buckets = [...newList.buckets]; + for (const b of newList._iterBucketIndicesAtRange(elem.range)) { + const elemIndex = _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].findExact(newList.buckets[b].elems, elem, b => elem.range.start.compare(b.range.start)); + if (elemIndex === null) continue; + + //console.log("- remove from bucket", b, "at elem", elemIndex) + + newList.buckets[b] = Object.assign({}, newList.buckets[b]); + newList.buckets[b].elems = [...newList.buckets[b].elems.slice(0, elemIndex), ...newList.buckets[b].elems.slice(elemIndex + 1)]; + } + if (removeId) newList.idMap = newList.idMap.delete(id); + } + return newList; + } + findById(id) { + return this.idMap.get(id); + } + *iterAll() { + for (const bucket of this.buckets) for (const elem of bucket.elems) { + const elemStart = this.bucketFn(elem.range.start); + if (elemStart >= bucket.start && elemStart < bucket.start + 1) yield elem; + } + } + *iterAtRange(range) { + let firstBucket = true; + for (const b of this._iterBucketIndicesAtRange(range)) { + const bucket = this.buckets[b]; + for (const elem of bucket.elems) { + const elemStart = this.bucketFn(elem.range.start); + if (range.overlapsRange(elem.range) && (firstBucket || elemStart >= bucket.start && elemStart < bucket.start + 1)) yield elem; + } + firstBucket = false; + } + } + *iterAtPoint(point) { + const range = _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"].fromPoint(point, true, true); + for (const item of this.iterAtRange(range)) yield item; + } + *iterActiveAtRangePairwise(range) { + if (this.idMap.size == 0) { + yield [null, null]; + return; + } + let prevItem = this.findPrevious(range.start); + while (true) { + const nextItem = this.findNextNotEqual(prevItem?.range.end ?? range.start); + yield [prevItem, nextItem]; + if (!nextItem) break; + prevItem = nextItem; + } + } + *iterAllPairwise() { + if (this.idMap.size == 0) { + yield [null, null]; + return; + } + let prevItem = null; + for (const nextItem of this.iterAll()) { + yield [prevItem, nextItem]; + prevItem = nextItem; + } + yield [prevItem, null]; + } + getTotalRange() { + let firstElem = null; + let lastElem = null; + for (const bucket of this.buckets) { + if (bucket.elems.length > 0) { + firstElem = bucket.elems[0]; + break; + } + } + for (let b = this.buckets.length - 1; b >= 0; b--) { + for (const elem of this.buckets[b].elems) { + if (!lastElem || elem.range.end.compare(lastElem.range.end) > 0) lastElem = elem; + } + if (lastElem) break; + } + if (!firstElem || !lastElem) return null; + return firstElem.range.merge(lastElem.range); + } + findFirst() { + for (const elem of this.iterAll()) return elem; + return null; + } + findActiveAt(time) { + let result = null; + for (const elem of this.iterAll()) { + if (elem.range.start.compare(time) > 0) break; + result = elem; + } + return result; + } + findPreviousAnchor(fromPoint) { + let previous = null; + const end = this.bucketFn(fromPoint); + const endB = Math.min(this.buckets.length - 1, _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].find(this.buckets, bucket => end - bucket.start)); + for (let b = endB; b >= 0; b--) { + if (previous && this.bucketFn(previous) > this.buckets[b].start + 1) break; + for (const elem of this.buckets[b].elems) { + if (elem.range.start.compare(fromPoint) < 0 && (previous === null || elem.range.start.compare(previous) > 0)) previous = elem.range.start; + if (elem.range.end.compare(fromPoint) < 0 && (previous === null || elem.range.end.compare(previous) > 0)) previous = elem.range.end; + } + } + return previous; + } + findPrevious(fromPoint) { + let nearestItem = null; + let nearestPoint = null; + for (const item of this.iterAll()) { + const itemRange = item.range; + if (itemRange.end.compare(fromPoint) > 0) continue; + if (nearestPoint == null || itemRange.end.compare(nearestPoint) > 0) { + nearestItem = item; + nearestPoint = itemRange.end; + } + } + return nearestItem; + } + findPreviousDeletionAnchor(fromPoint) { + const anchor = this.findPrevious(fromPoint); + if (!anchor) return null; + const anchorRange = anchor.range; + if (anchorRange.end.compare(fromPoint) != 0) return anchorRange.end; + let nearestPoint = anchorRange.start; + for (const item of this.iterAll()) { + const itemRange = item.range; + if (itemRange.end.compare(anchorRange.end) != 0) continue; + if (itemRange.start.compare(nearestPoint) > 0) nearestPoint = itemRange.start; + } + return nearestPoint; + } + findNextNotEqual(fromPoint) { + let nearestItem = null; + let nearestPoint = null; + for (const item of this.iterAll()) { + const itemRange = item.range; + if (itemRange.end.compare(fromPoint) <= 0) continue; + if (nearestPoint == null || itemRange.end.compare(nearestPoint) < 0) { + nearestItem = item; + nearestPoint = itemRange.end; + } + } + return nearestItem; + } + static test() { + let list = new ListOfRanges(); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], []); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), null); + const elem1 = { + id: 1, + range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](2, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](6, 4)) + }; + const elem2 = { + id: 2, + range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](0, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](3, 4)) + }; + const elem3 = { + id: 3, + range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](-3, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](11, 4)) + }; + const elem4 = { + id: 4, + range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](12, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](16, 4)) + }; + const elem5 = { + id: 5, + range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](5, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](13, 4)) + }; + const elem1_2 = { + id: 1, + range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](6, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](11, 4)) + }; + list = list.upsert(elem1); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem1.range); + list = list.upsert(elem2); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem2.range.merge(elem1.range)); + list = list.upsert(elem3); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem1.range)); + list = list.upsert(elem4); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem1, elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem4.range)], [elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem4.range)); + list = list.upsert(elem5); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem1, elem5, elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem1, elem5]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2, elem1]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem1, elem5]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem4.range)], [elem5, elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem5.range)], [elem3, elem1, elem5, elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem4.range)); + list = list.upsert(elem1_2); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem5, elem1_2, elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem5]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem5, elem1_2]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem4.range)], [elem5, elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem5.range)], [elem3, elem5, elem1_2, elem4]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1_2.range)], [elem3, elem5, elem1_2]); + assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem4.range)); + console.log("ListOfRanges tests passed"); + } +} + +/***/ }), + +/***/ "./src/utils/mathUtils.ts": +/*!********************************!*\ + !*** ./src/utils/mathUtils.ts ***! + \********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ dbToLinearGain: () => (/* binding */ dbToLinearGain), +/* harmony export */ dbToMidiVolume: () => (/* binding */ dbToMidiVolume), +/* harmony export */ linearGainToDb: () => (/* binding */ linearGainToDb), +/* harmony export */ midiToHertz: () => (/* binding */ midiToHertz), +/* harmony export */ midiVolumeToDb: () => (/* binding */ midiVolumeToDb), +/* harmony export */ midiVolumeToLinearGain: () => (/* binding */ midiVolumeToLinearGain), +/* harmony export */ mod: () => (/* binding */ mod), +/* harmony export */ quantize: () => (/* binding */ quantize) +/* harmony export */ }); +function mod(x, m) { + return (x % m + m) % m; +} +function quantize(x, step) { + return Math.floor(x * step) / step; +} +function midiToHertz(midi) { + return Math.pow(2, (midi - 69) / 12) * 440; +} +function dbToLinearGain(db) { + return Math.pow(10, db / 20); +} +function linearGainToDb(linearGain) { + return 20 * Math.log10(linearGain); +} +const minMidiDbLevel = -30; +function dbToMidiVolume(db) { + return Math.max(0, Math.min(1, 1 - db / minMidiDbLevel)); +} +function midiVolumeToDb(midiVol) { + if (midiVol <= 0) return 0; + return minMidiDbLevel * (1 - midiVol); +} +function midiVolumeToLinearGain(midiVol) { + if (midiVol <= 0) return 0; + return dbToLinearGain(midiVolumeToDb(midiVol)); +} + +/***/ }), + +/***/ "./src/utils/range.ts": +/*!****************************!*\ + !*** ./src/utils/range.ts ***! + \****************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Range) +/* harmony export */ }); +/* harmony import */ var _rational_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rational.ts */ "./src/utils/rational.ts"); + +class Range { + constructor(start, end, startInclusive = true, endInclusive = false) { + this.start = start; + this.end = end; + this.startInclusive = startInclusive; + this.endInclusive = endInclusive; + } + static fromPoint(p, startInclusive = true, endInclusive = true) { + return new Range(p, p, startInclusive, endInclusive); + } + static fromStartDuration(start, duration) { + return new Range(start, start.add(duration)); + } + static dummy() { + return new Range(new _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0), new _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0)); + } + get duration() { + return this.end.subtract(this.start); + } + setDuration(newDuration) { + return new Range(this.start, this.start.add(newDuration), this.startInclusive, this.endInclusive); + } + sorted() { + const startInclusive = this.start.lessThan(this.end) ? this.startInclusive : this.endInclusive; + const endInclusive = this.end.greaterThan(this.start) ? this.endInclusive : this.startInclusive; + return new Range(this.start.min(this.end), this.start.max(this.end), startInclusive, endInclusive); + } + max() { + return this.start.max(this.end); + } + min() { + return this.start.min(this.end); + } + merge(other) { + return Range.merge(this, other); + } + static merge(r1, r2) { + if (r1 === null && r2 === null) return null; + if (r1 === null) return r2; + if (r2 === null) return r1; + return new Range(r1.start.min(r2.start), r1.end.max(r2.end)); + } + intersect(other) { + return Range.intersect(this, other); + } + static intersect(r1, r2) { + if (r1 === null && r2 === null) return null; + if (r1 === null) return r2; + if (r2 === null) return r1; + return new Range(r1.start.max(r2.start), r1.end.min(r2.end)); + } + atZero() { + return new Range(new _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0), this.duration, this.startInclusive, this.endInclusive); + } + stretch(offset, pivot, origin) { + return new Range(this.start.stretch(offset, pivot, origin), this.end.stretch(offset, pivot, origin), this.startInclusive, this.endInclusive); + } + displace(offset) { + return new Range(this.start.add(offset), this.end.add(offset), this.startInclusive, this.endInclusive); + } + subtract(offset) { + return new Range(this.start.subtract(offset), this.end.subtract(offset), this.startInclusive, this.endInclusive); + } + grow(offset) { + return new Range(this.start.subtract(offset), this.end.add(offset), this.startInclusive, this.endInclusive); + } + shrink(offset) { + return new Range(this.start.add(offset), this.end.subtract(offset), this.startInclusive, this.endInclusive); + } + snap(step) { + return new Range(this.start.snap(step), this.end.snap(step), this.startInclusive, this.endInclusive); + } + *iterSlices(slice) { + if (slice.start.compare(this.start) <= 0) { + if (slice.end.compare(this.end) < 0) yield new Range(slice.end.max(this.start), this.end); + } else { + if (slice.end.compare(this.end) >= 0) yield new Range(this.start, slice.start.min(this.end));else { + yield new Range(this.start, slice.start.min(this.end)); + yield new Range(slice.end.max(this.start), this.end); + } + } + } + isPoint() { + return this.start.equalTo(this.end); + } + overlapsPoint(point) { + const compStart = this.start.compare(point); + const compEnd = this.end.compare(point); + const checkStart = this.startInclusive ? compStart <= 0 : compStart < 0; + const checkEnd = this.endInclusive ? compEnd >= 0 : compEnd > 0; + return checkStart && checkEnd; + } + overlapsRange(range) { + const compStart = this.start.compare(range.end); + const compEnd = this.end.compare(range.start); + const checkStart = this.startInclusive && range.endInclusive ? compStart <= 0 : compStart < 0; + const checkEnd = this.endInclusive && range.startInclusive ? compEnd >= 0 : compEnd > 0; + return checkStart && checkEnd; + } + containsRangeCompletely(range) { + const compStart = this.start.compare(range.start); + const compEnd = this.end.compare(range.end); + const checkStart = this.startInclusive ? compStart <= 0 : compStart < 0; + const checkEnd = this.endInclusive ? compEnd >= 0 : compEnd > 0; + return checkStart && checkEnd; + } + quantize(maxDenom) { + return new Range(this.start.quantize(maxDenom), this.end.quantize(maxDenom), this.startInclusive, this.endInclusive); + } + toString() { + return "[" + this.start.toString() + " ~ " + this.end.toString() + "]"; + } + toJson(quantize) { + if (this.start.compare(this.end) == 0) return [this.start.toJson()];else { + if (quantize !== undefined) return [this.start.toJson(), this.duration.quantize(quantize).toJson()];else return [this.start.toJson(), this.duration.toJson()]; + } + } + static fromJson(json) { + if (json.length == 1) return Range.fromPoint(_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromJson(json[0]));else return Range.fromStartDuration(_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromJson(json[0]), _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromJson(json[1])); + } +} + +/***/ }), + +/***/ "./src/utils/rational.ts": +/*!*******************************!*\ + !*** ./src/utils/rational.ts ***! + \*******************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Rational) +/* harmony export */ }); +function mod(x, m) { + return (x % m + m) % m; +} +class Rational { + constructor(numerator = 0, denominator = 1) { + if (denominator == 0) throw "denominator zero"; + if (!isFinite(numerator) || !isFinite(denominator)) throw "invalid rational"; + this.numerator = numerator; + this.denominator = denominator; + this.simplifyInPlace(); + } + static fromFloat(floatValue, maxDenominator) { + const integer = Math.floor(floatValue); + const frac = floatValue - integer; + return new Rational(integer * maxDenominator + Math.round(frac * maxDenominator), maxDenominator); + } + static fromIntegerPlusRational(integer, numeratorWithoutInteger, denominator) { + return new Rational(integer * denominator + numeratorWithoutInteger, denominator); + } + asFloat() { + return this.numerator / this.denominator; + } + get n() { + return this.numerator; + } + get d() { + return this.denominator; + } + get integer() { + return Math.floor(this.numerator / this.denominator); + } + get numeratorWithoutInteger() { + return mod(this.numerator, this.denominator); + } + negate() { + return new Rational(-this.numerator, this.denominator); + } + absolute() { + if (this.numerator < 0) return new Rational(-this.numerator, this.denominator);else return this; + } + add(other) { + return new Rational(this.numerator * other.denominator + other.numerator * this.denominator, this.denominator * other.denominator); + } + subtract(other) { + return new Rational(this.numerator * other.denominator - other.numerator * this.denominator, this.denominator * other.denominator); + } + multiply(other) { + return new Rational(this.numerator * other.numerator, this.denominator * other.denominator); + } + multiplyByFloat(x) { + return new Rational(this.numerator * x, this.denominator); + } + divide(other) { + return new Rational(this.numerator * other.denominator, this.denominator * other.numerator); + } + snap(step) { + return Rational.fromFloat(this.asFloat(), step.denominator); + } + quantize(maxDenominator) { + if (this.denominator <= maxDenominator) return this.simplify(); + return new Rational(Math.round(this.numerator / this.denominator * maxDenominator), maxDenominator); + } + stretch(offset, pivot, origin) { + let dist = origin.subtract(pivot); + if (dist.numerator == 0) return this; + let p = this.subtract(pivot).divide(dist); + let move = origin.add(offset).subtract(pivot).divide(dist); + return pivot.add(dist.multiply(p).multiply(move)); + } + isZero() { + return this.numerator == 0; + } + compare(other) { + let thisNumerator = this.numerator * other.denominator; + let otherNumerator = other.numerator * this.denominator; + if (thisNumerator < otherNumerator) return -1;else if (thisNumerator > otherNumerator) return 1;else return 0; + } + equalTo(other) { + return this.compare(other) == 0; + } + notEqualTo(other) { + return this.compare(other) != 0; + } + lessThan(other) { + return this.compare(other) < 0; + } + lessThanOrEqual(other) { + return this.compare(other) <= 0; + } + greaterThan(other) { + return this.compare(other) > 0; + } + greaterThanOrEqual(other) { + return this.compare(other) >= 0; + } + static max(a, b) { + if (a === null && b === null) return null; + if (a === null) return b; + if (b === null) return a; + if (a.compare(b) > 0) return a;else return b; + } + static min(a, b) { + if (a === null && b === null) return null; + if (a === null) return b; + if (b === null) return a; + if (a.compare(b) < 0) return a;else return b; + } + max(other) { + return Rational.max(this, other); + } + min(other) { + return Rational.min(this, other); + } + simplify() { + return new Rational(this.numerator, this.denominator); + } + simplifyInPlace() { + this.trySimplifyInPlaceBy(2); + this.trySimplifyInPlaceBy(3); + this.trySimplifyInPlaceBy(5); + this.trySimplifyInPlaceBy(7); + this.trySimplifyInPlaceBy(11); + this.trySimplifyInPlaceBy(13); + } + trySimplifyInPlaceBy(divider) { + while (this.numerator % divider == 0 && this.denominator % divider == 0) { + this.numerator /= divider; + this.denominator /= divider; + } + } + toString() { + let integer = Math.floor(this.numerator / this.denominator); + let numerator = this.numerator % this.denominator; + if (numerator == 0) return integer.toString();else return integer.toString() + " + " + numerator.toString() + "/" + this.denominator.toString(); + } + toJson() { + return [this.integer, this.numeratorWithoutInteger, this.denominator]; + } + static fromJson(array) { + return new Rational(array[0] * array[2] + array[1], array[2]); + } +} + +/***/ }), + +/***/ "./src/utils/rect.ts": +/*!***************************!*\ + !*** ./src/utils/rect.ts ***! + \***************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ Rect) +/* harmony export */ }); +class Rect { + constructor(x, y, w, h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + static fromVertices(x1, y1, x2, y2) { + return new Rect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1)); + } + static fromElement(elem) { + const clientRect = elem.getBoundingClientRect(); + return new Rect(clientRect.left, clientRect.top, clientRect.width, clientRect.height); + } + clone() { + return new Rect(this.x, this.y, this.w, this.h); + } + get x1() { + return this.x; + } + get y1() { + return this.y; + } + get x2() { + return this.x + this.w; + } + get y2() { + return this.y + this.h; + } + get xCenter() { + return (this.x1 + this.x2) / 2; + } + get yCenter() { + return (this.y1 + this.y2) / 2; + } + withX(value) { + return new Rect(value, this.y, this.w, this.h); + } + withY(value) { + return new Rect(this.x, value, this.w, this.h); + } + withW(value) { + return new Rect(this.x, this.y, value, this.h); + } + withH(value) { + return new Rect(this.x, this.y, this.w, value); + } + withX1(value) { + return Rect.fromVertices(value, this.y1, this.x2, this.y2); + } + withY1(value) { + return Rect.fromVertices(this.x1, value, this.x2, this.y2); + } + withX2(value) { + return Rect.fromVertices(this.x1, this.y1, value, this.y2); + } + withY2(value) { + return Rect.fromVertices(this.x1, this.y1, this.x2, value); + } + displace(x, y) { + return new Rect(this.x + x, this.y + y, this.w, this.h); + } + expand(amount) { + return Rect.fromVertices(this.x1 - amount, this.y1 - amount, this.x2 + amount, this.y2 + amount); + } + expandW(amount) { + return Rect.fromVertices(this.x1 - amount, this.y1, this.x2 + amount, this.y2); + } + contains(p) { + return p.x >= this.x && p.x < this.x2 && p.y >= this.y && p.y < this.y2; + } + overlaps(other) { + return this.x2 >= other.x && this.x < other.x2 && this.y2 >= other.y && this.y < other.y2; + } +} + +/***/ }), + +/***/ "./node_modules/immutable/dist/immutable.es.js": +/*!*****************************************************!*\ + !*** ./node_modules/immutable/dist/immutable.es.js ***! + \*****************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Collection: () => (/* binding */ Collection), +/* harmony export */ Iterable: () => (/* binding */ Iterable), +/* harmony export */ List: () => (/* binding */ List), +/* harmony export */ Map: () => (/* binding */ Map), +/* harmony export */ OrderedMap: () => (/* binding */ OrderedMap), +/* harmony export */ OrderedSet: () => (/* binding */ OrderedSet), +/* harmony export */ PairSorting: () => (/* binding */ PairSorting), +/* harmony export */ Range: () => (/* binding */ Range), +/* harmony export */ Record: () => (/* binding */ Record), +/* harmony export */ Repeat: () => (/* binding */ Repeat), +/* harmony export */ Seq: () => (/* binding */ Seq), +/* harmony export */ Set: () => (/* binding */ Set), +/* harmony export */ Stack: () => (/* binding */ Stack), +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), +/* harmony export */ fromJS: () => (/* binding */ fromJS), +/* harmony export */ get: () => (/* binding */ get), +/* harmony export */ getIn: () => (/* binding */ getIn$1), +/* harmony export */ has: () => (/* binding */ has), +/* harmony export */ hasIn: () => (/* binding */ hasIn$1), +/* harmony export */ hash: () => (/* binding */ hash), +/* harmony export */ is: () => (/* binding */ is), +/* harmony export */ isAssociative: () => (/* binding */ isAssociative), +/* harmony export */ isCollection: () => (/* binding */ isCollection), +/* harmony export */ isImmutable: () => (/* binding */ isImmutable), +/* harmony export */ isIndexed: () => (/* binding */ isIndexed), +/* harmony export */ isKeyed: () => (/* binding */ isKeyed), +/* harmony export */ isList: () => (/* binding */ isList), +/* harmony export */ isMap: () => (/* binding */ isMap), +/* harmony export */ isOrdered: () => (/* binding */ isOrdered), +/* harmony export */ isOrderedMap: () => (/* binding */ isOrderedMap), +/* harmony export */ isOrderedSet: () => (/* binding */ isOrderedSet), +/* harmony export */ isPlainObject: () => (/* binding */ isPlainObject), +/* harmony export */ isRecord: () => (/* binding */ isRecord), +/* harmony export */ isSeq: () => (/* binding */ isSeq), +/* harmony export */ isSet: () => (/* binding */ isSet), +/* harmony export */ isStack: () => (/* binding */ isStack), +/* harmony export */ isValueObject: () => (/* binding */ isValueObject), +/* harmony export */ merge: () => (/* binding */ merge), +/* harmony export */ mergeDeep: () => (/* binding */ mergeDeep$1), +/* harmony export */ mergeDeepWith: () => (/* binding */ mergeDeepWith$1), +/* harmony export */ mergeWith: () => (/* binding */ mergeWith), +/* harmony export */ remove: () => (/* binding */ remove), +/* harmony export */ removeIn: () => (/* binding */ removeIn), +/* harmony export */ set: () => (/* binding */ set), +/* harmony export */ setIn: () => (/* binding */ setIn$1), +/* harmony export */ update: () => (/* binding */ update$1), +/* harmony export */ updateIn: () => (/* binding */ updateIn$1), +/* harmony export */ version: () => (/* binding */ version) +/* harmony export */ }); +/** + * MIT License + * + * Copyright (c) 2014-present, Lee Byron and other contributors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +var DELETE = 'delete'; + +// Constants describing the size of trie nodes. +var SHIFT = 5; // Resulted in best performance after ______? +var SIZE = 1 << SHIFT; +var MASK = SIZE - 1; + +// A consistent shared value representing "not set" which equals nothing other +// than itself, and nothing that could be provided externally. +var NOT_SET = {}; + +// Boolean references, Rough equivalent of `bool &`. +function MakeRef() { + return { value: false }; +} + +function SetRef(ref) { + if (ref) { + ref.value = true; + } +} + +// A function which returns a value representing an "owner" for transient writes +// to tries. The return value will only ever equal itself, and will not equal +// the return of any subsequent call of this function. +function OwnerID() {} + +function ensureSize(iter) { + if (iter.size === undefined) { + iter.size = iter.__iterate(returnTrue); + } + return iter.size; +} + +function wrapIndex(iter, index) { + // This implements "is array index" which the ECMAString spec defines as: + // + // A String property name P is an array index if and only if + // ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal + // to 2^32−1. + // + // http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects + if (typeof index !== 'number') { + var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32 + if ('' + uint32Index !== index || uint32Index === 4294967295) { + return NaN; + } + index = uint32Index; + } + return index < 0 ? ensureSize(iter) + index : index; +} + +function returnTrue() { + return true; +} + +function wholeSlice(begin, end, size) { + return ( + ((begin === 0 && !isNeg(begin)) || + (size !== undefined && begin <= -size)) && + (end === undefined || (size !== undefined && end >= size)) + ); +} + +function resolveBegin(begin, size) { + return resolveIndex(begin, size, 0); +} + +function resolveEnd(end, size) { + return resolveIndex(end, size, size); +} + +function resolveIndex(index, size, defaultIndex) { + // Sanitize indices using this shorthand for ToInt32(argument) + // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 + return index === undefined + ? defaultIndex + : isNeg(index) + ? size === Infinity + ? size + : Math.max(0, size + index) | 0 + : size === undefined || size === index + ? index + : Math.min(size, index) | 0; +} + +function isNeg(value) { + // Account for -0 which is negative, but not less than 0. + return value < 0 || (value === 0 && 1 / value === -Infinity); +} + +var IS_COLLECTION_SYMBOL = '@@__IMMUTABLE_ITERABLE__@@'; + +function isCollection(maybeCollection) { + return Boolean(maybeCollection && maybeCollection[IS_COLLECTION_SYMBOL]); +} + +var IS_KEYED_SYMBOL = '@@__IMMUTABLE_KEYED__@@'; + +function isKeyed(maybeKeyed) { + return Boolean(maybeKeyed && maybeKeyed[IS_KEYED_SYMBOL]); +} + +var IS_INDEXED_SYMBOL = '@@__IMMUTABLE_INDEXED__@@'; + +function isIndexed(maybeIndexed) { + return Boolean(maybeIndexed && maybeIndexed[IS_INDEXED_SYMBOL]); +} + +function isAssociative(maybeAssociative) { + return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); +} + +var Collection = function Collection(value) { + // eslint-disable-next-line no-constructor-return + return isCollection(value) ? value : Seq(value); +}; + +var KeyedCollection = /*@__PURE__*/(function (Collection) { + function KeyedCollection(value) { + // eslint-disable-next-line no-constructor-return + return isKeyed(value) ? value : KeyedSeq(value); + } + + if ( Collection ) KeyedCollection.__proto__ = Collection; + KeyedCollection.prototype = Object.create( Collection && Collection.prototype ); + KeyedCollection.prototype.constructor = KeyedCollection; + + return KeyedCollection; +}(Collection)); + +var IndexedCollection = /*@__PURE__*/(function (Collection) { + function IndexedCollection(value) { + // eslint-disable-next-line no-constructor-return + return isIndexed(value) ? value : IndexedSeq(value); + } + + if ( Collection ) IndexedCollection.__proto__ = Collection; + IndexedCollection.prototype = Object.create( Collection && Collection.prototype ); + IndexedCollection.prototype.constructor = IndexedCollection; + + return IndexedCollection; +}(Collection)); + +var SetCollection = /*@__PURE__*/(function (Collection) { + function SetCollection(value) { + // eslint-disable-next-line no-constructor-return + return isCollection(value) && !isAssociative(value) ? value : SetSeq(value); + } + + if ( Collection ) SetCollection.__proto__ = Collection; + SetCollection.prototype = Object.create( Collection && Collection.prototype ); + SetCollection.prototype.constructor = SetCollection; + + return SetCollection; +}(Collection)); + +Collection.Keyed = KeyedCollection; +Collection.Indexed = IndexedCollection; +Collection.Set = SetCollection; + +var IS_SEQ_SYMBOL = '@@__IMMUTABLE_SEQ__@@'; + +function isSeq(maybeSeq) { + return Boolean(maybeSeq && maybeSeq[IS_SEQ_SYMBOL]); +} + +var IS_RECORD_SYMBOL = '@@__IMMUTABLE_RECORD__@@'; + +function isRecord(maybeRecord) { + return Boolean(maybeRecord && maybeRecord[IS_RECORD_SYMBOL]); +} + +function isImmutable(maybeImmutable) { + return isCollection(maybeImmutable) || isRecord(maybeImmutable); +} + +var IS_ORDERED_SYMBOL = '@@__IMMUTABLE_ORDERED__@@'; + +function isOrdered(maybeOrdered) { + return Boolean(maybeOrdered && maybeOrdered[IS_ORDERED_SYMBOL]); +} + +var ITERATE_KEYS = 0; +var ITERATE_VALUES = 1; +var ITERATE_ENTRIES = 2; + +var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; +var FAUX_ITERATOR_SYMBOL = '@@iterator'; + +var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; + +var Iterator = function Iterator(next) { + this.next = next; +}; + +Iterator.prototype.toString = function toString () { + return '[Iterator]'; +}; + +Iterator.KEYS = ITERATE_KEYS; +Iterator.VALUES = ITERATE_VALUES; +Iterator.ENTRIES = ITERATE_ENTRIES; + +Iterator.prototype.inspect = Iterator.prototype.toSource = function () { + return this.toString(); +}; +Iterator.prototype[ITERATOR_SYMBOL] = function () { + return this; +}; + +function iteratorValue(type, k, v, iteratorResult) { + var value = type === 0 ? k : type === 1 ? v : [k, v]; + iteratorResult + ? (iteratorResult.value = value) + : (iteratorResult = { + value: value, + done: false, + }); + return iteratorResult; +} + +function iteratorDone() { + return { value: undefined, done: true }; +} + +function hasIterator(maybeIterable) { + if (Array.isArray(maybeIterable)) { + // IE11 trick as it does not support `Symbol.iterator` + return true; + } + + return !!getIteratorFn(maybeIterable); +} + +function isIterator(maybeIterator) { + return maybeIterator && typeof maybeIterator.next === 'function'; +} + +function getIterator(iterable) { + var iteratorFn = getIteratorFn(iterable); + return iteratorFn && iteratorFn.call(iterable); +} + +function getIteratorFn(iterable) { + var iteratorFn = + iterable && + ((REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || + iterable[FAUX_ITERATOR_SYMBOL]); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } +} + +function isEntriesIterable(maybeIterable) { + var iteratorFn = getIteratorFn(maybeIterable); + return iteratorFn && iteratorFn === maybeIterable.entries; +} + +function isKeysIterable(maybeIterable) { + var iteratorFn = getIteratorFn(maybeIterable); + return iteratorFn && iteratorFn === maybeIterable.keys; +} + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +function isArrayLike(value) { + if (Array.isArray(value) || typeof value === 'string') { + return true; + } + + return ( + value && + typeof value === 'object' && + Number.isInteger(value.length) && + value.length >= 0 && + (value.length === 0 + ? // Only {length: 0} is considered Array-like. + Object.keys(value).length === 1 + : // An object is only Array-like if it has a property where the last value + // in the array-like may be found (which could be undefined). + value.hasOwnProperty(value.length - 1)) + ); +} + +var Seq = /*@__PURE__*/(function (Collection) { + function Seq(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySequence() + : isImmutable(value) + ? value.toSeq() + : seqFromValue(value); + } + + if ( Collection ) Seq.__proto__ = Collection; + Seq.prototype = Object.create( Collection && Collection.prototype ); + Seq.prototype.constructor = Seq; + + Seq.prototype.toSeq = function toSeq () { + return this; + }; + + Seq.prototype.toString = function toString () { + return this.__toString('Seq {', '}'); + }; + + Seq.prototype.cacheResult = function cacheResult () { + if (!this._cache && this.__iterateUncached) { + this._cache = this.entrySeq().toArray(); + this.size = this._cache.length; + } + return this; + }; + + // abstract __iterateUncached(fn, reverse) + + Seq.prototype.__iterate = function __iterate (fn, reverse) { + var cache = this._cache; + if (cache) { + var size = cache.length; + var i = 0; + while (i !== size) { + var entry = cache[reverse ? size - ++i : i++]; + if (fn(entry[1], entry[0], this) === false) { + break; + } + } + return i; + } + return this.__iterateUncached(fn, reverse); + }; + + // abstract __iteratorUncached(type, reverse) + + Seq.prototype.__iterator = function __iterator (type, reverse) { + var cache = this._cache; + if (cache) { + var size = cache.length; + var i = 0; + return new Iterator(function () { + if (i === size) { + return iteratorDone(); + } + var entry = cache[reverse ? size - ++i : i++]; + return iteratorValue(type, entry[0], entry[1]); + }); + } + return this.__iteratorUncached(type, reverse); + }; + + return Seq; +}(Collection)); + +var KeyedSeq = /*@__PURE__*/(function (Seq) { + function KeyedSeq(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySequence().toKeyedSeq() + : isCollection(value) + ? isKeyed(value) + ? value.toSeq() + : value.fromEntrySeq() + : isRecord(value) + ? value.toSeq() + : keyedSeqFromValue(value); + } + + if ( Seq ) KeyedSeq.__proto__ = Seq; + KeyedSeq.prototype = Object.create( Seq && Seq.prototype ); + KeyedSeq.prototype.constructor = KeyedSeq; + + KeyedSeq.prototype.toKeyedSeq = function toKeyedSeq () { + return this; + }; + + return KeyedSeq; +}(Seq)); + +var IndexedSeq = /*@__PURE__*/(function (Seq) { + function IndexedSeq(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySequence() + : isCollection(value) + ? isKeyed(value) + ? value.entrySeq() + : value.toIndexedSeq() + : isRecord(value) + ? value.toSeq().entrySeq() + : indexedSeqFromValue(value); + } + + if ( Seq ) IndexedSeq.__proto__ = Seq; + IndexedSeq.prototype = Object.create( Seq && Seq.prototype ); + IndexedSeq.prototype.constructor = IndexedSeq; + + IndexedSeq.of = function of (/*...values*/) { + return IndexedSeq(arguments); + }; + + IndexedSeq.prototype.toIndexedSeq = function toIndexedSeq () { + return this; + }; + + IndexedSeq.prototype.toString = function toString () { + return this.__toString('Seq [', ']'); + }; + + return IndexedSeq; +}(Seq)); + +var SetSeq = /*@__PURE__*/(function (Seq) { + function SetSeq(value) { + // eslint-disable-next-line no-constructor-return + return ( + isCollection(value) && !isAssociative(value) ? value : IndexedSeq(value) + ).toSetSeq(); + } + + if ( Seq ) SetSeq.__proto__ = Seq; + SetSeq.prototype = Object.create( Seq && Seq.prototype ); + SetSeq.prototype.constructor = SetSeq; + + SetSeq.of = function of (/*...values*/) { + return SetSeq(arguments); + }; + + SetSeq.prototype.toSetSeq = function toSetSeq () { + return this; + }; + + return SetSeq; +}(Seq)); + +Seq.isSeq = isSeq; +Seq.Keyed = KeyedSeq; +Seq.Set = SetSeq; +Seq.Indexed = IndexedSeq; + +Seq.prototype[IS_SEQ_SYMBOL] = true; + +// #pragma Root Sequences + +var ArraySeq = /*@__PURE__*/(function (IndexedSeq) { + function ArraySeq(array) { + this._array = array; + this.size = array.length; + } + + if ( IndexedSeq ) ArraySeq.__proto__ = IndexedSeq; + ArraySeq.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); + ArraySeq.prototype.constructor = ArraySeq; + + ArraySeq.prototype.get = function get (index, notSetValue) { + return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; + }; + + ArraySeq.prototype.__iterate = function __iterate (fn, reverse) { + var array = this._array; + var size = array.length; + var i = 0; + while (i !== size) { + var ii = reverse ? size - ++i : i++; + if (fn(array[ii], ii, this) === false) { + break; + } + } + return i; + }; + + ArraySeq.prototype.__iterator = function __iterator (type, reverse) { + var array = this._array; + var size = array.length; + var i = 0; + return new Iterator(function () { + if (i === size) { + return iteratorDone(); + } + var ii = reverse ? size - ++i : i++; + return iteratorValue(type, ii, array[ii]); + }); + }; + + return ArraySeq; +}(IndexedSeq)); + +var ObjectSeq = /*@__PURE__*/(function (KeyedSeq) { + function ObjectSeq(object) { + var keys = Object.keys(object).concat( + Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : [] + ); + this._object = object; + this._keys = keys; + this.size = keys.length; + } + + if ( KeyedSeq ) ObjectSeq.__proto__ = KeyedSeq; + ObjectSeq.prototype = Object.create( KeyedSeq && KeyedSeq.prototype ); + ObjectSeq.prototype.constructor = ObjectSeq; + + ObjectSeq.prototype.get = function get (key, notSetValue) { + if (notSetValue !== undefined && !this.has(key)) { + return notSetValue; + } + return this._object[key]; + }; + + ObjectSeq.prototype.has = function has (key) { + return hasOwnProperty.call(this._object, key); + }; + + ObjectSeq.prototype.__iterate = function __iterate (fn, reverse) { + var object = this._object; + var keys = this._keys; + var size = keys.length; + var i = 0; + while (i !== size) { + var key = keys[reverse ? size - ++i : i++]; + if (fn(object[key], key, this) === false) { + break; + } + } + return i; + }; + + ObjectSeq.prototype.__iterator = function __iterator (type, reverse) { + var object = this._object; + var keys = this._keys; + var size = keys.length; + var i = 0; + return new Iterator(function () { + if (i === size) { + return iteratorDone(); + } + var key = keys[reverse ? size - ++i : i++]; + return iteratorValue(type, key, object[key]); + }); + }; + + return ObjectSeq; +}(KeyedSeq)); +ObjectSeq.prototype[IS_ORDERED_SYMBOL] = true; + +var CollectionSeq = /*@__PURE__*/(function (IndexedSeq) { + function CollectionSeq(collection) { + this._collection = collection; + this.size = collection.length || collection.size; + } + + if ( IndexedSeq ) CollectionSeq.__proto__ = IndexedSeq; + CollectionSeq.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); + CollectionSeq.prototype.constructor = CollectionSeq; + + CollectionSeq.prototype.__iterateUncached = function __iterateUncached (fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var collection = this._collection; + var iterator = getIterator(collection); + var iterations = 0; + if (isIterator(iterator)) { + var step; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; + } + } + } + return iterations; + }; + + CollectionSeq.prototype.__iteratorUncached = function __iteratorUncached (type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var collection = this._collection; + var iterator = getIterator(collection); + if (!isIterator(iterator)) { + return new Iterator(iteratorDone); + } + var iterations = 0; + return new Iterator(function () { + var step = iterator.next(); + return step.done ? step : iteratorValue(type, iterations++, step.value); + }); + }; + + return CollectionSeq; +}(IndexedSeq)); + +// # pragma Helper functions + +var EMPTY_SEQ; + +function emptySequence() { + return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); +} + +function keyedSeqFromValue(value) { + var seq = maybeIndexedSeqFromValue(value); + if (seq) { + return seq.fromEntrySeq(); + } + if (typeof value === 'object') { + return new ObjectSeq(value); + } + throw new TypeError( + 'Expected Array or collection object of [k, v] entries, or keyed object: ' + + value + ); +} + +function indexedSeqFromValue(value) { + var seq = maybeIndexedSeqFromValue(value); + if (seq) { + return seq; + } + throw new TypeError( + 'Expected Array or collection object of values: ' + value + ); +} + +function seqFromValue(value) { + var seq = maybeIndexedSeqFromValue(value); + if (seq) { + return isEntriesIterable(value) + ? seq.fromEntrySeq() + : isKeysIterable(value) + ? seq.toSetSeq() + : seq; + } + if (typeof value === 'object') { + return new ObjectSeq(value); + } + throw new TypeError( + 'Expected Array or collection object of values, or keyed object: ' + value + ); +} + +function maybeIndexedSeqFromValue(value) { + return isArrayLike(value) + ? new ArraySeq(value) + : hasIterator(value) + ? new CollectionSeq(value) + : undefined; +} + +var IS_MAP_SYMBOL = '@@__IMMUTABLE_MAP__@@'; + +function isMap(maybeMap) { + return Boolean(maybeMap && maybeMap[IS_MAP_SYMBOL]); +} + +function isOrderedMap(maybeOrderedMap) { + return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); +} + +function isValueObject(maybeValue) { + return Boolean( + maybeValue && + typeof maybeValue.equals === 'function' && + typeof maybeValue.hashCode === 'function' + ); +} + +/** + * An extension of the "same-value" algorithm as [described for use by ES6 Map + * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) + * + * NaN is considered the same as NaN, however -0 and 0 are considered the same + * value, which is different from the algorithm described by + * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). + * + * This is extended further to allow Objects to describe the values they + * represent, by way of `valueOf` or `equals` (and `hashCode`). + * + * Note: because of this extension, the key equality of Immutable.Map and the + * value equality of Immutable.Set will differ from ES6 Map and Set. + * + * ### Defining custom values + * + * The easiest way to describe the value an object represents is by implementing + * `valueOf`. For example, `Date` represents a value by returning a unix + * timestamp for `valueOf`: + * + * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... + * var date2 = new Date(1234567890000); + * date1.valueOf(); // 1234567890000 + * assert( date1 !== date2 ); + * assert( Immutable.is( date1, date2 ) ); + * + * Note: overriding `valueOf` may have other implications if you use this object + * where JavaScript expects a primitive, such as implicit string coercion. + * + * For more complex types, especially collections, implementing `valueOf` may + * not be performant. An alternative is to implement `equals` and `hashCode`. + * + * `equals` takes another object, presumably of similar type, and returns true + * if it is equal. Equality is symmetrical, so the same result should be + * returned if this and the argument are flipped. + * + * assert( a.equals(b) === b.equals(a) ); + * + * `hashCode` returns a 32bit integer number representing the object which will + * be used to determine how to store the value object in a Map or Set. You must + * provide both or neither methods, one must not exist without the other. + * + * Also, an important relationship between these methods must be upheld: if two + * values are equal, they *must* return the same hashCode. If the values are not + * equal, they might have the same hashCode; this is called a hash collision, + * and while undesirable for performance reasons, it is acceptable. + * + * if (a.equals(b)) { + * assert( a.hashCode() === b.hashCode() ); + * } + * + * All Immutable collections are Value Objects: they implement `equals()` + * and `hashCode()`. + */ +function is(valueA, valueB) { + if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { + return true; + } + if (!valueA || !valueB) { + return false; + } + if ( + typeof valueA.valueOf === 'function' && + typeof valueB.valueOf === 'function' + ) { + valueA = valueA.valueOf(); + valueB = valueB.valueOf(); + if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { + return true; + } + if (!valueA || !valueB) { + return false; + } + } + return !!( + isValueObject(valueA) && + isValueObject(valueB) && + valueA.equals(valueB) + ); +} + +var imul = + typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 + ? Math.imul + : function imul(a, b) { + a |= 0; // int + b |= 0; // int + var c = a & 0xffff; + var d = b & 0xffff; + // Shift by 0 fixes the sign on the high part. + return (c * d + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0)) | 0; // int + }; + +// v8 has an optimization for storing 31-bit signed numbers. +// Values which have either 00 or 11 as the high order bits qualify. +// This function drops the highest order bit in a signed number, maintaining +// the sign bit. +function smi(i32) { + return ((i32 >>> 1) & 0x40000000) | (i32 & 0xbfffffff); +} + +var defaultValueOf = Object.prototype.valueOf; + +function hash(o) { + if (o == null) { + return hashNullish(o); + } + + if (typeof o.hashCode === 'function') { + // Drop any high bits from accidentally long hash codes. + return smi(o.hashCode(o)); + } + + var v = valueOf(o); + + if (v == null) { + return hashNullish(v); + } + + switch (typeof v) { + case 'boolean': + // The hash values for built-in constants are a 1 value for each 5-byte + // shift region expect for the first, which encodes the value. This + // reduces the odds of a hash collision for these common values. + return v ? 0x42108421 : 0x42108420; + case 'number': + return hashNumber(v); + case 'string': + return v.length > STRING_HASH_CACHE_MIN_STRLEN + ? cachedHashString(v) + : hashString(v); + case 'object': + case 'function': + return hashJSObj(v); + case 'symbol': + return hashSymbol(v); + default: + if (typeof v.toString === 'function') { + return hashString(v.toString()); + } + throw new Error('Value type ' + typeof v + ' cannot be hashed.'); + } +} + +function hashNullish(nullish) { + return nullish === null ? 0x42108422 : /* undefined */ 0x42108423; +} + +// Compress arbitrarily large numbers into smi hashes. +function hashNumber(n) { + if (n !== n || n === Infinity) { + return 0; + } + var hash = n | 0; + if (hash !== n) { + hash ^= n * 0xffffffff; + } + while (n > 0xffffffff) { + n /= 0xffffffff; + hash ^= n; + } + return smi(hash); +} + +function cachedHashString(string) { + var hashed = stringHashCache[string]; + if (hashed === undefined) { + hashed = hashString(string); + if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { + STRING_HASH_CACHE_SIZE = 0; + stringHashCache = {}; + } + STRING_HASH_CACHE_SIZE++; + stringHashCache[string] = hashed; + } + return hashed; +} + +// http://jsperf.com/hashing-strings +function hashString(string) { + // This is the hash from JVM + // The hash code for a string is computed as + // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], + // where s[i] is the ith character of the string and n is the length of + // the string. We "mod" the result to make it between 0 (inclusive) and 2^31 + // (exclusive) by dropping high bits. + var hashed = 0; + for (var ii = 0; ii < string.length; ii++) { + hashed = (31 * hashed + string.charCodeAt(ii)) | 0; + } + return smi(hashed); +} + +function hashSymbol(sym) { + var hashed = symbolMap[sym]; + if (hashed !== undefined) { + return hashed; + } + + hashed = nextHash(); + + symbolMap[sym] = hashed; + + return hashed; +} + +function hashJSObj(obj) { + var hashed; + if (usingWeakMap) { + hashed = weakMap.get(obj); + if (hashed !== undefined) { + return hashed; + } + } + + hashed = obj[UID_HASH_KEY]; + if (hashed !== undefined) { + return hashed; + } + + if (!canDefineProperty) { + hashed = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; + if (hashed !== undefined) { + return hashed; + } + + hashed = getIENodeHash(obj); + if (hashed !== undefined) { + return hashed; + } + } + + hashed = nextHash(); + + if (usingWeakMap) { + weakMap.set(obj, hashed); + } else if (isExtensible !== undefined && isExtensible(obj) === false) { + throw new Error('Non-extensible objects are not allowed as keys.'); + } else if (canDefineProperty) { + Object.defineProperty(obj, UID_HASH_KEY, { + enumerable: false, + configurable: false, + writable: false, + value: hashed, + }); + } else if ( + obj.propertyIsEnumerable !== undefined && + obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable + ) { + // Since we can't define a non-enumerable property on the object + // we'll hijack one of the less-used non-enumerable properties to + // save our hash on it. Since this is a function it will not show up in + // `JSON.stringify` which is what we want. + obj.propertyIsEnumerable = function () { + return this.constructor.prototype.propertyIsEnumerable.apply( + this, + arguments + ); + }; + obj.propertyIsEnumerable[UID_HASH_KEY] = hashed; + } else if (obj.nodeType !== undefined) { + // At this point we couldn't get the IE `uniqueID` to use as a hash + // and we couldn't use a non-enumerable property to exploit the + // dontEnum bug so we simply add the `UID_HASH_KEY` on the node + // itself. + obj[UID_HASH_KEY] = hashed; + } else { + throw new Error('Unable to set a non-enumerable property on object.'); + } + + return hashed; +} + +// Get references to ES5 object methods. +var isExtensible = Object.isExtensible; + +// True if Object.defineProperty works as expected. IE8 fails this test. +var canDefineProperty = (function () { + try { + Object.defineProperty({}, '@', {}); + return true; + } catch (e) { + return false; + } +})(); + +// IE has a `uniqueID` property on DOM nodes. We can construct the hash from it +// and avoid memory leaks from the IE cloneNode bug. +function getIENodeHash(node) { + if (node && node.nodeType > 0) { + switch (node.nodeType) { + case 1: // Element + return node.uniqueID; + case 9: // Document + return node.documentElement && node.documentElement.uniqueID; + } + } +} + +function valueOf(obj) { + return obj.valueOf !== defaultValueOf && typeof obj.valueOf === 'function' + ? obj.valueOf(obj) + : obj; +} + +function nextHash() { + var nextHash = ++_objHashUID; + if (_objHashUID & 0x40000000) { + _objHashUID = 0; + } + return nextHash; +} + +// If possible, use a WeakMap. +var usingWeakMap = typeof WeakMap === 'function'; +var weakMap; +if (usingWeakMap) { + weakMap = new WeakMap(); +} + +var symbolMap = Object.create(null); + +var _objHashUID = 0; + +var UID_HASH_KEY = '__immutablehash__'; +if (typeof Symbol === 'function') { + UID_HASH_KEY = Symbol(UID_HASH_KEY); +} + +var STRING_HASH_CACHE_MIN_STRLEN = 16; +var STRING_HASH_CACHE_MAX_SIZE = 255; +var STRING_HASH_CACHE_SIZE = 0; +var stringHashCache = {}; + +var ToKeyedSequence = /*@__PURE__*/(function (KeyedSeq) { + function ToKeyedSequence(indexed, useKeys) { + this._iter = indexed; + this._useKeys = useKeys; + this.size = indexed.size; + } + + if ( KeyedSeq ) ToKeyedSequence.__proto__ = KeyedSeq; + ToKeyedSequence.prototype = Object.create( KeyedSeq && KeyedSeq.prototype ); + ToKeyedSequence.prototype.constructor = ToKeyedSequence; + + ToKeyedSequence.prototype.get = function get (key, notSetValue) { + return this._iter.get(key, notSetValue); + }; + + ToKeyedSequence.prototype.has = function has (key) { + return this._iter.has(key); + }; + + ToKeyedSequence.prototype.valueSeq = function valueSeq () { + return this._iter.valueSeq(); + }; + + ToKeyedSequence.prototype.reverse = function reverse () { + var this$1$1 = this; + + var reversedSequence = reverseFactory(this, true); + if (!this._useKeys) { + reversedSequence.valueSeq = function () { return this$1$1._iter.toSeq().reverse(); }; + } + return reversedSequence; + }; + + ToKeyedSequence.prototype.map = function map (mapper, context) { + var this$1$1 = this; + + var mappedSequence = mapFactory(this, mapper, context); + if (!this._useKeys) { + mappedSequence.valueSeq = function () { return this$1$1._iter.toSeq().map(mapper, context); }; + } + return mappedSequence; + }; + + ToKeyedSequence.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + return this._iter.__iterate(function (v, k) { return fn(v, k, this$1$1); }, reverse); + }; + + ToKeyedSequence.prototype.__iterator = function __iterator (type, reverse) { + return this._iter.__iterator(type, reverse); + }; + + return ToKeyedSequence; +}(KeyedSeq)); +ToKeyedSequence.prototype[IS_ORDERED_SYMBOL] = true; + +var ToIndexedSequence = /*@__PURE__*/(function (IndexedSeq) { + function ToIndexedSequence(iter) { + this._iter = iter; + this.size = iter.size; + } + + if ( IndexedSeq ) ToIndexedSequence.__proto__ = IndexedSeq; + ToIndexedSequence.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); + ToIndexedSequence.prototype.constructor = ToIndexedSequence; + + ToIndexedSequence.prototype.includes = function includes (value) { + return this._iter.includes(value); + }; + + ToIndexedSequence.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + var i = 0; + reverse && ensureSize(this); + return this._iter.__iterate( + function (v) { return fn(v, reverse ? this$1$1.size - ++i : i++, this$1$1); }, + reverse + ); + }; + + ToIndexedSequence.prototype.__iterator = function __iterator (type, reverse) { + var this$1$1 = this; + + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + var i = 0; + reverse && ensureSize(this); + return new Iterator(function () { + var step = iterator.next(); + return step.done + ? step + : iteratorValue( + type, + reverse ? this$1$1.size - ++i : i++, + step.value, + step + ); + }); + }; + + return ToIndexedSequence; +}(IndexedSeq)); + +var ToSetSequence = /*@__PURE__*/(function (SetSeq) { + function ToSetSequence(iter) { + this._iter = iter; + this.size = iter.size; + } + + if ( SetSeq ) ToSetSequence.__proto__ = SetSeq; + ToSetSequence.prototype = Object.create( SetSeq && SetSeq.prototype ); + ToSetSequence.prototype.constructor = ToSetSequence; + + ToSetSequence.prototype.has = function has (key) { + return this._iter.includes(key); + }; + + ToSetSequence.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + return this._iter.__iterate(function (v) { return fn(v, v, this$1$1); }, reverse); + }; + + ToSetSequence.prototype.__iterator = function __iterator (type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(function () { + var step = iterator.next(); + return step.done + ? step + : iteratorValue(type, step.value, step.value, step); + }); + }; + + return ToSetSequence; +}(SetSeq)); + +var FromEntriesSequence = /*@__PURE__*/(function (KeyedSeq) { + function FromEntriesSequence(entries) { + this._iter = entries; + this.size = entries.size; + } + + if ( KeyedSeq ) FromEntriesSequence.__proto__ = KeyedSeq; + FromEntriesSequence.prototype = Object.create( KeyedSeq && KeyedSeq.prototype ); + FromEntriesSequence.prototype.constructor = FromEntriesSequence; + + FromEntriesSequence.prototype.entrySeq = function entrySeq () { + return this._iter.toSeq(); + }; + + FromEntriesSequence.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + return this._iter.__iterate(function (entry) { + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + var indexedCollection = isCollection(entry); + return fn( + indexedCollection ? entry.get(1) : entry[1], + indexedCollection ? entry.get(0) : entry[0], + this$1$1 + ); + } + }, reverse); + }; + + FromEntriesSequence.prototype.__iterator = function __iterator (type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(function () { + while (true) { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + var indexedCollection = isCollection(entry); + return iteratorValue( + type, + indexedCollection ? entry.get(0) : entry[0], + indexedCollection ? entry.get(1) : entry[1], + step + ); + } + } + }); + }; + + return FromEntriesSequence; +}(KeyedSeq)); + +ToIndexedSequence.prototype.cacheResult = + ToKeyedSequence.prototype.cacheResult = + ToSetSequence.prototype.cacheResult = + FromEntriesSequence.prototype.cacheResult = + cacheResultThrough; + +function flipFactory(collection) { + var flipSequence = makeSequence(collection); + flipSequence._iter = collection; + flipSequence.size = collection.size; + flipSequence.flip = function () { return collection; }; + flipSequence.reverse = function () { + var reversedSequence = collection.reverse.apply(this); // super.reverse() + reversedSequence.flip = function () { return collection.reverse(); }; + return reversedSequence; + }; + flipSequence.has = function (key) { return collection.includes(key); }; + flipSequence.includes = function (key) { return collection.has(key); }; + flipSequence.cacheResult = cacheResultThrough; + flipSequence.__iterateUncached = function (fn, reverse) { + var this$1$1 = this; + + return collection.__iterate(function (v, k) { return fn(k, v, this$1$1) !== false; }, reverse); + }; + flipSequence.__iteratorUncached = function (type, reverse) { + if (type === ITERATE_ENTRIES) { + var iterator = collection.__iterator(type, reverse); + return new Iterator(function () { + var step = iterator.next(); + if (!step.done) { + var k = step.value[0]; + step.value[0] = step.value[1]; + step.value[1] = k; + } + return step; + }); + } + return collection.__iterator( + type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, + reverse + ); + }; + return flipSequence; +} + +function mapFactory(collection, mapper, context) { + var mappedSequence = makeSequence(collection); + mappedSequence.size = collection.size; + mappedSequence.has = function (key) { return collection.has(key); }; + mappedSequence.get = function (key, notSetValue) { + var v = collection.get(key, NOT_SET); + return v === NOT_SET + ? notSetValue + : mapper.call(context, v, key, collection); + }; + mappedSequence.__iterateUncached = function (fn, reverse) { + var this$1$1 = this; + + return collection.__iterate( + function (v, k, c) { return fn(mapper.call(context, v, k, c), k, this$1$1) !== false; }, + reverse + ); + }; + mappedSequence.__iteratorUncached = function (type, reverse) { + var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + return new Iterator(function () { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + var key = entry[0]; + return iteratorValue( + type, + key, + mapper.call(context, entry[1], key, collection), + step + ); + }); + }; + return mappedSequence; +} + +function reverseFactory(collection, useKeys) { + var this$1$1 = this; + + var reversedSequence = makeSequence(collection); + reversedSequence._iter = collection; + reversedSequence.size = collection.size; + reversedSequence.reverse = function () { return collection; }; + if (collection.flip) { + reversedSequence.flip = function () { + var flipSequence = flipFactory(collection); + flipSequence.reverse = function () { return collection.flip(); }; + return flipSequence; + }; + } + reversedSequence.get = function (key, notSetValue) { return collection.get(useKeys ? key : -1 - key, notSetValue); }; + reversedSequence.has = function (key) { return collection.has(useKeys ? key : -1 - key); }; + reversedSequence.includes = function (value) { return collection.includes(value); }; + reversedSequence.cacheResult = cacheResultThrough; + reversedSequence.__iterate = function (fn, reverse) { + var this$1$1 = this; + + var i = 0; + reverse && ensureSize(collection); + return collection.__iterate( + function (v, k) { return fn(v, useKeys ? k : reverse ? this$1$1.size - ++i : i++, this$1$1); }, + !reverse + ); + }; + reversedSequence.__iterator = function (type, reverse) { + var i = 0; + reverse && ensureSize(collection); + var iterator = collection.__iterator(ITERATE_ENTRIES, !reverse); + return new Iterator(function () { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + return iteratorValue( + type, + useKeys ? entry[0] : reverse ? this$1$1.size - ++i : i++, + entry[1], + step + ); + }); + }; + return reversedSequence; +} + +function filterFactory(collection, predicate, context, useKeys) { + var filterSequence = makeSequence(collection); + if (useKeys) { + filterSequence.has = function (key) { + var v = collection.get(key, NOT_SET); + return v !== NOT_SET && !!predicate.call(context, v, key, collection); + }; + filterSequence.get = function (key, notSetValue) { + var v = collection.get(key, NOT_SET); + return v !== NOT_SET && predicate.call(context, v, key, collection) + ? v + : notSetValue; + }; + } + filterSequence.__iterateUncached = function (fn, reverse) { + var this$1$1 = this; + + var iterations = 0; + collection.__iterate(function (v, k, c) { + if (predicate.call(context, v, k, c)) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$1$1); + } + }, reverse); + return iterations; + }; + filterSequence.__iteratorUncached = function (type, reverse) { + var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + var iterations = 0; + return new Iterator(function () { + while (true) { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + var key = entry[0]; + var value = entry[1]; + if (predicate.call(context, value, key, collection)) { + return iteratorValue(type, useKeys ? key : iterations++, value, step); + } + } + }); + }; + return filterSequence; +} + +function countByFactory(collection, grouper, context) { + var groups = Map().asMutable(); + collection.__iterate(function (v, k) { + groups.update(grouper.call(context, v, k, collection), 0, function (a) { return a + 1; }); + }); + return groups.asImmutable(); +} + +function groupByFactory(collection, grouper, context) { + var isKeyedIter = isKeyed(collection); + var groups = (isOrdered(collection) ? OrderedMap() : Map()).asMutable(); + collection.__iterate(function (v, k) { + groups.update( + grouper.call(context, v, k, collection), + function (a) { return ((a = a || []), a.push(isKeyedIter ? [k, v] : v), a); } + ); + }); + var coerce = collectionClass(collection); + return groups.map(function (arr) { return reify(collection, coerce(arr)); }).asImmutable(); +} + +function partitionFactory(collection, predicate, context) { + var isKeyedIter = isKeyed(collection); + var groups = [[], []]; + collection.__iterate(function (v, k) { + groups[predicate.call(context, v, k, collection) ? 1 : 0].push( + isKeyedIter ? [k, v] : v + ); + }); + var coerce = collectionClass(collection); + return groups.map(function (arr) { return reify(collection, coerce(arr)); }); +} + +function sliceFactory(collection, begin, end, useKeys) { + var originalSize = collection.size; + + if (wholeSlice(begin, end, originalSize)) { + return collection; + } + + // begin or end can not be resolved if they were provided as negative numbers and + // this collection's size is unknown. In that case, cache first so there is + // a known size and these do not resolve to NaN. + if (typeof originalSize === 'undefined' && (begin < 0 || end < 0)) { + return sliceFactory(collection.toSeq().cacheResult(), begin, end, useKeys); + } + + var resolvedBegin = resolveBegin(begin, originalSize); + var resolvedEnd = resolveEnd(end, originalSize); + + // Note: resolvedEnd is undefined when the original sequence's length is + // unknown and this slice did not supply an end and should contain all + // elements after resolvedBegin. + // In that case, resolvedSize will be NaN and sliceSize will remain undefined. + var resolvedSize = resolvedEnd - resolvedBegin; + var sliceSize; + if (resolvedSize === resolvedSize) { + sliceSize = resolvedSize < 0 ? 0 : resolvedSize; + } + + var sliceSeq = makeSequence(collection); + + // If collection.size is undefined, the size of the realized sliceSeq is + // unknown at this point unless the number of items to slice is 0 + sliceSeq.size = + sliceSize === 0 ? sliceSize : (collection.size && sliceSize) || undefined; + + if (!useKeys && isSeq(collection) && sliceSize >= 0) { + sliceSeq.get = function (index, notSetValue) { + index = wrapIndex(this, index); + return index >= 0 && index < sliceSize + ? collection.get(index + resolvedBegin, notSetValue) + : notSetValue; + }; + } + + sliceSeq.__iterateUncached = function (fn, reverse) { + var this$1$1 = this; + + if (sliceSize === 0) { + return 0; + } + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var skipped = 0; + var isSkipping = true; + var iterations = 0; + collection.__iterate(function (v, k) { + if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { + iterations++; + return ( + fn(v, useKeys ? k : iterations - 1, this$1$1) !== false && + iterations !== sliceSize + ); + } + }); + return iterations; + }; + + sliceSeq.__iteratorUncached = function (type, reverse) { + if (sliceSize !== 0 && reverse) { + return this.cacheResult().__iterator(type, reverse); + } + // Don't bother instantiating parent iterator if taking 0. + if (sliceSize === 0) { + return new Iterator(iteratorDone); + } + var iterator = collection.__iterator(type, reverse); + var skipped = 0; + var iterations = 0; + return new Iterator(function () { + while (skipped++ < resolvedBegin) { + iterator.next(); + } + if (++iterations > sliceSize) { + return iteratorDone(); + } + var step = iterator.next(); + if (useKeys || type === ITERATE_VALUES || step.done) { + return step; + } + if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations - 1, undefined, step); + } + return iteratorValue(type, iterations - 1, step.value[1], step); + }); + }; + + return sliceSeq; +} + +function takeWhileFactory(collection, predicate, context) { + var takeSequence = makeSequence(collection); + takeSequence.__iterateUncached = function (fn, reverse) { + var this$1$1 = this; + + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var iterations = 0; + collection.__iterate( + function (v, k, c) { return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$1$1); } + ); + return iterations; + }; + takeSequence.__iteratorUncached = function (type, reverse) { + var this$1$1 = this; + + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + var iterating = true; + return new Iterator(function () { + if (!iterating) { + return iteratorDone(); + } + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + var k = entry[0]; + var v = entry[1]; + if (!predicate.call(context, v, k, this$1$1)) { + iterating = false; + return iteratorDone(); + } + return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); + }); + }; + return takeSequence; +} + +function skipWhileFactory(collection, predicate, context, useKeys) { + var skipSequence = makeSequence(collection); + skipSequence.__iterateUncached = function (fn, reverse) { + var this$1$1 = this; + + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var isSkipping = true; + var iterations = 0; + collection.__iterate(function (v, k, c) { + if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$1$1); + } + }); + return iterations; + }; + skipSequence.__iteratorUncached = function (type, reverse) { + var this$1$1 = this; + + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); + var skipping = true; + var iterations = 0; + return new Iterator(function () { + var step; + var k; + var v; + do { + step = iterator.next(); + if (step.done) { + if (useKeys || type === ITERATE_VALUES) { + return step; + } + if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations++, undefined, step); + } + return iteratorValue(type, iterations++, step.value[1], step); + } + var entry = step.value; + k = entry[0]; + v = entry[1]; + skipping && (skipping = predicate.call(context, v, k, this$1$1)); + } while (skipping); + return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); + }); + }; + return skipSequence; +} + +function concatFactory(collection, values) { + var isKeyedCollection = isKeyed(collection); + var iters = [collection] + .concat(values) + .map(function (v) { + if (!isCollection(v)) { + v = isKeyedCollection + ? keyedSeqFromValue(v) + : indexedSeqFromValue(Array.isArray(v) ? v : [v]); + } else if (isKeyedCollection) { + v = KeyedCollection(v); + } + return v; + }) + .filter(function (v) { return v.size !== 0; }); + + if (iters.length === 0) { + return collection; + } + + if (iters.length === 1) { + var singleton = iters[0]; + if ( + singleton === collection || + (isKeyedCollection && isKeyed(singleton)) || + (isIndexed(collection) && isIndexed(singleton)) + ) { + return singleton; + } + } + + var concatSeq = new ArraySeq(iters); + if (isKeyedCollection) { + concatSeq = concatSeq.toKeyedSeq(); + } else if (!isIndexed(collection)) { + concatSeq = concatSeq.toSetSeq(); + } + concatSeq = concatSeq.flatten(true); + concatSeq.size = iters.reduce(function (sum, seq) { + if (sum !== undefined) { + var size = seq.size; + if (size !== undefined) { + return sum + size; + } + } + }, 0); + return concatSeq; +} + +function flattenFactory(collection, depth, useKeys) { + var flatSequence = makeSequence(collection); + flatSequence.__iterateUncached = function (fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var iterations = 0; + var stopped = false; + function flatDeep(iter, currentDepth) { + iter.__iterate(function (v, k) { + if ((!depth || currentDepth < depth) && isCollection(v)) { + flatDeep(v, currentDepth + 1); + } else { + iterations++; + if (fn(v, useKeys ? k : iterations - 1, flatSequence) === false) { + stopped = true; + } + } + return !stopped; + }, reverse); + } + flatDeep(collection, 0); + return iterations; + }; + flatSequence.__iteratorUncached = function (type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterator = collection.__iterator(type, reverse); + var stack = []; + var iterations = 0; + return new Iterator(function () { + while (iterator) { + var step = iterator.next(); + if (step.done !== false) { + iterator = stack.pop(); + continue; + } + var v = step.value; + if (type === ITERATE_ENTRIES) { + v = v[1]; + } + if ((!depth || stack.length < depth) && isCollection(v)) { + stack.push(iterator); + iterator = v.__iterator(type, reverse); + } else { + return useKeys ? step : iteratorValue(type, iterations++, v, step); + } + } + return iteratorDone(); + }); + }; + return flatSequence; +} + +function flatMapFactory(collection, mapper, context) { + var coerce = collectionClass(collection); + return collection + .toSeq() + .map(function (v, k) { return coerce(mapper.call(context, v, k, collection)); }) + .flatten(true); +} + +function interposeFactory(collection, separator) { + var interposedSequence = makeSequence(collection); + interposedSequence.size = collection.size && collection.size * 2 - 1; + interposedSequence.__iterateUncached = function (fn, reverse) { + var this$1$1 = this; + + var iterations = 0; + collection.__iterate( + function (v) { return (!iterations || fn(separator, iterations++, this$1$1) !== false) && + fn(v, iterations++, this$1$1) !== false; }, + reverse + ); + return iterations; + }; + interposedSequence.__iteratorUncached = function (type, reverse) { + var iterator = collection.__iterator(ITERATE_VALUES, reverse); + var iterations = 0; + var step; + return new Iterator(function () { + if (!step || iterations % 2) { + step = iterator.next(); + if (step.done) { + return step; + } + } + return iterations % 2 + ? iteratorValue(type, iterations++, separator) + : iteratorValue(type, iterations++, step.value, step); + }); + }; + return interposedSequence; +} + +function sortFactory(collection, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; + } + var isKeyedCollection = isKeyed(collection); + var index = 0; + var entries = collection + .toSeq() + .map(function (v, k) { return [k, v, index++, mapper ? mapper(v, k, collection) : v]; }) + .valueSeq() + .toArray(); + entries + .sort(function (a, b) { return comparator(a[3], b[3]) || a[2] - b[2]; }) + .forEach( + isKeyedCollection + ? function (v, i) { + entries[i].length = 2; + } + : function (v, i) { + entries[i] = v[1]; + } + ); + return isKeyedCollection + ? KeyedSeq(entries) + : isIndexed(collection) + ? IndexedSeq(entries) + : SetSeq(entries); +} + +function maxFactory(collection, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; + } + if (mapper) { + var entry = collection + .toSeq() + .map(function (v, k) { return [v, mapper(v, k, collection)]; }) + .reduce(function (a, b) { return (maxCompare(comparator, a[1], b[1]) ? b : a); }); + return entry && entry[0]; + } + return collection.reduce(function (a, b) { return (maxCompare(comparator, a, b) ? b : a); }); +} + +function maxCompare(comparator, a, b) { + var comp = comparator(b, a); + // b is considered the new max if the comparator declares them equal, but + // they are not equal and b is in fact a nullish value. + return ( + (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || + comp > 0 + ); +} + +function zipWithFactory(keyIter, zipper, iters, zipAll) { + var zipSequence = makeSequence(keyIter); + var sizes = new ArraySeq(iters).map(function (i) { return i.size; }); + zipSequence.size = zipAll ? sizes.max() : sizes.min(); + // Note: this a generic base implementation of __iterate in terms of + // __iterator which may be more generically useful in the future. + zipSequence.__iterate = function (fn, reverse) { + /* generic: + var iterator = this.__iterator(ITERATE_ENTRIES, reverse); + var step; + var iterations = 0; + while (!(step = iterator.next()).done) { + iterations++; + if (fn(step.value[1], step.value[0], this) === false) { + break; + } + } + return iterations; + */ + // indexed: + var iterator = this.__iterator(ITERATE_VALUES, reverse); + var step; + var iterations = 0; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; + } + } + return iterations; + }; + zipSequence.__iteratorUncached = function (type, reverse) { + var iterators = iters.map( + function (i) { return ((i = Collection(i)), getIterator(reverse ? i.reverse() : i)); } + ); + var iterations = 0; + var isDone = false; + return new Iterator(function () { + var steps; + if (!isDone) { + steps = iterators.map(function (i) { return i.next(); }); + isDone = zipAll ? steps.every(function (s) { return s.done; }) : steps.some(function (s) { return s.done; }); + } + if (isDone) { + return iteratorDone(); + } + return iteratorValue( + type, + iterations++, + zipper.apply( + null, + steps.map(function (s) { return s.value; }) + ) + ); + }); + }; + return zipSequence; +} + +// #pragma Helper Functions + +function reify(iter, seq) { + return iter === seq ? iter : isSeq(iter) ? seq : iter.constructor(seq); +} + +function validateEntry(entry) { + if (entry !== Object(entry)) { + throw new TypeError('Expected [K, V] tuple: ' + entry); + } +} + +function collectionClass(collection) { + return isKeyed(collection) + ? KeyedCollection + : isIndexed(collection) + ? IndexedCollection + : SetCollection; +} + +function makeSequence(collection) { + return Object.create( + (isKeyed(collection) + ? KeyedSeq + : isIndexed(collection) + ? IndexedSeq + : SetSeq + ).prototype + ); +} + +function cacheResultThrough() { + if (this._iter.cacheResult) { + this._iter.cacheResult(); + this.size = this._iter.size; + return this; + } + return Seq.prototype.cacheResult.call(this); +} + +function defaultComparator(a, b) { + if (a === undefined && b === undefined) { + return 0; + } + + if (a === undefined) { + return 1; + } + + if (b === undefined) { + return -1; + } + + return a > b ? 1 : a < b ? -1 : 0; +} + +function arrCopy(arr, offset) { + offset = offset || 0; + var len = Math.max(0, arr.length - offset); + var newArr = new Array(len); + for (var ii = 0; ii < len; ii++) { + newArr[ii] = arr[ii + offset]; + } + return newArr; +} + +function invariant(condition, error) { + if (!condition) { throw new Error(error); } +} + +function assertNotInfinite(size) { + invariant( + size !== Infinity, + 'Cannot perform this action with an infinite size.' + ); +} + +function coerceKeyPath(keyPath) { + if (isArrayLike(keyPath) && typeof keyPath !== 'string') { + return keyPath; + } + if (isOrdered(keyPath)) { + return keyPath.toArray(); + } + throw new TypeError( + 'Invalid keyPath: expected Ordered Collection or Array: ' + keyPath + ); +} + +var toString = Object.prototype.toString; + +function isPlainObject(value) { + // The base prototype's toString deals with Argument objects and native namespaces like Math + if ( + !value || + typeof value !== 'object' || + toString.call(value) !== '[object Object]' + ) { + return false; + } + + var proto = Object.getPrototypeOf(value); + if (proto === null) { + return true; + } + + // Iteratively going up the prototype chain is needed for cross-realm environments (differing contexts, iframes, etc) + var parentProto = proto; + var nextProto = Object.getPrototypeOf(proto); + while (nextProto !== null) { + parentProto = nextProto; + nextProto = Object.getPrototypeOf(parentProto); + } + return parentProto === proto; +} + +/** + * Returns true if the value is a potentially-persistent data structure, either + * provided by Immutable.js or a plain Array or Object. + */ +function isDataStructure(value) { + return ( + typeof value === 'object' && + (isImmutable(value) || Array.isArray(value) || isPlainObject(value)) + ); +} + +function quoteString(value) { + try { + return typeof value === 'string' ? JSON.stringify(value) : String(value); + } catch (_ignoreError) { + return JSON.stringify(value); + } +} + +function has(collection, key) { + return isImmutable(collection) + ? collection.has(key) + : isDataStructure(collection) && hasOwnProperty.call(collection, key); +} + +function get(collection, key, notSetValue) { + return isImmutable(collection) + ? collection.get(key, notSetValue) + : !has(collection, key) + ? notSetValue + : typeof collection.get === 'function' + ? collection.get(key) + : collection[key]; +} + +function shallowCopy(from) { + if (Array.isArray(from)) { + return arrCopy(from); + } + var to = {}; + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + return to; +} + +function remove(collection, key) { + if (!isDataStructure(collection)) { + throw new TypeError( + 'Cannot update non-data-structure value: ' + collection + ); + } + if (isImmutable(collection)) { + if (!collection.remove) { + throw new TypeError( + 'Cannot update immutable value without .remove() method: ' + collection + ); + } + return collection.remove(key); + } + if (!hasOwnProperty.call(collection, key)) { + return collection; + } + var collectionCopy = shallowCopy(collection); + if (Array.isArray(collectionCopy)) { + collectionCopy.splice(key, 1); + } else { + delete collectionCopy[key]; + } + return collectionCopy; +} + +function set(collection, key, value) { + if (!isDataStructure(collection)) { + throw new TypeError( + 'Cannot update non-data-structure value: ' + collection + ); + } + if (isImmutable(collection)) { + if (!collection.set) { + throw new TypeError( + 'Cannot update immutable value without .set() method: ' + collection + ); + } + return collection.set(key, value); + } + if (hasOwnProperty.call(collection, key) && value === collection[key]) { + return collection; + } + var collectionCopy = shallowCopy(collection); + collectionCopy[key] = value; + return collectionCopy; +} + +function updateIn$1(collection, keyPath, notSetValue, updater) { + if (!updater) { + updater = notSetValue; + notSetValue = undefined; + } + var updatedValue = updateInDeeply( + isImmutable(collection), + collection, + coerceKeyPath(keyPath), + 0, + notSetValue, + updater + ); + return updatedValue === NOT_SET ? notSetValue : updatedValue; +} + +function updateInDeeply( + inImmutable, + existing, + keyPath, + i, + notSetValue, + updater +) { + var wasNotSet = existing === NOT_SET; + if (i === keyPath.length) { + var existingValue = wasNotSet ? notSetValue : existing; + var newValue = updater(existingValue); + return newValue === existingValue ? existing : newValue; + } + if (!wasNotSet && !isDataStructure(existing)) { + throw new TypeError( + 'Cannot update within non-data-structure value in path [' + + keyPath.slice(0, i).map(quoteString) + + ']: ' + + existing + ); + } + var key = keyPath[i]; + var nextExisting = wasNotSet ? NOT_SET : get(existing, key, NOT_SET); + var nextUpdated = updateInDeeply( + nextExisting === NOT_SET ? inImmutable : isImmutable(nextExisting), + nextExisting, + keyPath, + i + 1, + notSetValue, + updater + ); + return nextUpdated === nextExisting + ? existing + : nextUpdated === NOT_SET + ? remove(existing, key) + : set( + wasNotSet ? (inImmutable ? emptyMap() : {}) : existing, + key, + nextUpdated + ); +} + +function setIn$1(collection, keyPath, value) { + return updateIn$1(collection, keyPath, NOT_SET, function () { return value; }); +} + +function setIn(keyPath, v) { + return setIn$1(this, keyPath, v); +} + +function removeIn(collection, keyPath) { + return updateIn$1(collection, keyPath, function () { return NOT_SET; }); +} + +function deleteIn(keyPath) { + return removeIn(this, keyPath); +} + +function update$1(collection, key, notSetValue, updater) { + return updateIn$1(collection, [key], notSetValue, updater); +} + +function update(key, notSetValue, updater) { + return arguments.length === 1 + ? key(this) + : update$1(this, key, notSetValue, updater); +} + +function updateIn(keyPath, notSetValue, updater) { + return updateIn$1(this, keyPath, notSetValue, updater); +} + +function merge$1() { + var iters = [], len = arguments.length; + while ( len-- ) iters[ len ] = arguments[ len ]; + + return mergeIntoKeyedWith(this, iters); +} + +function mergeWith$1(merger) { + var iters = [], len = arguments.length - 1; + while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; + + if (typeof merger !== 'function') { + throw new TypeError('Invalid merger function: ' + merger); + } + return mergeIntoKeyedWith(this, iters, merger); +} + +function mergeIntoKeyedWith(collection, collections, merger) { + var iters = []; + for (var ii = 0; ii < collections.length; ii++) { + var collection$1 = KeyedCollection(collections[ii]); + if (collection$1.size !== 0) { + iters.push(collection$1); + } + } + if (iters.length === 0) { + return collection; + } + if ( + collection.toSeq().size === 0 && + !collection.__ownerID && + iters.length === 1 + ) { + return collection.constructor(iters[0]); + } + return collection.withMutations(function (collection) { + var mergeIntoCollection = merger + ? function (value, key) { + update$1(collection, key, NOT_SET, function (oldVal) { return oldVal === NOT_SET ? value : merger(oldVal, value, key); } + ); + } + : function (value, key) { + collection.set(key, value); + }; + for (var ii = 0; ii < iters.length; ii++) { + iters[ii].forEach(mergeIntoCollection); + } + }); +} + +function merge(collection) { + var sources = [], len = arguments.length - 1; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; + + return mergeWithSources(collection, sources); +} + +function mergeWith(merger, collection) { + var sources = [], len = arguments.length - 2; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 2 ]; + + return mergeWithSources(collection, sources, merger); +} + +function mergeDeep$1(collection) { + var sources = [], len = arguments.length - 1; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; + + return mergeDeepWithSources(collection, sources); +} + +function mergeDeepWith$1(merger, collection) { + var sources = [], len = arguments.length - 2; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 2 ]; + + return mergeDeepWithSources(collection, sources, merger); +} + +function mergeDeepWithSources(collection, sources, merger) { + return mergeWithSources(collection, sources, deepMergerWith(merger)); +} + +function mergeWithSources(collection, sources, merger) { + if (!isDataStructure(collection)) { + throw new TypeError( + 'Cannot merge into non-data-structure value: ' + collection + ); + } + if (isImmutable(collection)) { + return typeof merger === 'function' && collection.mergeWith + ? collection.mergeWith.apply(collection, [ merger ].concat( sources )) + : collection.merge + ? collection.merge.apply(collection, sources) + : collection.concat.apply(collection, sources); + } + var isArray = Array.isArray(collection); + var merged = collection; + var Collection = isArray ? IndexedCollection : KeyedCollection; + var mergeItem = isArray + ? function (value) { + // Copy on write + if (merged === collection) { + merged = shallowCopy(merged); + } + merged.push(value); + } + : function (value, key) { + var hasVal = hasOwnProperty.call(merged, key); + var nextVal = + hasVal && merger ? merger(merged[key], value, key) : value; + if (!hasVal || nextVal !== merged[key]) { + // Copy on write + if (merged === collection) { + merged = shallowCopy(merged); + } + merged[key] = nextVal; + } + }; + for (var i = 0; i < sources.length; i++) { + Collection(sources[i]).forEach(mergeItem); + } + return merged; +} + +function deepMergerWith(merger) { + function deepMerger(oldValue, newValue, key) { + return isDataStructure(oldValue) && + isDataStructure(newValue) && + areMergeable(oldValue, newValue) + ? mergeWithSources(oldValue, [newValue], deepMerger) + : merger + ? merger(oldValue, newValue, key) + : newValue; + } + return deepMerger; +} + +/** + * It's unclear what the desired behavior is for merging two collections that + * fall into separate categories between keyed, indexed, or set-like, so we only + * consider them mergeable if they fall into the same category. + */ +function areMergeable(oldDataStructure, newDataStructure) { + var oldSeq = Seq(oldDataStructure); + var newSeq = Seq(newDataStructure); + // This logic assumes that a sequence can only fall into one of the three + // categories mentioned above (since there's no `isSetLike()` method). + return ( + isIndexed(oldSeq) === isIndexed(newSeq) && + isKeyed(oldSeq) === isKeyed(newSeq) + ); +} + +function mergeDeep() { + var iters = [], len = arguments.length; + while ( len-- ) iters[ len ] = arguments[ len ]; + + return mergeDeepWithSources(this, iters); +} + +function mergeDeepWith(merger) { + var iters = [], len = arguments.length - 1; + while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; + + return mergeDeepWithSources(this, iters, merger); +} + +function mergeIn(keyPath) { + var iters = [], len = arguments.length - 1; + while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; + + return updateIn$1(this, keyPath, emptyMap(), function (m) { return mergeWithSources(m, iters); }); +} + +function mergeDeepIn(keyPath) { + var iters = [], len = arguments.length - 1; + while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; + + return updateIn$1(this, keyPath, emptyMap(), function (m) { return mergeDeepWithSources(m, iters); } + ); +} + +function withMutations(fn) { + var mutable = this.asMutable(); + fn(mutable); + return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; +} + +function asMutable() { + return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); +} + +function asImmutable() { + return this.__ensureOwner(); +} + +function wasAltered() { + return this.__altered; +} + +var Map = /*@__PURE__*/(function (KeyedCollection) { + function Map(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyMap() + : isMap(value) && !isOrdered(value) + ? value + : emptyMap().withMutations(function (map) { + var iter = KeyedCollection(value); + assertNotInfinite(iter.size); + iter.forEach(function (v, k) { return map.set(k, v); }); + }); + } + + if ( KeyedCollection ) Map.__proto__ = KeyedCollection; + Map.prototype = Object.create( KeyedCollection && KeyedCollection.prototype ); + Map.prototype.constructor = Map; + + Map.of = function of () { + var keyValues = [], len = arguments.length; + while ( len-- ) keyValues[ len ] = arguments[ len ]; + + return emptyMap().withMutations(function (map) { + for (var i = 0; i < keyValues.length; i += 2) { + if (i + 1 >= keyValues.length) { + throw new Error('Missing value for key: ' + keyValues[i]); + } + map.set(keyValues[i], keyValues[i + 1]); + } + }); + }; + + Map.prototype.toString = function toString () { + return this.__toString('Map {', '}'); + }; + + // @pragma Access + + Map.prototype.get = function get (k, notSetValue) { + return this._root + ? this._root.get(0, undefined, k, notSetValue) + : notSetValue; + }; + + // @pragma Modification + + Map.prototype.set = function set (k, v) { + return updateMap(this, k, v); + }; + + Map.prototype.remove = function remove (k) { + return updateMap(this, k, NOT_SET); + }; + + Map.prototype.deleteAll = function deleteAll (keys) { + var collection = Collection(keys); + + if (collection.size === 0) { + return this; + } + + return this.withMutations(function (map) { + collection.forEach(function (key) { return map.remove(key); }); + }); + }; + + Map.prototype.clear = function clear () { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._root = null; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyMap(); + }; + + // @pragma Composition + + Map.prototype.sort = function sort (comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator)); + }; + + Map.prototype.sortBy = function sortBy (mapper, comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator, mapper)); + }; + + Map.prototype.map = function map (mapper, context) { + var this$1$1 = this; + + return this.withMutations(function (map) { + map.forEach(function (value, key) { + map.set(key, mapper.call(context, value, key, this$1$1)); + }); + }); + }; + + // @pragma Mutability + + Map.prototype.__iterator = function __iterator (type, reverse) { + return new MapIterator(this, type, reverse); + }; + + Map.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + var iterations = 0; + this._root && + this._root.iterate(function (entry) { + iterations++; + return fn(entry[1], entry[0], this$1$1); + }, reverse); + return iterations; + }; + + Map.prototype.__ensureOwner = function __ensureOwner (ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + if (this.size === 0) { + return emptyMap(); + } + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeMap(this.size, this._root, ownerID, this.__hash); + }; + + return Map; +}(KeyedCollection)); + +Map.isMap = isMap; + +var MapPrototype = Map.prototype; +MapPrototype[IS_MAP_SYMBOL] = true; +MapPrototype[DELETE] = MapPrototype.remove; +MapPrototype.removeAll = MapPrototype.deleteAll; +MapPrototype.setIn = setIn; +MapPrototype.removeIn = MapPrototype.deleteIn = deleteIn; +MapPrototype.update = update; +MapPrototype.updateIn = updateIn; +MapPrototype.merge = MapPrototype.concat = merge$1; +MapPrototype.mergeWith = mergeWith$1; +MapPrototype.mergeDeep = mergeDeep; +MapPrototype.mergeDeepWith = mergeDeepWith; +MapPrototype.mergeIn = mergeIn; +MapPrototype.mergeDeepIn = mergeDeepIn; +MapPrototype.withMutations = withMutations; +MapPrototype.wasAltered = wasAltered; +MapPrototype.asImmutable = asImmutable; +MapPrototype['@@transducer/init'] = MapPrototype.asMutable = asMutable; +MapPrototype['@@transducer/step'] = function (result, arr) { + return result.set(arr[0], arr[1]); +}; +MapPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); +}; + +// #pragma Trie Nodes + +var ArrayMapNode = function ArrayMapNode(ownerID, entries) { + this.ownerID = ownerID; + this.entries = entries; +}; + +ArrayMapNode.prototype.get = function get (shift, keyHash, key, notSetValue) { + var entries = this.entries; + for (var ii = 0, len = entries.length; ii < len; ii++) { + if (is(key, entries[ii][0])) { + return entries[ii][1]; + } + } + return notSetValue; +}; + +ArrayMapNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + var removed = value === NOT_SET; + + var entries = this.entries; + var idx = 0; + var len = entries.length; + for (; idx < len; idx++) { + if (is(key, entries[idx][0])) { + break; + } + } + var exists = idx < len; + + if (exists ? entries[idx][1] === value : removed) { + return this; + } + + SetRef(didAlter); + (removed || !exists) && SetRef(didChangeSize); + + if (removed && entries.length === 1) { + return; // undefined + } + + if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { + return createNodes(ownerID, entries, key, value); + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newEntries = isEditable ? entries : arrCopy(entries); + + if (exists) { + if (removed) { + idx === len - 1 + ? newEntries.pop() + : (newEntries[idx] = newEntries.pop()); + } else { + newEntries[idx] = [key, value]; + } + } else { + newEntries.push([key, value]); + } + + if (isEditable) { + this.entries = newEntries; + return this; + } + + return new ArrayMapNode(ownerID, newEntries); +}; + +var BitmapIndexedNode = function BitmapIndexedNode(ownerID, bitmap, nodes) { + this.ownerID = ownerID; + this.bitmap = bitmap; + this.nodes = nodes; +}; + +BitmapIndexedNode.prototype.get = function get (shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var bit = 1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK); + var bitmap = this.bitmap; + return (bitmap & bit) === 0 + ? notSetValue + : this.nodes[popCount(bitmap & (bit - 1))].get( + shift + SHIFT, + keyHash, + key, + notSetValue + ); +}; + +BitmapIndexedNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var bit = 1 << keyHashFrag; + var bitmap = this.bitmap; + var exists = (bitmap & bit) !== 0; + + if (!exists && value === NOT_SET) { + return this; + } + + var idx = popCount(bitmap & (bit - 1)); + var nodes = this.nodes; + var node = exists ? nodes[idx] : undefined; + var newNode = updateNode( + node, + ownerID, + shift + SHIFT, + keyHash, + key, + value, + didChangeSize, + didAlter + ); + + if (newNode === node) { + return this; + } + + if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { + return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); + } + + if ( + exists && + !newNode && + nodes.length === 2 && + isLeafNode(nodes[idx ^ 1]) + ) { + return nodes[idx ^ 1]; + } + + if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { + return newNode; + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newBitmap = exists ? (newNode ? bitmap : bitmap ^ bit) : bitmap | bit; + var newNodes = exists + ? newNode + ? setAt(nodes, idx, newNode, isEditable) + : spliceOut(nodes, idx, isEditable) + : spliceIn(nodes, idx, newNode, isEditable); + + if (isEditable) { + this.bitmap = newBitmap; + this.nodes = newNodes; + return this; + } + + return new BitmapIndexedNode(ownerID, newBitmap, newNodes); +}; + +var HashArrayMapNode = function HashArrayMapNode(ownerID, count, nodes) { + this.ownerID = ownerID; + this.count = count; + this.nodes = nodes; +}; + +HashArrayMapNode.prototype.get = function get (shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var node = this.nodes[idx]; + return node + ? node.get(shift + SHIFT, keyHash, key, notSetValue) + : notSetValue; +}; + +HashArrayMapNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var removed = value === NOT_SET; + var nodes = this.nodes; + var node = nodes[idx]; + + if (removed && !node) { + return this; + } + + var newNode = updateNode( + node, + ownerID, + shift + SHIFT, + keyHash, + key, + value, + didChangeSize, + didAlter + ); + if (newNode === node) { + return this; + } + + var newCount = this.count; + if (!node) { + newCount++; + } else if (!newNode) { + newCount--; + if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { + return packNodes(ownerID, nodes, newCount, idx); + } + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newNodes = setAt(nodes, idx, newNode, isEditable); + + if (isEditable) { + this.count = newCount; + this.nodes = newNodes; + return this; + } + + return new HashArrayMapNode(ownerID, newCount, newNodes); +}; + +var HashCollisionNode = function HashCollisionNode(ownerID, keyHash, entries) { + this.ownerID = ownerID; + this.keyHash = keyHash; + this.entries = entries; +}; + +HashCollisionNode.prototype.get = function get (shift, keyHash, key, notSetValue) { + var entries = this.entries; + for (var ii = 0, len = entries.length; ii < len; ii++) { + if (is(key, entries[ii][0])) { + return entries[ii][1]; + } + } + return notSetValue; +}; + +HashCollisionNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + + var removed = value === NOT_SET; + + if (keyHash !== this.keyHash) { + if (removed) { + return this; + } + SetRef(didAlter); + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); + } + + var entries = this.entries; + var idx = 0; + var len = entries.length; + for (; idx < len; idx++) { + if (is(key, entries[idx][0])) { + break; + } + } + var exists = idx < len; + + if (exists ? entries[idx][1] === value : removed) { + return this; + } + + SetRef(didAlter); + (removed || !exists) && SetRef(didChangeSize); + + if (removed && len === 2) { + return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newEntries = isEditable ? entries : arrCopy(entries); + + if (exists) { + if (removed) { + idx === len - 1 + ? newEntries.pop() + : (newEntries[idx] = newEntries.pop()); + } else { + newEntries[idx] = [key, value]; + } + } else { + newEntries.push([key, value]); + } + + if (isEditable) { + this.entries = newEntries; + return this; + } + + return new HashCollisionNode(ownerID, this.keyHash, newEntries); +}; + +var ValueNode = function ValueNode(ownerID, keyHash, entry) { + this.ownerID = ownerID; + this.keyHash = keyHash; + this.entry = entry; +}; + +ValueNode.prototype.get = function get (shift, keyHash, key, notSetValue) { + return is(key, this.entry[0]) ? this.entry[1] : notSetValue; +}; + +ValueNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + var removed = value === NOT_SET; + var keyMatch = is(key, this.entry[0]); + if (keyMatch ? value === this.entry[1] : removed) { + return this; + } + + SetRef(didAlter); + + if (removed) { + SetRef(didChangeSize); + return; // undefined + } + + if (keyMatch) { + if (ownerID && ownerID === this.ownerID) { + this.entry[1] = value; + return this; + } + return new ValueNode(ownerID, this.keyHash, [key, value]); + } + + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); +}; + +// #pragma Iterators + +ArrayMapNode.prototype.iterate = HashCollisionNode.prototype.iterate = + function (fn, reverse) { + var entries = this.entries; + for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { + if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { + return false; + } + } + }; + +BitmapIndexedNode.prototype.iterate = HashArrayMapNode.prototype.iterate = + function (fn, reverse) { + var nodes = this.nodes; + for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { + var node = nodes[reverse ? maxIndex - ii : ii]; + if (node && node.iterate(fn, reverse) === false) { + return false; + } + } + }; + +// eslint-disable-next-line no-unused-vars +ValueNode.prototype.iterate = function (fn, reverse) { + return fn(this.entry); +}; + +var MapIterator = /*@__PURE__*/(function (Iterator) { + function MapIterator(map, type, reverse) { + this._type = type; + this._reverse = reverse; + this._stack = map._root && mapIteratorFrame(map._root); + } + + if ( Iterator ) MapIterator.__proto__ = Iterator; + MapIterator.prototype = Object.create( Iterator && Iterator.prototype ); + MapIterator.prototype.constructor = MapIterator; + + MapIterator.prototype.next = function next () { + var type = this._type; + var stack = this._stack; + while (stack) { + var node = stack.node; + var index = stack.index++; + var maxIndex = (void 0); + if (node.entry) { + if (index === 0) { + return mapIteratorValue(type, node.entry); + } + } else if (node.entries) { + maxIndex = node.entries.length - 1; + if (index <= maxIndex) { + return mapIteratorValue( + type, + node.entries[this._reverse ? maxIndex - index : index] + ); + } + } else { + maxIndex = node.nodes.length - 1; + if (index <= maxIndex) { + var subNode = node.nodes[this._reverse ? maxIndex - index : index]; + if (subNode) { + if (subNode.entry) { + return mapIteratorValue(type, subNode.entry); + } + stack = this._stack = mapIteratorFrame(subNode, stack); + } + continue; + } + } + stack = this._stack = this._stack.__prev; + } + return iteratorDone(); + }; + + return MapIterator; +}(Iterator)); + +function mapIteratorValue(type, entry) { + return iteratorValue(type, entry[0], entry[1]); +} + +function mapIteratorFrame(node, prev) { + return { + node: node, + index: 0, + __prev: prev, + }; +} + +function makeMap(size, root, ownerID, hash) { + var map = Object.create(MapPrototype); + map.size = size; + map._root = root; + map.__ownerID = ownerID; + map.__hash = hash; + map.__altered = false; + return map; +} + +var EMPTY_MAP; +function emptyMap() { + return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); +} + +function updateMap(map, k, v) { + var newRoot; + var newSize; + if (!map._root) { + if (v === NOT_SET) { + return map; + } + newSize = 1; + newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); + } else { + var didChangeSize = MakeRef(); + var didAlter = MakeRef(); + newRoot = updateNode( + map._root, + map.__ownerID, + 0, + undefined, + k, + v, + didChangeSize, + didAlter + ); + if (!didAlter.value) { + return map; + } + newSize = map.size + (didChangeSize.value ? (v === NOT_SET ? -1 : 1) : 0); + } + if (map.__ownerID) { + map.size = newSize; + map._root = newRoot; + map.__hash = undefined; + map.__altered = true; + return map; + } + return newRoot ? makeMap(newSize, newRoot) : emptyMap(); +} + +function updateNode( + node, + ownerID, + shift, + keyHash, + key, + value, + didChangeSize, + didAlter +) { + if (!node) { + if (value === NOT_SET) { + return node; + } + SetRef(didAlter); + SetRef(didChangeSize); + return new ValueNode(ownerID, keyHash, [key, value]); + } + return node.update( + ownerID, + shift, + keyHash, + key, + value, + didChangeSize, + didAlter + ); +} + +function isLeafNode(node) { + return ( + node.constructor === ValueNode || node.constructor === HashCollisionNode + ); +} + +function mergeIntoNode(node, ownerID, shift, keyHash, entry) { + if (node.keyHash === keyHash) { + return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); + } + + var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; + var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + + var newNode; + var nodes = + idx1 === idx2 + ? [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] + : ((newNode = new ValueNode(ownerID, keyHash, entry)), + idx1 < idx2 ? [node, newNode] : [newNode, node]); + + return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); +} + +function createNodes(ownerID, entries, key, value) { + if (!ownerID) { + ownerID = new OwnerID(); + } + var node = new ValueNode(ownerID, hash(key), [key, value]); + for (var ii = 0; ii < entries.length; ii++) { + var entry = entries[ii]; + node = node.update(ownerID, 0, undefined, entry[0], entry[1]); + } + return node; +} + +function packNodes(ownerID, nodes, count, excluding) { + var bitmap = 0; + var packedII = 0; + var packedNodes = new Array(count); + for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { + var node = nodes[ii]; + if (node !== undefined && ii !== excluding) { + bitmap |= bit; + packedNodes[packedII++] = node; + } + } + return new BitmapIndexedNode(ownerID, bitmap, packedNodes); +} + +function expandNodes(ownerID, nodes, bitmap, including, node) { + var count = 0; + var expandedNodes = new Array(SIZE); + for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { + expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; + } + expandedNodes[including] = node; + return new HashArrayMapNode(ownerID, count + 1, expandedNodes); +} + +function popCount(x) { + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x += x >> 8; + x += x >> 16; + return x & 0x7f; +} + +function setAt(array, idx, val, canEdit) { + var newArray = canEdit ? array : arrCopy(array); + newArray[idx] = val; + return newArray; +} + +function spliceIn(array, idx, val, canEdit) { + var newLen = array.length + 1; + if (canEdit && idx + 1 === newLen) { + array[idx] = val; + return array; + } + var newArray = new Array(newLen); + var after = 0; + for (var ii = 0; ii < newLen; ii++) { + if (ii === idx) { + newArray[ii] = val; + after = -1; + } else { + newArray[ii] = array[ii + after]; + } + } + return newArray; +} + +function spliceOut(array, idx, canEdit) { + var newLen = array.length - 1; + if (canEdit && idx === newLen) { + array.pop(); + return array; + } + var newArray = new Array(newLen); + var after = 0; + for (var ii = 0; ii < newLen; ii++) { + if (ii === idx) { + after = 1; + } + newArray[ii] = array[ii + after]; + } + return newArray; +} + +var MAX_ARRAY_MAP_SIZE = SIZE / 4; +var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; +var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; + +var IS_LIST_SYMBOL = '@@__IMMUTABLE_LIST__@@'; + +function isList(maybeList) { + return Boolean(maybeList && maybeList[IS_LIST_SYMBOL]); +} + +var List = /*@__PURE__*/(function (IndexedCollection) { + function List(value) { + var empty = emptyList(); + if (value === undefined || value === null) { + // eslint-disable-next-line no-constructor-return + return empty; + } + if (isList(value)) { + // eslint-disable-next-line no-constructor-return + return value; + } + var iter = IndexedCollection(value); + var size = iter.size; + if (size === 0) { + // eslint-disable-next-line no-constructor-return + return empty; + } + assertNotInfinite(size); + if (size > 0 && size < SIZE) { + // eslint-disable-next-line no-constructor-return + return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); + } + // eslint-disable-next-line no-constructor-return + return empty.withMutations(function (list) { + list.setSize(size); + iter.forEach(function (v, i) { return list.set(i, v); }); + }); + } + + if ( IndexedCollection ) List.__proto__ = IndexedCollection; + List.prototype = Object.create( IndexedCollection && IndexedCollection.prototype ); + List.prototype.constructor = List; + + List.of = function of (/*...values*/) { + return this(arguments); + }; + + List.prototype.toString = function toString () { + return this.__toString('List [', ']'); + }; + + // @pragma Access + + List.prototype.get = function get (index, notSetValue) { + index = wrapIndex(this, index); + if (index >= 0 && index < this.size) { + index += this._origin; + var node = listNodeFor(this, index); + return node && node.array[index & MASK]; + } + return notSetValue; + }; + + // @pragma Modification + + List.prototype.set = function set (index, value) { + return updateList(this, index, value); + }; + + List.prototype.remove = function remove (index) { + return !this.has(index) + ? this + : index === 0 + ? this.shift() + : index === this.size - 1 + ? this.pop() + : this.splice(index, 1); + }; + + List.prototype.insert = function insert (index, value) { + return this.splice(index, 0, value); + }; + + List.prototype.clear = function clear () { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = this._origin = this._capacity = 0; + this._level = SHIFT; + this._root = this._tail = this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyList(); + }; + + List.prototype.push = function push (/*...values*/) { + var values = arguments; + var oldSize = this.size; + return this.withMutations(function (list) { + setListBounds(list, 0, oldSize + values.length); + for (var ii = 0; ii < values.length; ii++) { + list.set(oldSize + ii, values[ii]); + } + }); + }; + + List.prototype.pop = function pop () { + return setListBounds(this, 0, -1); + }; + + List.prototype.unshift = function unshift (/*...values*/) { + var values = arguments; + return this.withMutations(function (list) { + setListBounds(list, -values.length); + for (var ii = 0; ii < values.length; ii++) { + list.set(ii, values[ii]); + } + }); + }; + + List.prototype.shift = function shift () { + return setListBounds(this, 1); + }; + + // @pragma Composition + + List.prototype.concat = function concat (/*...collections*/) { + var arguments$1 = arguments; + + var seqs = []; + for (var i = 0; i < arguments.length; i++) { + var argument = arguments$1[i]; + var seq = IndexedCollection( + typeof argument !== 'string' && hasIterator(argument) + ? argument + : [argument] + ); + if (seq.size !== 0) { + seqs.push(seq); + } + } + if (seqs.length === 0) { + return this; + } + if (this.size === 0 && !this.__ownerID && seqs.length === 1) { + return this.constructor(seqs[0]); + } + return this.withMutations(function (list) { + seqs.forEach(function (seq) { return seq.forEach(function (value) { return list.push(value); }); }); + }); + }; + + List.prototype.setSize = function setSize (size) { + return setListBounds(this, 0, size); + }; + + List.prototype.map = function map (mapper, context) { + var this$1$1 = this; + + return this.withMutations(function (list) { + for (var i = 0; i < this$1$1.size; i++) { + list.set(i, mapper.call(context, list.get(i), i, this$1$1)); + } + }); + }; + + // @pragma Iteration + + List.prototype.slice = function slice (begin, end) { + var size = this.size; + if (wholeSlice(begin, end, size)) { + return this; + } + return setListBounds( + this, + resolveBegin(begin, size), + resolveEnd(end, size) + ); + }; + + List.prototype.__iterator = function __iterator (type, reverse) { + var index = reverse ? this.size : 0; + var values = iterateList(this, reverse); + return new Iterator(function () { + var value = values(); + return value === DONE + ? iteratorDone() + : iteratorValue(type, reverse ? --index : index++, value); + }); + }; + + List.prototype.__iterate = function __iterate (fn, reverse) { + var index = reverse ? this.size : 0; + var values = iterateList(this, reverse); + var value; + while ((value = values()) !== DONE) { + if (fn(value, reverse ? --index : index++, this) === false) { + break; + } + } + return index; + }; + + List.prototype.__ensureOwner = function __ensureOwner (ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + if (this.size === 0) { + return emptyList(); + } + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeList( + this._origin, + this._capacity, + this._level, + this._root, + this._tail, + ownerID, + this.__hash + ); + }; + + return List; +}(IndexedCollection)); + +List.isList = isList; + +var ListPrototype = List.prototype; +ListPrototype[IS_LIST_SYMBOL] = true; +ListPrototype[DELETE] = ListPrototype.remove; +ListPrototype.merge = ListPrototype.concat; +ListPrototype.setIn = setIn; +ListPrototype.deleteIn = ListPrototype.removeIn = deleteIn; +ListPrototype.update = update; +ListPrototype.updateIn = updateIn; +ListPrototype.mergeIn = mergeIn; +ListPrototype.mergeDeepIn = mergeDeepIn; +ListPrototype.withMutations = withMutations; +ListPrototype.wasAltered = wasAltered; +ListPrototype.asImmutable = asImmutable; +ListPrototype['@@transducer/init'] = ListPrototype.asMutable = asMutable; +ListPrototype['@@transducer/step'] = function (result, arr) { + return result.push(arr); +}; +ListPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); +}; + +var VNode = function VNode(array, ownerID) { + this.array = array; + this.ownerID = ownerID; +}; + +// TODO: seems like these methods are very similar + +VNode.prototype.removeBefore = function removeBefore (ownerID, level, index) { + if (index === level ? 1 << level : this.array.length === 0) { + return this; + } + var originIndex = (index >>> level) & MASK; + if (originIndex >= this.array.length) { + return new VNode([], ownerID); + } + var removingFirst = originIndex === 0; + var newChild; + if (level > 0) { + var oldChild = this.array[originIndex]; + newChild = + oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); + if (newChild === oldChild && removingFirst) { + return this; + } + } + if (removingFirst && !newChild) { + return this; + } + var editable = editableVNode(this, ownerID); + if (!removingFirst) { + for (var ii = 0; ii < originIndex; ii++) { + editable.array[ii] = undefined; + } + } + if (newChild) { + editable.array[originIndex] = newChild; + } + return editable; +}; + +VNode.prototype.removeAfter = function removeAfter (ownerID, level, index) { + if (index === (level ? 1 << level : 0) || this.array.length === 0) { + return this; + } + var sizeIndex = ((index - 1) >>> level) & MASK; + if (sizeIndex >= this.array.length) { + return this; + } + + var newChild; + if (level > 0) { + var oldChild = this.array[sizeIndex]; + newChild = + oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); + if (newChild === oldChild && sizeIndex === this.array.length - 1) { + return this; + } + } + + var editable = editableVNode(this, ownerID); + editable.array.splice(sizeIndex + 1); + if (newChild) { + editable.array[sizeIndex] = newChild; + } + return editable; +}; + +var DONE = {}; + +function iterateList(list, reverse) { + var left = list._origin; + var right = list._capacity; + var tailPos = getTailOffset(right); + var tail = list._tail; + + return iterateNodeOrLeaf(list._root, list._level, 0); + + function iterateNodeOrLeaf(node, level, offset) { + return level === 0 + ? iterateLeaf(node, offset) + : iterateNode(node, level, offset); + } + + function iterateLeaf(node, offset) { + var array = offset === tailPos ? tail && tail.array : node && node.array; + var from = offset > left ? 0 : left - offset; + var to = right - offset; + if (to > SIZE) { + to = SIZE; + } + return function () { + if (from === to) { + return DONE; + } + var idx = reverse ? --to : from++; + return array && array[idx]; + }; + } + + function iterateNode(node, level, offset) { + var values; + var array = node && node.array; + var from = offset > left ? 0 : (left - offset) >> level; + var to = ((right - offset) >> level) + 1; + if (to > SIZE) { + to = SIZE; + } + return function () { + while (true) { + if (values) { + var value = values(); + if (value !== DONE) { + return value; + } + values = null; + } + if (from === to) { + return DONE; + } + var idx = reverse ? --to : from++; + values = iterateNodeOrLeaf( + array && array[idx], + level - SHIFT, + offset + (idx << level) + ); + } + }; + } +} + +function makeList(origin, capacity, level, root, tail, ownerID, hash) { + var list = Object.create(ListPrototype); + list.size = capacity - origin; + list._origin = origin; + list._capacity = capacity; + list._level = level; + list._root = root; + list._tail = tail; + list.__ownerID = ownerID; + list.__hash = hash; + list.__altered = false; + return list; +} + +var EMPTY_LIST; +function emptyList() { + return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); +} + +function updateList(list, index, value) { + index = wrapIndex(list, index); + + if (index !== index) { + return list; + } + + if (index >= list.size || index < 0) { + return list.withMutations(function (list) { + index < 0 + ? setListBounds(list, index).set(0, value) + : setListBounds(list, 0, index + 1).set(index, value); + }); + } + + index += list._origin; + + var newTail = list._tail; + var newRoot = list._root; + var didAlter = MakeRef(); + if (index >= getTailOffset(list._capacity)) { + newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); + } else { + newRoot = updateVNode( + newRoot, + list.__ownerID, + list._level, + index, + value, + didAlter + ); + } + + if (!didAlter.value) { + return list; + } + + if (list.__ownerID) { + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; + } + return makeList(list._origin, list._capacity, list._level, newRoot, newTail); +} + +function updateVNode(node, ownerID, level, index, value, didAlter) { + var idx = (index >>> level) & MASK; + var nodeHas = node && idx < node.array.length; + if (!nodeHas && value === undefined) { + return node; + } + + var newNode; + + if (level > 0) { + var lowerNode = node && node.array[idx]; + var newLowerNode = updateVNode( + lowerNode, + ownerID, + level - SHIFT, + index, + value, + didAlter + ); + if (newLowerNode === lowerNode) { + return node; + } + newNode = editableVNode(node, ownerID); + newNode.array[idx] = newLowerNode; + return newNode; + } + + if (nodeHas && node.array[idx] === value) { + return node; + } + + if (didAlter) { + SetRef(didAlter); + } + + newNode = editableVNode(node, ownerID); + if (value === undefined && idx === newNode.array.length - 1) { + newNode.array.pop(); + } else { + newNode.array[idx] = value; + } + return newNode; +} + +function editableVNode(node, ownerID) { + if (ownerID && node && ownerID === node.ownerID) { + return node; + } + return new VNode(node ? node.array.slice() : [], ownerID); +} + +function listNodeFor(list, rawIndex) { + if (rawIndex >= getTailOffset(list._capacity)) { + return list._tail; + } + if (rawIndex < 1 << (list._level + SHIFT)) { + var node = list._root; + var level = list._level; + while (node && level > 0) { + node = node.array[(rawIndex >>> level) & MASK]; + level -= SHIFT; + } + return node; + } +} + +function setListBounds(list, begin, end) { + // Sanitize begin & end using this shorthand for ToInt32(argument) + // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 + if (begin !== undefined) { + begin |= 0; + } + if (end !== undefined) { + end |= 0; + } + var owner = list.__ownerID || new OwnerID(); + var oldOrigin = list._origin; + var oldCapacity = list._capacity; + var newOrigin = oldOrigin + begin; + var newCapacity = + end === undefined + ? oldCapacity + : end < 0 + ? oldCapacity + end + : oldOrigin + end; + if (newOrigin === oldOrigin && newCapacity === oldCapacity) { + return list; + } + + // If it's going to end after it starts, it's empty. + if (newOrigin >= newCapacity) { + return list.clear(); + } + + var newLevel = list._level; + var newRoot = list._root; + + // New origin might need creating a higher root. + var offsetShift = 0; + while (newOrigin + offsetShift < 0) { + newRoot = new VNode( + newRoot && newRoot.array.length ? [undefined, newRoot] : [], + owner + ); + newLevel += SHIFT; + offsetShift += 1 << newLevel; + } + if (offsetShift) { + newOrigin += offsetShift; + oldOrigin += offsetShift; + newCapacity += offsetShift; + oldCapacity += offsetShift; + } + + var oldTailOffset = getTailOffset(oldCapacity); + var newTailOffset = getTailOffset(newCapacity); + + // New size might need creating a higher root. + while (newTailOffset >= 1 << (newLevel + SHIFT)) { + newRoot = new VNode( + newRoot && newRoot.array.length ? [newRoot] : [], + owner + ); + newLevel += SHIFT; + } + + // Locate or create the new tail. + var oldTail = list._tail; + var newTail = + newTailOffset < oldTailOffset + ? listNodeFor(list, newCapacity - 1) + : newTailOffset > oldTailOffset + ? new VNode([], owner) + : oldTail; + + // Merge Tail into tree. + if ( + oldTail && + newTailOffset > oldTailOffset && + newOrigin < oldCapacity && + oldTail.array.length + ) { + newRoot = editableVNode(newRoot, owner); + var node = newRoot; + for (var level = newLevel; level > SHIFT; level -= SHIFT) { + var idx = (oldTailOffset >>> level) & MASK; + node = node.array[idx] = editableVNode(node.array[idx], owner); + } + node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; + } + + // If the size has been reduced, there's a chance the tail needs to be trimmed. + if (newCapacity < oldCapacity) { + newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); + } + + // If the new origin is within the tail, then we do not need a root. + if (newOrigin >= newTailOffset) { + newOrigin -= newTailOffset; + newCapacity -= newTailOffset; + newLevel = SHIFT; + newRoot = null; + newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); + + // Otherwise, if the root has been trimmed, garbage collect. + } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { + offsetShift = 0; + + // Identify the new top root node of the subtree of the old root. + while (newRoot) { + var beginIndex = (newOrigin >>> newLevel) & MASK; + if ((beginIndex !== newTailOffset >>> newLevel) & MASK) { + break; + } + if (beginIndex) { + offsetShift += (1 << newLevel) * beginIndex; + } + newLevel -= SHIFT; + newRoot = newRoot.array[beginIndex]; + } + + // Trim the new sides of the new root. + if (newRoot && newOrigin > oldOrigin) { + newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); + } + if (newRoot && newTailOffset < oldTailOffset) { + newRoot = newRoot.removeAfter( + owner, + newLevel, + newTailOffset - offsetShift + ); + } + if (offsetShift) { + newOrigin -= offsetShift; + newCapacity -= offsetShift; + } + } + + if (list.__ownerID) { + list.size = newCapacity - newOrigin; + list._origin = newOrigin; + list._capacity = newCapacity; + list._level = newLevel; + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; + } + return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); +} + +function getTailOffset(size) { + return size < SIZE ? 0 : ((size - 1) >>> SHIFT) << SHIFT; +} + +var OrderedMap = /*@__PURE__*/(function (Map) { + function OrderedMap(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyOrderedMap() + : isOrderedMap(value) + ? value + : emptyOrderedMap().withMutations(function (map) { + var iter = KeyedCollection(value); + assertNotInfinite(iter.size); + iter.forEach(function (v, k) { return map.set(k, v); }); + }); + } + + if ( Map ) OrderedMap.__proto__ = Map; + OrderedMap.prototype = Object.create( Map && Map.prototype ); + OrderedMap.prototype.constructor = OrderedMap; + + OrderedMap.of = function of (/*...values*/) { + return this(arguments); + }; + + OrderedMap.prototype.toString = function toString () { + return this.__toString('OrderedMap {', '}'); + }; + + // @pragma Access + + OrderedMap.prototype.get = function get (k, notSetValue) { + var index = this._map.get(k); + return index !== undefined ? this._list.get(index)[1] : notSetValue; + }; + + // @pragma Modification + + OrderedMap.prototype.clear = function clear () { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._map.clear(); + this._list.clear(); + this.__altered = true; + return this; + } + return emptyOrderedMap(); + }; + + OrderedMap.prototype.set = function set (k, v) { + return updateOrderedMap(this, k, v); + }; + + OrderedMap.prototype.remove = function remove (k) { + return updateOrderedMap(this, k, NOT_SET); + }; + + OrderedMap.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + return this._list.__iterate( + function (entry) { return entry && fn(entry[1], entry[0], this$1$1); }, + reverse + ); + }; + + OrderedMap.prototype.__iterator = function __iterator (type, reverse) { + return this._list.fromEntrySeq().__iterator(type, reverse); + }; + + OrderedMap.prototype.__ensureOwner = function __ensureOwner (ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map.__ensureOwner(ownerID); + var newList = this._list.__ensureOwner(ownerID); + if (!ownerID) { + if (this.size === 0) { + return emptyOrderedMap(); + } + this.__ownerID = ownerID; + this.__altered = false; + this._map = newMap; + this._list = newList; + return this; + } + return makeOrderedMap(newMap, newList, ownerID, this.__hash); + }; + + return OrderedMap; +}(Map)); + +OrderedMap.isOrderedMap = isOrderedMap; + +OrderedMap.prototype[IS_ORDERED_SYMBOL] = true; +OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; + +function makeOrderedMap(map, list, ownerID, hash) { + var omap = Object.create(OrderedMap.prototype); + omap.size = map ? map.size : 0; + omap._map = map; + omap._list = list; + omap.__ownerID = ownerID; + omap.__hash = hash; + omap.__altered = false; + return omap; +} + +var EMPTY_ORDERED_MAP; +function emptyOrderedMap() { + return ( + EMPTY_ORDERED_MAP || + (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())) + ); +} + +function updateOrderedMap(omap, k, v) { + var map = omap._map; + var list = omap._list; + var i = map.get(k); + var has = i !== undefined; + var newMap; + var newList; + if (v === NOT_SET) { + // removed + if (!has) { + return omap; + } + if (list.size >= SIZE && list.size >= map.size * 2) { + newList = list.filter(function (entry, idx) { return entry !== undefined && i !== idx; }); + newMap = newList + .toKeyedSeq() + .map(function (entry) { return entry[0]; }) + .flip() + .toMap(); + if (omap.__ownerID) { + newMap.__ownerID = newList.__ownerID = omap.__ownerID; + } + } else { + newMap = map.remove(k); + newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); + } + } else if (has) { + if (v === list.get(i)[1]) { + return omap; + } + newMap = map; + newList = list.set(i, [k, v]); + } else { + newMap = map.set(k, list.size); + newList = list.set(list.size, [k, v]); + } + if (omap.__ownerID) { + omap.size = newMap.size; + omap._map = newMap; + omap._list = newList; + omap.__hash = undefined; + omap.__altered = true; + return omap; + } + return makeOrderedMap(newMap, newList); +} + +var IS_STACK_SYMBOL = '@@__IMMUTABLE_STACK__@@'; + +function isStack(maybeStack) { + return Boolean(maybeStack && maybeStack[IS_STACK_SYMBOL]); +} + +var Stack = /*@__PURE__*/(function (IndexedCollection) { + function Stack(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyStack() + : isStack(value) + ? value + : emptyStack().pushAll(value); + } + + if ( IndexedCollection ) Stack.__proto__ = IndexedCollection; + Stack.prototype = Object.create( IndexedCollection && IndexedCollection.prototype ); + Stack.prototype.constructor = Stack; + + Stack.of = function of (/*...values*/) { + return this(arguments); + }; + + Stack.prototype.toString = function toString () { + return this.__toString('Stack [', ']'); + }; + + // @pragma Access + + Stack.prototype.get = function get (index, notSetValue) { + var head = this._head; + index = wrapIndex(this, index); + while (head && index--) { + head = head.next; + } + return head ? head.value : notSetValue; + }; + + Stack.prototype.peek = function peek () { + return this._head && this._head.value; + }; + + // @pragma Modification + + Stack.prototype.push = function push (/*...values*/) { + var arguments$1 = arguments; + + if (arguments.length === 0) { + return this; + } + var newSize = this.size + arguments.length; + var head = this._head; + for (var ii = arguments.length - 1; ii >= 0; ii--) { + head = { + value: arguments$1[ii], + next: head, + }; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + Stack.prototype.pushAll = function pushAll (iter) { + iter = IndexedCollection(iter); + if (iter.size === 0) { + return this; + } + if (this.size === 0 && isStack(iter)) { + return iter; + } + assertNotInfinite(iter.size); + var newSize = this.size; + var head = this._head; + iter.__iterate(function (value) { + newSize++; + head = { + value: value, + next: head, + }; + }, /* reverse */ true); + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + Stack.prototype.pop = function pop () { + return this.slice(1); + }; + + Stack.prototype.clear = function clear () { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._head = undefined; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyStack(); + }; + + Stack.prototype.slice = function slice (begin, end) { + if (wholeSlice(begin, end, this.size)) { + return this; + } + var resolvedBegin = resolveBegin(begin, this.size); + var resolvedEnd = resolveEnd(end, this.size); + if (resolvedEnd !== this.size) { + // super.slice(begin, end); + return IndexedCollection.prototype.slice.call(this, begin, end); + } + var newSize = this.size - resolvedBegin; + var head = this._head; + while (resolvedBegin--) { + head = head.next; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + // @pragma Mutability + + Stack.prototype.__ensureOwner = function __ensureOwner (ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + if (this.size === 0) { + return emptyStack(); + } + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeStack(this.size, this._head, ownerID, this.__hash); + }; + + // @pragma Iteration + + Stack.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + if (reverse) { + return new ArraySeq(this.toArray()).__iterate( + function (v, k) { return fn(v, k, this$1$1); }, + reverse + ); + } + var iterations = 0; + var node = this._head; + while (node) { + if (fn(node.value, iterations++, this) === false) { + break; + } + node = node.next; + } + return iterations; + }; + + Stack.prototype.__iterator = function __iterator (type, reverse) { + if (reverse) { + return new ArraySeq(this.toArray()).__iterator(type, reverse); + } + var iterations = 0; + var node = this._head; + return new Iterator(function () { + if (node) { + var value = node.value; + node = node.next; + return iteratorValue(type, iterations++, value); + } + return iteratorDone(); + }); + }; + + return Stack; +}(IndexedCollection)); + +Stack.isStack = isStack; + +var StackPrototype = Stack.prototype; +StackPrototype[IS_STACK_SYMBOL] = true; +StackPrototype.shift = StackPrototype.pop; +StackPrototype.unshift = StackPrototype.push; +StackPrototype.unshiftAll = StackPrototype.pushAll; +StackPrototype.withMutations = withMutations; +StackPrototype.wasAltered = wasAltered; +StackPrototype.asImmutable = asImmutable; +StackPrototype['@@transducer/init'] = StackPrototype.asMutable = asMutable; +StackPrototype['@@transducer/step'] = function (result, arr) { + return result.unshift(arr); +}; +StackPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); +}; + +function makeStack(size, head, ownerID, hash) { + var map = Object.create(StackPrototype); + map.size = size; + map._head = head; + map.__ownerID = ownerID; + map.__hash = hash; + map.__altered = false; + return map; +} + +var EMPTY_STACK; +function emptyStack() { + return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); +} + +var IS_SET_SYMBOL = '@@__IMMUTABLE_SET__@@'; + +function isSet(maybeSet) { + return Boolean(maybeSet && maybeSet[IS_SET_SYMBOL]); +} + +function isOrderedSet(maybeOrderedSet) { + return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); +} + +function deepEqual(a, b) { + if (a === b) { + return true; + } + + if ( + !isCollection(b) || + (a.size !== undefined && b.size !== undefined && a.size !== b.size) || + (a.__hash !== undefined && + b.__hash !== undefined && + a.__hash !== b.__hash) || + isKeyed(a) !== isKeyed(b) || + isIndexed(a) !== isIndexed(b) || + isOrdered(a) !== isOrdered(b) + ) { + return false; + } + + if (a.size === 0 && b.size === 0) { + return true; + } + + var notAssociative = !isAssociative(a); + + if (isOrdered(a)) { + var entries = a.entries(); + return ( + b.every(function (v, k) { + var entry = entries.next().value; + return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); + }) && entries.next().done + ); + } + + var flipped = false; + + if (a.size === undefined) { + if (b.size === undefined) { + if (typeof a.cacheResult === 'function') { + a.cacheResult(); + } + } else { + flipped = true; + var _ = a; + a = b; + b = _; + } + } + + var allEqual = true; + var bSize = b.__iterate(function (v, k) { + if ( + notAssociative + ? !a.has(v) + : flipped + ? !is(v, a.get(k, NOT_SET)) + : !is(a.get(k, NOT_SET), v) + ) { + allEqual = false; + return false; + } + }); + + return allEqual && a.size === bSize; +} + +function mixin(ctor, methods) { + var keyCopier = function (key) { + ctor.prototype[key] = methods[key]; + }; + Object.keys(methods).forEach(keyCopier); + Object.getOwnPropertySymbols && + Object.getOwnPropertySymbols(methods).forEach(keyCopier); + return ctor; +} + +function toJS(value) { + if (!value || typeof value !== 'object') { + return value; + } + if (!isCollection(value)) { + if (!isDataStructure(value)) { + return value; + } + value = Seq(value); + } + if (isKeyed(value)) { + var result$1 = {}; + value.__iterate(function (v, k) { + result$1[k] = toJS(v); + }); + return result$1; + } + var result = []; + value.__iterate(function (v) { + result.push(toJS(v)); + }); + return result; +} + +var Set = /*@__PURE__*/(function (SetCollection) { + function Set(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptySet() + : isSet(value) && !isOrdered(value) + ? value + : emptySet().withMutations(function (set) { + var iter = SetCollection(value); + assertNotInfinite(iter.size); + iter.forEach(function (v) { return set.add(v); }); + }); + } + + if ( SetCollection ) Set.__proto__ = SetCollection; + Set.prototype = Object.create( SetCollection && SetCollection.prototype ); + Set.prototype.constructor = Set; + + Set.of = function of (/*...values*/) { + return this(arguments); + }; + + Set.fromKeys = function fromKeys (value) { + return this(KeyedCollection(value).keySeq()); + }; + + Set.intersect = function intersect (sets) { + sets = Collection(sets).toArray(); + return sets.length + ? SetPrototype.intersect.apply(Set(sets.pop()), sets) + : emptySet(); + }; + + Set.union = function union (sets) { + sets = Collection(sets).toArray(); + return sets.length + ? SetPrototype.union.apply(Set(sets.pop()), sets) + : emptySet(); + }; + + Set.prototype.toString = function toString () { + return this.__toString('Set {', '}'); + }; + + // @pragma Access + + Set.prototype.has = function has (value) { + return this._map.has(value); + }; + + // @pragma Modification + + Set.prototype.add = function add (value) { + return updateSet(this, this._map.set(value, value)); + }; + + Set.prototype.remove = function remove (value) { + return updateSet(this, this._map.remove(value)); + }; + + Set.prototype.clear = function clear () { + return updateSet(this, this._map.clear()); + }; + + // @pragma Composition + + Set.prototype.map = function map (mapper, context) { + var this$1$1 = this; + + // keep track if the set is altered by the map function + var didChanges = false; + + var newMap = updateSet( + this, + this._map.mapEntries(function (ref) { + var v = ref[1]; + + var mapped = mapper.call(context, v, v, this$1$1); + + if (mapped !== v) { + didChanges = true; + } + + return [mapped, mapped]; + }, context) + ); + + return didChanges ? newMap : this; + }; + + Set.prototype.union = function union () { + var iters = [], len = arguments.length; + while ( len-- ) iters[ len ] = arguments[ len ]; + + iters = iters.filter(function (x) { return x.size !== 0; }); + if (iters.length === 0) { + return this; + } + if (this.size === 0 && !this.__ownerID && iters.length === 1) { + return this.constructor(iters[0]); + } + return this.withMutations(function (set) { + for (var ii = 0; ii < iters.length; ii++) { + if (typeof iters[ii] === 'string') { + set.add(iters[ii]); + } else { + SetCollection(iters[ii]).forEach(function (value) { return set.add(value); }); + } + } + }); + }; + + Set.prototype.intersect = function intersect () { + var iters = [], len = arguments.length; + while ( len-- ) iters[ len ] = arguments[ len ]; + + if (iters.length === 0) { + return this; + } + iters = iters.map(function (iter) { return SetCollection(iter); }); + var toRemove = []; + this.forEach(function (value) { + if (!iters.every(function (iter) { return iter.includes(value); })) { + toRemove.push(value); + } + }); + return this.withMutations(function (set) { + toRemove.forEach(function (value) { + set.remove(value); + }); + }); + }; + + Set.prototype.subtract = function subtract () { + var iters = [], len = arguments.length; + while ( len-- ) iters[ len ] = arguments[ len ]; + + if (iters.length === 0) { + return this; + } + iters = iters.map(function (iter) { return SetCollection(iter); }); + var toRemove = []; + this.forEach(function (value) { + if (iters.some(function (iter) { return iter.includes(value); })) { + toRemove.push(value); + } + }); + return this.withMutations(function (set) { + toRemove.forEach(function (value) { + set.remove(value); + }); + }); + }; + + Set.prototype.sort = function sort (comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator)); + }; + + Set.prototype.sortBy = function sortBy (mapper, comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator, mapper)); + }; + + Set.prototype.wasAltered = function wasAltered () { + return this._map.wasAltered(); + }; + + Set.prototype.__iterate = function __iterate (fn, reverse) { + var this$1$1 = this; + + return this._map.__iterate(function (k) { return fn(k, k, this$1$1); }, reverse); + }; + + Set.prototype.__iterator = function __iterator (type, reverse) { + return this._map.__iterator(type, reverse); + }; + + Set.prototype.__ensureOwner = function __ensureOwner (ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map.__ensureOwner(ownerID); + if (!ownerID) { + if (this.size === 0) { + return this.__empty(); + } + this.__ownerID = ownerID; + this._map = newMap; + return this; + } + return this.__make(newMap, ownerID); + }; + + return Set; +}(SetCollection)); + +Set.isSet = isSet; + +var SetPrototype = Set.prototype; +SetPrototype[IS_SET_SYMBOL] = true; +SetPrototype[DELETE] = SetPrototype.remove; +SetPrototype.merge = SetPrototype.concat = SetPrototype.union; +SetPrototype.withMutations = withMutations; +SetPrototype.asImmutable = asImmutable; +SetPrototype['@@transducer/init'] = SetPrototype.asMutable = asMutable; +SetPrototype['@@transducer/step'] = function (result, arr) { + return result.add(arr); +}; +SetPrototype['@@transducer/result'] = function (obj) { + return obj.asImmutable(); +}; + +SetPrototype.__empty = emptySet; +SetPrototype.__make = makeSet; + +function updateSet(set, newMap) { + if (set.__ownerID) { + set.size = newMap.size; + set._map = newMap; + return set; + } + return newMap === set._map + ? set + : newMap.size === 0 + ? set.__empty() + : set.__make(newMap); +} + +function makeSet(map, ownerID) { + var set = Object.create(SetPrototype); + set.size = map ? map.size : 0; + set._map = map; + set.__ownerID = ownerID; + return set; +} + +var EMPTY_SET; +function emptySet() { + return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); +} + +/** + * Returns a lazy seq of nums from start (inclusive) to end + * (exclusive), by step, where start defaults to 0, step to 1, and end to + * infinity. When start is equal to end, returns empty list. + */ +var Range = /*@__PURE__*/(function (IndexedSeq) { + function Range(start, end, step) { + if (!(this instanceof Range)) { + // eslint-disable-next-line no-constructor-return + return new Range(start, end, step); + } + invariant(step !== 0, 'Cannot step a Range by 0'); + start = start || 0; + if (end === undefined) { + end = Infinity; + } + step = step === undefined ? 1 : Math.abs(step); + if (end < start) { + step = -step; + } + this._start = start; + this._end = end; + this._step = step; + this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); + if (this.size === 0) { + if (EMPTY_RANGE) { + // eslint-disable-next-line no-constructor-return + return EMPTY_RANGE; + } + EMPTY_RANGE = this; + } + } + + if ( IndexedSeq ) Range.__proto__ = IndexedSeq; + Range.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); + Range.prototype.constructor = Range; + + Range.prototype.toString = function toString () { + if (this.size === 0) { + return 'Range []'; + } + return ( + 'Range [ ' + + this._start + + '...' + + this._end + + (this._step !== 1 ? ' by ' + this._step : '') + + ' ]' + ); + }; + + Range.prototype.get = function get (index, notSetValue) { + return this.has(index) + ? this._start + wrapIndex(this, index) * this._step + : notSetValue; + }; + + Range.prototype.includes = function includes (searchValue) { + var possibleIndex = (searchValue - this._start) / this._step; + return ( + possibleIndex >= 0 && + possibleIndex < this.size && + possibleIndex === Math.floor(possibleIndex) + ); + }; + + Range.prototype.slice = function slice (begin, end) { + if (wholeSlice(begin, end, this.size)) { + return this; + } + begin = resolveBegin(begin, this.size); + end = resolveEnd(end, this.size); + if (end <= begin) { + return new Range(0, 0); + } + return new Range( + this.get(begin, this._end), + this.get(end, this._end), + this._step + ); + }; + + Range.prototype.indexOf = function indexOf (searchValue) { + var offsetValue = searchValue - this._start; + if (offsetValue % this._step === 0) { + var index = offsetValue / this._step; + if (index >= 0 && index < this.size) { + return index; + } + } + return -1; + }; + + Range.prototype.lastIndexOf = function lastIndexOf (searchValue) { + return this.indexOf(searchValue); + }; + + Range.prototype.__iterate = function __iterate (fn, reverse) { + var size = this.size; + var step = this._step; + var value = reverse ? this._start + (size - 1) * step : this._start; + var i = 0; + while (i !== size) { + if (fn(value, reverse ? size - ++i : i++, this) === false) { + break; + } + value += reverse ? -step : step; + } + return i; + }; + + Range.prototype.__iterator = function __iterator (type, reverse) { + var size = this.size; + var step = this._step; + var value = reverse ? this._start + (size - 1) * step : this._start; + var i = 0; + return new Iterator(function () { + if (i === size) { + return iteratorDone(); + } + var v = value; + value += reverse ? -step : step; + return iteratorValue(type, reverse ? size - ++i : i++, v); + }); + }; + + Range.prototype.equals = function equals (other) { + return other instanceof Range + ? this._start === other._start && + this._end === other._end && + this._step === other._step + : deepEqual(this, other); + }; + + return Range; +}(IndexedSeq)); + +var EMPTY_RANGE; + +function getIn$1(collection, searchKeyPath, notSetValue) { + var keyPath = coerceKeyPath(searchKeyPath); + var i = 0; + while (i !== keyPath.length) { + collection = get(collection, keyPath[i++], NOT_SET); + if (collection === NOT_SET) { + return notSetValue; + } + } + return collection; +} + +function getIn(searchKeyPath, notSetValue) { + return getIn$1(this, searchKeyPath, notSetValue); +} + +function hasIn$1(collection, keyPath) { + return getIn$1(collection, keyPath, NOT_SET) !== NOT_SET; +} + +function hasIn(searchKeyPath) { + return hasIn$1(this, searchKeyPath); +} + +function toObject() { + assertNotInfinite(this.size); + var object = {}; + this.__iterate(function (v, k) { + object[k] = v; + }); + return object; +} + +// Note: all of these methods are deprecated. +Collection.isIterable = isCollection; +Collection.isKeyed = isKeyed; +Collection.isIndexed = isIndexed; +Collection.isAssociative = isAssociative; +Collection.isOrdered = isOrdered; + +Collection.Iterator = Iterator; + +mixin(Collection, { + // ### Conversion to other types + + toArray: function toArray() { + assertNotInfinite(this.size); + var array = new Array(this.size || 0); + var useTuples = isKeyed(this); + var i = 0; + this.__iterate(function (v, k) { + // Keyed collections produce an array of tuples. + array[i++] = useTuples ? [k, v] : v; + }); + return array; + }, + + toIndexedSeq: function toIndexedSeq() { + return new ToIndexedSequence(this); + }, + + toJS: function toJS$1() { + return toJS(this); + }, + + toKeyedSeq: function toKeyedSeq() { + return new ToKeyedSequence(this, true); + }, + + toMap: function toMap() { + // Use Late Binding here to solve the circular dependency. + return Map(this.toKeyedSeq()); + }, + + toObject: toObject, + + toOrderedMap: function toOrderedMap() { + // Use Late Binding here to solve the circular dependency. + return OrderedMap(this.toKeyedSeq()); + }, + + toOrderedSet: function toOrderedSet() { + // Use Late Binding here to solve the circular dependency. + return OrderedSet(isKeyed(this) ? this.valueSeq() : this); + }, + + toSet: function toSet() { + // Use Late Binding here to solve the circular dependency. + return Set(isKeyed(this) ? this.valueSeq() : this); + }, + + toSetSeq: function toSetSeq() { + return new ToSetSequence(this); + }, + + toSeq: function toSeq() { + return isIndexed(this) + ? this.toIndexedSeq() + : isKeyed(this) + ? this.toKeyedSeq() + : this.toSetSeq(); + }, + + toStack: function toStack() { + // Use Late Binding here to solve the circular dependency. + return Stack(isKeyed(this) ? this.valueSeq() : this); + }, + + toList: function toList() { + // Use Late Binding here to solve the circular dependency. + return List(isKeyed(this) ? this.valueSeq() : this); + }, + + // ### Common JavaScript methods and properties + + toString: function toString() { + return '[Collection]'; + }, + + __toString: function __toString(head, tail) { + if (this.size === 0) { + return head + tail; + } + return ( + head + + ' ' + + this.toSeq().map(this.__toStringMapper).join(', ') + + ' ' + + tail + ); + }, + + // ### ES6 Collection methods (ES6 Array and Map) + + concat: function concat() { + var values = [], len = arguments.length; + while ( len-- ) values[ len ] = arguments[ len ]; + + return reify(this, concatFactory(this, values)); + }, + + includes: function includes(searchValue) { + return this.some(function (value) { return is(value, searchValue); }); + }, + + entries: function entries() { + return this.__iterator(ITERATE_ENTRIES); + }, + + every: function every(predicate, context) { + assertNotInfinite(this.size); + var returnValue = true; + this.__iterate(function (v, k, c) { + if (!predicate.call(context, v, k, c)) { + returnValue = false; + return false; + } + }); + return returnValue; + }, + + filter: function filter(predicate, context) { + return reify(this, filterFactory(this, predicate, context, true)); + }, + + partition: function partition(predicate, context) { + return partitionFactory(this, predicate, context); + }, + + find: function find(predicate, context, notSetValue) { + var entry = this.findEntry(predicate, context); + return entry ? entry[1] : notSetValue; + }, + + forEach: function forEach(sideEffect, context) { + assertNotInfinite(this.size); + return this.__iterate(context ? sideEffect.bind(context) : sideEffect); + }, + + join: function join(separator) { + assertNotInfinite(this.size); + separator = separator !== undefined ? '' + separator : ','; + var joined = ''; + var isFirst = true; + this.__iterate(function (v) { + isFirst ? (isFirst = false) : (joined += separator); + joined += v !== null && v !== undefined ? v.toString() : ''; + }); + return joined; + }, + + keys: function keys() { + return this.__iterator(ITERATE_KEYS); + }, + + map: function map(mapper, context) { + return reify(this, mapFactory(this, mapper, context)); + }, + + reduce: function reduce$1(reducer, initialReduction, context) { + return reduce( + this, + reducer, + initialReduction, + context, + arguments.length < 2, + false + ); + }, + + reduceRight: function reduceRight(reducer, initialReduction, context) { + return reduce( + this, + reducer, + initialReduction, + context, + arguments.length < 2, + true + ); + }, + + reverse: function reverse() { + return reify(this, reverseFactory(this, true)); + }, + + slice: function slice(begin, end) { + return reify(this, sliceFactory(this, begin, end, true)); + }, + + some: function some(predicate, context) { + assertNotInfinite(this.size); + var returnValue = false; + this.__iterate(function (v, k, c) { + if (predicate.call(context, v, k, c)) { + returnValue = true; + return false; + } + }); + return returnValue; + }, + + sort: function sort(comparator) { + return reify(this, sortFactory(this, comparator)); + }, + + values: function values() { + return this.__iterator(ITERATE_VALUES); + }, + + // ### More sequential methods + + butLast: function butLast() { + return this.slice(0, -1); + }, + + isEmpty: function isEmpty() { + return this.size !== undefined ? this.size === 0 : !this.some(function () { return true; }); + }, + + count: function count(predicate, context) { + return ensureSize( + predicate ? this.toSeq().filter(predicate, context) : this + ); + }, + + countBy: function countBy(grouper, context) { + return countByFactory(this, grouper, context); + }, + + equals: function equals(other) { + return deepEqual(this, other); + }, + + entrySeq: function entrySeq() { + var collection = this; + if (collection._cache) { + // We cache as an entries array, so we can just return the cache! + return new ArraySeq(collection._cache); + } + var entriesSequence = collection.toSeq().map(entryMapper).toIndexedSeq(); + entriesSequence.fromEntrySeq = function () { return collection.toSeq(); }; + return entriesSequence; + }, + + filterNot: function filterNot(predicate, context) { + return this.filter(not(predicate), context); + }, + + findEntry: function findEntry(predicate, context, notSetValue) { + var found = notSetValue; + this.__iterate(function (v, k, c) { + if (predicate.call(context, v, k, c)) { + found = [k, v]; + return false; + } + }); + return found; + }, + + findKey: function findKey(predicate, context) { + var entry = this.findEntry(predicate, context); + return entry && entry[0]; + }, + + findLast: function findLast(predicate, context, notSetValue) { + return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); + }, + + findLastEntry: function findLastEntry(predicate, context, notSetValue) { + return this.toKeyedSeq() + .reverse() + .findEntry(predicate, context, notSetValue); + }, + + findLastKey: function findLastKey(predicate, context) { + return this.toKeyedSeq().reverse().findKey(predicate, context); + }, + + first: function first(notSetValue) { + return this.find(returnTrue, null, notSetValue); + }, + + flatMap: function flatMap(mapper, context) { + return reify(this, flatMapFactory(this, mapper, context)); + }, + + flatten: function flatten(depth) { + return reify(this, flattenFactory(this, depth, true)); + }, + + fromEntrySeq: function fromEntrySeq() { + return new FromEntriesSequence(this); + }, + + get: function get(searchKey, notSetValue) { + return this.find(function (_, key) { return is(key, searchKey); }, undefined, notSetValue); + }, + + getIn: getIn, + + groupBy: function groupBy(grouper, context) { + return groupByFactory(this, grouper, context); + }, + + has: function has(searchKey) { + return this.get(searchKey, NOT_SET) !== NOT_SET; + }, + + hasIn: hasIn, + + isSubset: function isSubset(iter) { + iter = typeof iter.includes === 'function' ? iter : Collection(iter); + return this.every(function (value) { return iter.includes(value); }); + }, + + isSuperset: function isSuperset(iter) { + iter = typeof iter.isSubset === 'function' ? iter : Collection(iter); + return iter.isSubset(this); + }, + + keyOf: function keyOf(searchValue) { + return this.findKey(function (value) { return is(value, searchValue); }); + }, + + keySeq: function keySeq() { + return this.toSeq().map(keyMapper).toIndexedSeq(); + }, + + last: function last(notSetValue) { + return this.toSeq().reverse().first(notSetValue); + }, + + lastKeyOf: function lastKeyOf(searchValue) { + return this.toKeyedSeq().reverse().keyOf(searchValue); + }, + + max: function max(comparator) { + return maxFactory(this, comparator); + }, + + maxBy: function maxBy(mapper, comparator) { + return maxFactory(this, comparator, mapper); + }, + + min: function min(comparator) { + return maxFactory( + this, + comparator ? neg(comparator) : defaultNegComparator + ); + }, + + minBy: function minBy(mapper, comparator) { + return maxFactory( + this, + comparator ? neg(comparator) : defaultNegComparator, + mapper + ); + }, + + rest: function rest() { + return this.slice(1); + }, + + skip: function skip(amount) { + return amount === 0 ? this : this.slice(Math.max(0, amount)); + }, + + skipLast: function skipLast(amount) { + return amount === 0 ? this : this.slice(0, -Math.max(0, amount)); + }, + + skipWhile: function skipWhile(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, true)); + }, + + skipUntil: function skipUntil(predicate, context) { + return this.skipWhile(not(predicate), context); + }, + + sortBy: function sortBy(mapper, comparator) { + return reify(this, sortFactory(this, comparator, mapper)); + }, + + take: function take(amount) { + return this.slice(0, Math.max(0, amount)); + }, + + takeLast: function takeLast(amount) { + return this.slice(-Math.max(0, amount)); + }, + + takeWhile: function takeWhile(predicate, context) { + return reify(this, takeWhileFactory(this, predicate, context)); + }, + + takeUntil: function takeUntil(predicate, context) { + return this.takeWhile(not(predicate), context); + }, + + update: function update(fn) { + return fn(this); + }, + + valueSeq: function valueSeq() { + return this.toIndexedSeq(); + }, + + // ### Hashable Object + + hashCode: function hashCode() { + return this.__hash || (this.__hash = hashCollection(this)); + }, + + // ### Internal + + // abstract __iterate(fn, reverse) + + // abstract __iterator(type, reverse) +}); + +var CollectionPrototype = Collection.prototype; +CollectionPrototype[IS_COLLECTION_SYMBOL] = true; +CollectionPrototype[ITERATOR_SYMBOL] = CollectionPrototype.values; +CollectionPrototype.toJSON = CollectionPrototype.toArray; +CollectionPrototype.__toStringMapper = quoteString; +CollectionPrototype.inspect = CollectionPrototype.toSource = function () { + return this.toString(); +}; +CollectionPrototype.chain = CollectionPrototype.flatMap; +CollectionPrototype.contains = CollectionPrototype.includes; + +mixin(KeyedCollection, { + // ### More sequential methods + + flip: function flip() { + return reify(this, flipFactory(this)); + }, + + mapEntries: function mapEntries(mapper, context) { + var this$1$1 = this; + + var iterations = 0; + return reify( + this, + this.toSeq() + .map(function (v, k) { return mapper.call(context, [k, v], iterations++, this$1$1); }) + .fromEntrySeq() + ); + }, + + mapKeys: function mapKeys(mapper, context) { + var this$1$1 = this; + + return reify( + this, + this.toSeq() + .flip() + .map(function (k, v) { return mapper.call(context, k, v, this$1$1); }) + .flip() + ); + }, +}); + +var KeyedCollectionPrototype = KeyedCollection.prototype; +KeyedCollectionPrototype[IS_KEYED_SYMBOL] = true; +KeyedCollectionPrototype[ITERATOR_SYMBOL] = CollectionPrototype.entries; +KeyedCollectionPrototype.toJSON = toObject; +KeyedCollectionPrototype.__toStringMapper = function (v, k) { return quoteString(k) + ': ' + quoteString(v); }; + +mixin(IndexedCollection, { + // ### Conversion to other types + + toKeyedSeq: function toKeyedSeq() { + return new ToKeyedSequence(this, false); + }, + + // ### ES6 Collection methods (ES6 Array and Map) + + filter: function filter(predicate, context) { + return reify(this, filterFactory(this, predicate, context, false)); + }, + + findIndex: function findIndex(predicate, context) { + var entry = this.findEntry(predicate, context); + return entry ? entry[0] : -1; + }, + + indexOf: function indexOf(searchValue) { + var key = this.keyOf(searchValue); + return key === undefined ? -1 : key; + }, + + lastIndexOf: function lastIndexOf(searchValue) { + var key = this.lastKeyOf(searchValue); + return key === undefined ? -1 : key; + }, + + reverse: function reverse() { + return reify(this, reverseFactory(this, false)); + }, + + slice: function slice(begin, end) { + return reify(this, sliceFactory(this, begin, end, false)); + }, + + splice: function splice(index, removeNum /*, ...values*/) { + var numArgs = arguments.length; + removeNum = Math.max(removeNum || 0, 0); + if (numArgs === 0 || (numArgs === 2 && !removeNum)) { + return this; + } + // If index is negative, it should resolve relative to the size of the + // collection. However size may be expensive to compute if not cached, so + // only call count() if the number is in fact negative. + index = resolveBegin(index, index < 0 ? this.count() : this.size); + var spliced = this.slice(0, index); + return reify( + this, + numArgs === 1 + ? spliced + : spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) + ); + }, + + // ### More collection methods + + findLastIndex: function findLastIndex(predicate, context) { + var entry = this.findLastEntry(predicate, context); + return entry ? entry[0] : -1; + }, + + first: function first(notSetValue) { + return this.get(0, notSetValue); + }, + + flatten: function flatten(depth) { + return reify(this, flattenFactory(this, depth, false)); + }, + + get: function get(index, notSetValue) { + index = wrapIndex(this, index); + return index < 0 || + this.size === Infinity || + (this.size !== undefined && index > this.size) + ? notSetValue + : this.find(function (_, key) { return key === index; }, undefined, notSetValue); + }, + + has: function has(index) { + index = wrapIndex(this, index); + return ( + index >= 0 && + (this.size !== undefined + ? this.size === Infinity || index < this.size + : this.indexOf(index) !== -1) + ); + }, + + interpose: function interpose(separator) { + return reify(this, interposeFactory(this, separator)); + }, + + interleave: function interleave(/*...collections*/) { + var collections = [this].concat(arrCopy(arguments)); + var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, collections); + var interleaved = zipped.flatten(true); + if (zipped.size) { + interleaved.size = zipped.size * collections.length; + } + return reify(this, interleaved); + }, + + keySeq: function keySeq() { + return Range(0, this.size); + }, + + last: function last(notSetValue) { + return this.get(-1, notSetValue); + }, + + skipWhile: function skipWhile(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, false)); + }, + + zip: function zip(/*, ...collections */) { + var collections = [this].concat(arrCopy(arguments)); + return reify(this, zipWithFactory(this, defaultZipper, collections)); + }, + + zipAll: function zipAll(/*, ...collections */) { + var collections = [this].concat(arrCopy(arguments)); + return reify(this, zipWithFactory(this, defaultZipper, collections, true)); + }, + + zipWith: function zipWith(zipper /*, ...collections */) { + var collections = arrCopy(arguments); + collections[0] = this; + return reify(this, zipWithFactory(this, zipper, collections)); + }, +}); + +var IndexedCollectionPrototype = IndexedCollection.prototype; +IndexedCollectionPrototype[IS_INDEXED_SYMBOL] = true; +IndexedCollectionPrototype[IS_ORDERED_SYMBOL] = true; + +mixin(SetCollection, { + // ### ES6 Collection methods (ES6 Array and Map) + + get: function get(value, notSetValue) { + return this.has(value) ? value : notSetValue; + }, + + includes: function includes(value) { + return this.has(value); + }, + + // ### More sequential methods + + keySeq: function keySeq() { + return this.valueSeq(); + }, +}); + +var SetCollectionPrototype = SetCollection.prototype; +SetCollectionPrototype.has = CollectionPrototype.includes; +SetCollectionPrototype.contains = SetCollectionPrototype.includes; +SetCollectionPrototype.keys = SetCollectionPrototype.values; + +// Mixin subclasses + +mixin(KeyedSeq, KeyedCollectionPrototype); +mixin(IndexedSeq, IndexedCollectionPrototype); +mixin(SetSeq, SetCollectionPrototype); + +// #pragma Helper functions + +function reduce(collection, reducer, reduction, context, useFirst, reverse) { + assertNotInfinite(collection.size); + collection.__iterate(function (v, k, c) { + if (useFirst) { + useFirst = false; + reduction = v; + } else { + reduction = reducer.call(context, reduction, v, k, c); + } + }, reverse); + return reduction; +} + +function keyMapper(v, k) { + return k; +} + +function entryMapper(v, k) { + return [k, v]; +} + +function not(predicate) { + return function () { + return !predicate.apply(this, arguments); + }; +} + +function neg(predicate) { + return function () { + return -predicate.apply(this, arguments); + }; +} + +function defaultZipper() { + return arrCopy(arguments); +} + +function defaultNegComparator(a, b) { + return a < b ? 1 : a > b ? -1 : 0; +} + +function hashCollection(collection) { + if (collection.size === Infinity) { + return 0; + } + var ordered = isOrdered(collection); + var keyed = isKeyed(collection); + var h = ordered ? 1 : 0; + var size = collection.__iterate( + keyed + ? ordered + ? function (v, k) { + h = (31 * h + hashMerge(hash(v), hash(k))) | 0; + } + : function (v, k) { + h = (h + hashMerge(hash(v), hash(k))) | 0; + } + : ordered + ? function (v) { + h = (31 * h + hash(v)) | 0; + } + : function (v) { + h = (h + hash(v)) | 0; + } + ); + return murmurHashOfSize(size, h); +} + +function murmurHashOfSize(size, h) { + h = imul(h, 0xcc9e2d51); + h = imul((h << 15) | (h >>> -15), 0x1b873593); + h = imul((h << 13) | (h >>> -13), 5); + h = ((h + 0xe6546b64) | 0) ^ size; + h = imul(h ^ (h >>> 16), 0x85ebca6b); + h = imul(h ^ (h >>> 13), 0xc2b2ae35); + h = smi(h ^ (h >>> 16)); + return h; +} + +function hashMerge(a, b) { + return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; // int +} + +var OrderedSet = /*@__PURE__*/(function (Set) { + function OrderedSet(value) { + // eslint-disable-next-line no-constructor-return + return value === undefined || value === null + ? emptyOrderedSet() + : isOrderedSet(value) + ? value + : emptyOrderedSet().withMutations(function (set) { + var iter = SetCollection(value); + assertNotInfinite(iter.size); + iter.forEach(function (v) { return set.add(v); }); + }); + } + + if ( Set ) OrderedSet.__proto__ = Set; + OrderedSet.prototype = Object.create( Set && Set.prototype ); + OrderedSet.prototype.constructor = OrderedSet; + + OrderedSet.of = function of (/*...values*/) { + return this(arguments); + }; + + OrderedSet.fromKeys = function fromKeys (value) { + return this(KeyedCollection(value).keySeq()); + }; + + OrderedSet.prototype.toString = function toString () { + return this.__toString('OrderedSet {', '}'); + }; + + return OrderedSet; +}(Set)); + +OrderedSet.isOrderedSet = isOrderedSet; + +var OrderedSetPrototype = OrderedSet.prototype; +OrderedSetPrototype[IS_ORDERED_SYMBOL] = true; +OrderedSetPrototype.zip = IndexedCollectionPrototype.zip; +OrderedSetPrototype.zipWith = IndexedCollectionPrototype.zipWith; +OrderedSetPrototype.zipAll = IndexedCollectionPrototype.zipAll; + +OrderedSetPrototype.__empty = emptyOrderedSet; +OrderedSetPrototype.__make = makeOrderedSet; + +function makeOrderedSet(map, ownerID) { + var set = Object.create(OrderedSetPrototype); + set.size = map ? map.size : 0; + set._map = map; + set.__ownerID = ownerID; + return set; +} + +var EMPTY_ORDERED_SET; +function emptyOrderedSet() { + return ( + EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())) + ); +} + +var PairSorting = { + LeftThenRight: -1, + RightThenLeft: +1, +}; + +function throwOnInvalidDefaultValues(defaultValues) { + if (isRecord(defaultValues)) { + throw new Error( + 'Can not call `Record` with an immutable Record as default values. Use a plain javascript object instead.' + ); + } + + if (isImmutable(defaultValues)) { + throw new Error( + 'Can not call `Record` with an immutable Collection as default values. Use a plain javascript object instead.' + ); + } + + if (defaultValues === null || typeof defaultValues !== 'object') { + throw new Error( + 'Can not call `Record` with a non-object as default values. Use a plain javascript object instead.' + ); + } +} + +var Record = function Record(defaultValues, name) { + var hasInitialized; + + throwOnInvalidDefaultValues(defaultValues); + + var RecordType = function Record(values) { + var this$1$1 = this; + + if (values instanceof RecordType) { + return values; + } + if (!(this instanceof RecordType)) { + return new RecordType(values); + } + if (!hasInitialized) { + hasInitialized = true; + var keys = Object.keys(defaultValues); + var indices = (RecordTypePrototype._indices = {}); + // Deprecated: left to attempt not to break any external code which + // relies on a ._name property existing on record instances. + // Use Record.getDescriptiveName() instead + RecordTypePrototype._name = name; + RecordTypePrototype._keys = keys; + RecordTypePrototype._defaultValues = defaultValues; + for (var i = 0; i < keys.length; i++) { + var propName = keys[i]; + indices[propName] = i; + if (RecordTypePrototype[propName]) { + /* eslint-disable no-console */ + typeof console === 'object' && + console.warn && + console.warn( + 'Cannot define ' + + recordName(this) + + ' with property "' + + propName + + '" since that property name is part of the Record API.' + ); + /* eslint-enable no-console */ + } else { + setProp(RecordTypePrototype, propName); + } + } + } + this.__ownerID = undefined; + this._values = List().withMutations(function (l) { + l.setSize(this$1$1._keys.length); + KeyedCollection(values).forEach(function (v, k) { + l.set(this$1$1._indices[k], v === this$1$1._defaultValues[k] ? undefined : v); + }); + }); + return this; + }; + + var RecordTypePrototype = (RecordType.prototype = + Object.create(RecordPrototype)); + RecordTypePrototype.constructor = RecordType; + + if (name) { + RecordType.displayName = name; + } + + // eslint-disable-next-line no-constructor-return + return RecordType; +}; + +Record.prototype.toString = function toString () { + var str = recordName(this) + ' { '; + var keys = this._keys; + var k; + for (var i = 0, l = keys.length; i !== l; i++) { + k = keys[i]; + str += (i ? ', ' : '') + k + ': ' + quoteString(this.get(k)); + } + return str + ' }'; +}; + +Record.prototype.equals = function equals (other) { + return ( + this === other || + (isRecord(other) && recordSeq(this).equals(recordSeq(other))) + ); +}; + +Record.prototype.hashCode = function hashCode () { + return recordSeq(this).hashCode(); +}; + +// @pragma Access + +Record.prototype.has = function has (k) { + return this._indices.hasOwnProperty(k); +}; + +Record.prototype.get = function get (k, notSetValue) { + if (!this.has(k)) { + return notSetValue; + } + var index = this._indices[k]; + var value = this._values.get(index); + return value === undefined ? this._defaultValues[k] : value; +}; + +// @pragma Modification + +Record.prototype.set = function set (k, v) { + if (this.has(k)) { + var newValues = this._values.set( + this._indices[k], + v === this._defaultValues[k] ? undefined : v + ); + if (newValues !== this._values && !this.__ownerID) { + return makeRecord(this, newValues); + } + } + return this; +}; + +Record.prototype.remove = function remove (k) { + return this.set(k); +}; + +Record.prototype.clear = function clear () { + var newValues = this._values.clear().setSize(this._keys.length); + + return this.__ownerID ? this : makeRecord(this, newValues); +}; + +Record.prototype.wasAltered = function wasAltered () { + return this._values.wasAltered(); +}; + +Record.prototype.toSeq = function toSeq () { + return recordSeq(this); +}; + +Record.prototype.toJS = function toJS$1 () { + return toJS(this); +}; + +Record.prototype.entries = function entries () { + return this.__iterator(ITERATE_ENTRIES); +}; + +Record.prototype.__iterator = function __iterator (type, reverse) { + return recordSeq(this).__iterator(type, reverse); +}; + +Record.prototype.__iterate = function __iterate (fn, reverse) { + return recordSeq(this).__iterate(fn, reverse); +}; + +Record.prototype.__ensureOwner = function __ensureOwner (ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newValues = this._values.__ensureOwner(ownerID); + if (!ownerID) { + this.__ownerID = ownerID; + this._values = newValues; + return this; + } + return makeRecord(this, newValues, ownerID); +}; + +Record.isRecord = isRecord; +Record.getDescriptiveName = recordName; +var RecordPrototype = Record.prototype; +RecordPrototype[IS_RECORD_SYMBOL] = true; +RecordPrototype[DELETE] = RecordPrototype.remove; +RecordPrototype.deleteIn = RecordPrototype.removeIn = deleteIn; +RecordPrototype.getIn = getIn; +RecordPrototype.hasIn = CollectionPrototype.hasIn; +RecordPrototype.merge = merge$1; +RecordPrototype.mergeWith = mergeWith$1; +RecordPrototype.mergeIn = mergeIn; +RecordPrototype.mergeDeep = mergeDeep; +RecordPrototype.mergeDeepWith = mergeDeepWith; +RecordPrototype.mergeDeepIn = mergeDeepIn; +RecordPrototype.setIn = setIn; +RecordPrototype.update = update; +RecordPrototype.updateIn = updateIn; +RecordPrototype.withMutations = withMutations; +RecordPrototype.asMutable = asMutable; +RecordPrototype.asImmutable = asImmutable; +RecordPrototype[ITERATOR_SYMBOL] = RecordPrototype.entries; +RecordPrototype.toJSON = RecordPrototype.toObject = + CollectionPrototype.toObject; +RecordPrototype.inspect = RecordPrototype.toSource = function () { + return this.toString(); +}; + +function makeRecord(likeRecord, values, ownerID) { + var record = Object.create(Object.getPrototypeOf(likeRecord)); + record._values = values; + record.__ownerID = ownerID; + return record; +} + +function recordName(record) { + return record.constructor.displayName || record.constructor.name || 'Record'; +} + +function recordSeq(record) { + return keyedSeqFromValue(record._keys.map(function (k) { return [k, record.get(k)]; })); +} + +function setProp(prototype, name) { + try { + Object.defineProperty(prototype, name, { + get: function () { + return this.get(name); + }, + set: function (value) { + invariant(this.__ownerID, 'Cannot set on an immutable record.'); + this.set(name, value); + }, + }); + } catch (error) { + // Object.defineProperty failed. Probably IE8. + } +} + +/** + * Returns a lazy Seq of `value` repeated `times` times. When `times` is + * undefined, returns an infinite sequence of `value`. + */ +var Repeat = /*@__PURE__*/(function (IndexedSeq) { + function Repeat(value, times) { + if (!(this instanceof Repeat)) { + // eslint-disable-next-line no-constructor-return + return new Repeat(value, times); + } + this._value = value; + this.size = times === undefined ? Infinity : Math.max(0, times); + if (this.size === 0) { + if (EMPTY_REPEAT) { + // eslint-disable-next-line no-constructor-return + return EMPTY_REPEAT; + } + EMPTY_REPEAT = this; + } + } + + if ( IndexedSeq ) Repeat.__proto__ = IndexedSeq; + Repeat.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); + Repeat.prototype.constructor = Repeat; + + Repeat.prototype.toString = function toString () { + if (this.size === 0) { + return 'Repeat []'; + } + return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; + }; + + Repeat.prototype.get = function get (index, notSetValue) { + return this.has(index) ? this._value : notSetValue; + }; + + Repeat.prototype.includes = function includes (searchValue) { + return is(this._value, searchValue); + }; + + Repeat.prototype.slice = function slice (begin, end) { + var size = this.size; + return wholeSlice(begin, end, size) + ? this + : new Repeat( + this._value, + resolveEnd(end, size) - resolveBegin(begin, size) + ); + }; + + Repeat.prototype.reverse = function reverse () { + return this; + }; + + Repeat.prototype.indexOf = function indexOf (searchValue) { + if (is(this._value, searchValue)) { + return 0; + } + return -1; + }; + + Repeat.prototype.lastIndexOf = function lastIndexOf (searchValue) { + if (is(this._value, searchValue)) { + return this.size; + } + return -1; + }; + + Repeat.prototype.__iterate = function __iterate (fn, reverse) { + var size = this.size; + var i = 0; + while (i !== size) { + if (fn(this._value, reverse ? size - ++i : i++, this) === false) { + break; + } + } + return i; + }; + + Repeat.prototype.__iterator = function __iterator (type, reverse) { + var this$1$1 = this; + + var size = this.size; + var i = 0; + return new Iterator(function () { return i === size + ? iteratorDone() + : iteratorValue(type, reverse ? size - ++i : i++, this$1$1._value); } + ); + }; + + Repeat.prototype.equals = function equals (other) { + return other instanceof Repeat + ? is(this._value, other._value) + : deepEqual(this, other); + }; + + return Repeat; +}(IndexedSeq)); + +var EMPTY_REPEAT; + +function fromJS(value, converter) { + return fromJSWith( + [], + converter || defaultConverter, + value, + '', + converter && converter.length > 2 ? [] : undefined, + { '': value } + ); +} + +function fromJSWith(stack, converter, value, key, keyPath, parentValue) { + if ( + typeof value !== 'string' && + !isImmutable(value) && + (isArrayLike(value) || hasIterator(value) || isPlainObject(value)) + ) { + if (~stack.indexOf(value)) { + throw new TypeError('Cannot convert circular structure to Immutable'); + } + stack.push(value); + keyPath && key !== '' && keyPath.push(key); + var converted = converter.call( + parentValue, + key, + Seq(value).map(function (v, k) { return fromJSWith(stack, converter, v, k, keyPath, value); } + ), + keyPath && keyPath.slice() + ); + stack.pop(); + keyPath && keyPath.pop(); + return converted; + } + return value; +} + +function defaultConverter(k, v) { + // Effectively the opposite of "Collection.toSeq()" + return isIndexed(v) ? v.toList() : isKeyed(v) ? v.toMap() : v.toSet(); +} + +var version = "4.3.7"; + +var Immutable = { + version: version, + + Collection: Collection, + // Note: Iterable is deprecated + Iterable: Collection, + + Seq: Seq, + Map: Map, + OrderedMap: OrderedMap, + List: List, + Stack: Stack, + Set: Set, + OrderedSet: OrderedSet, + PairSorting: PairSorting, + + Record: Record, + Range: Range, + Repeat: Repeat, + + is: is, + fromJS: fromJS, + hash: hash, + + isImmutable: isImmutable, + isCollection: isCollection, + isKeyed: isKeyed, + isIndexed: isIndexed, + isAssociative: isAssociative, + isOrdered: isOrdered, + isValueObject: isValueObject, + isPlainObject: isPlainObject, + isSeq: isSeq, + isList: isList, + isMap: isMap, + isOrderedMap: isOrderedMap, + isStack: isStack, + isSet: isSet, + isOrderedSet: isOrderedSet, + isRecord: isRecord, + + get: get, + getIn: getIn$1, + has: has, + hasIn: hasIn$1, + merge: merge, + mergeDeep: mergeDeep$1, + mergeWith: mergeWith, + mergeDeepWith: mergeDeepWith$1, + remove: remove, + removeIn: removeIn, + set: set, + setIn: setIn$1, + update: update$1, + updateIn: updateIn$1, +}; + +// Note: Iterable is deprecated +var Iterable = Collection; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Immutable); + + + +/***/ }), + +/***/ "?1e65": +/*!************************!*\ + !*** assert (ignored) ***! + \************************/ +/***/ (() => { + +/* (ignored) */ + +/***/ }), + +/***/ "./node_modules/goober/dist/goober.modern.js": +/*!***************************************************!*\ + !*** ./node_modules/goober/dist/goober.modern.js ***! + \***************************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ css: () => (/* binding */ u), +/* harmony export */ extractCss: () => (/* binding */ r), +/* harmony export */ glob: () => (/* binding */ b), +/* harmony export */ keyframes: () => (/* binding */ h), +/* harmony export */ setup: () => (/* binding */ m), +/* harmony export */ styled: () => (/* binding */ j) +/* harmony export */ }); +let e={data:""},t=t=>"object"==typeof window?((t?t.querySelector("#_goober"):window._goober)||Object.assign((t||document.head).appendChild(document.createElement("style")),{innerHTML:" ",id:"_goober"})).firstChild:t||e,r=e=>{let r=t(e),l=r.data;return r.data="",l},l=/(?:([\u0080-\uFFFF\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\s*)/g,a=/\/\*[^]*?\*\/| +/g,n=/\n+/g,o=(e,t)=>{let r="",l="",a="";for(let n in e){let c=e[n];"@"==n[0]?"i"==n[1]?r=n+" "+c+";":l+="f"==n[1]?o(c,n):n+"{"+o(c,"k"==n[1]?"":t)+"}":"object"==typeof c?l+=o(c,t?t.replace(/([^,])+/g,e=>n.replace(/(^:.*)|([^,])+/g,t=>/&/.test(t)?t.replace(/&/g,e):e?e+" "+t:t)):n):null!=c&&(n=/^--/.test(n)?n:n.replace(/[A-Z]/g,"-$&").toLowerCase(),a+=o.p?o.p(n,c):n+":"+c+";")}return r+(t&&a?t+"{"+a+"}":a)+l},c={},s=e=>{if("object"==typeof e){let t="";for(let r in e)t+=r+s(e[r]);return t}return e},i=(e,t,r,i,p)=>{let u=s(e),d=c[u]||(c[u]=(e=>{let t=0,r=11;for(;t>>0;return"go"+r})(u));if(!c[d]){let t=u!==e?e:(e=>{let t,r,o=[{}];for(;t=l.exec(e.replace(a,""));)t[4]?o.shift():t[3]?(r=t[3].replace(n," ").trim(),o.unshift(o[0][r]=o[0][r]||{})):o[0][t[1]]=t[2].replace(n," ").trim();return o[0]})(e);c[d]=o(p?{["@keyframes "+d]:t}:t,r?"":"."+d)}let f=r&&c.g?c.g:null;return r&&(c.g=c[d]),((e,t,r,l)=>{l?t.data=t.data.replace(l,e):-1===t.data.indexOf(e)&&(t.data=r?e+t.data:t.data+e)})(c[d],t,i,f),d},p=(e,t,r)=>e.reduce((e,l,a)=>{let n=t[a];if(n&&n.call){let e=n(r),t=e&&e.props&&e.props.className||/^go/.test(e)&&e;n=t?"."+t:e&&"object"==typeof e?e.props?"":o(e,""):!1===e?"":e}return e+l+(null==n?"":n)},"");function u(e){let r=this||{},l=e.call?e(r.p):e;return i(l.unshift?l.raw?p(l,[].slice.call(arguments,1),r.p):l.reduce((e,t)=>Object.assign(e,t&&t.call?t(r.p):t),{}):l,t(r.target),r.g,r.o,r.k)}let d,f,g,b=u.bind({g:1}),h=u.bind({k:1});function m(e,t,r,l){o.p=t,d=e,f=r,g=l}function j(e,t){let r=this||{};return function(){let l=arguments;function a(n,o){let c=Object.assign({},n),s=c.className||a.className;r.p=Object.assign({theme:f&&f()},c),r.o=/ *go\d+/.test(s),c.className=u.apply(r,l)+(s?" "+s:""),t&&(c.ref=o);let i=e;return e[0]&&(i=c.as||e,delete c.as),g&&i[0]&&g(c),d(i,c)}return t?t(a):a}} + + +/***/ }), + +/***/ "./node_modules/solid-js/dist/dev.js": +/*!*******************************************!*\ + !*** ./node_modules/solid-js/dist/dev.js ***! + \*******************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ $DEVCOMP: () => (/* binding */ $DEVCOMP), +/* harmony export */ $PROXY: () => (/* binding */ $PROXY), +/* harmony export */ $TRACK: () => (/* binding */ $TRACK), +/* harmony export */ DEV: () => (/* binding */ DEV), +/* harmony export */ ErrorBoundary: () => (/* binding */ ErrorBoundary), +/* harmony export */ For: () => (/* binding */ For), +/* harmony export */ Index: () => (/* binding */ Index), +/* harmony export */ Match: () => (/* binding */ Match), +/* harmony export */ Show: () => (/* binding */ Show), +/* harmony export */ Suspense: () => (/* binding */ Suspense), +/* harmony export */ SuspenseList: () => (/* binding */ SuspenseList), +/* harmony export */ Switch: () => (/* binding */ Switch), +/* harmony export */ batch: () => (/* binding */ batch), +/* harmony export */ cancelCallback: () => (/* binding */ cancelCallback), +/* harmony export */ catchError: () => (/* binding */ catchError), +/* harmony export */ children: () => (/* binding */ children), +/* harmony export */ createComponent: () => (/* binding */ createComponent), +/* harmony export */ createComputed: () => (/* binding */ createComputed), +/* harmony export */ createContext: () => (/* binding */ createContext), +/* harmony export */ createDeferred: () => (/* binding */ createDeferred), +/* harmony export */ createEffect: () => (/* binding */ createEffect), +/* harmony export */ createMemo: () => (/* binding */ createMemo), +/* harmony export */ createReaction: () => (/* binding */ createReaction), +/* harmony export */ createRenderEffect: () => (/* binding */ createRenderEffect), +/* harmony export */ createResource: () => (/* binding */ createResource), +/* harmony export */ createRoot: () => (/* binding */ createRoot), +/* harmony export */ createSelector: () => (/* binding */ createSelector), +/* harmony export */ createSignal: () => (/* binding */ createSignal), +/* harmony export */ createUniqueId: () => (/* binding */ createUniqueId), +/* harmony export */ enableExternalSource: () => (/* binding */ enableExternalSource), +/* harmony export */ enableHydration: () => (/* binding */ enableHydration), +/* harmony export */ enableScheduling: () => (/* binding */ enableScheduling), +/* harmony export */ equalFn: () => (/* binding */ equalFn), +/* harmony export */ from: () => (/* binding */ from), +/* harmony export */ getListener: () => (/* binding */ getListener), +/* harmony export */ getOwner: () => (/* binding */ getOwner), +/* harmony export */ indexArray: () => (/* binding */ indexArray), +/* harmony export */ lazy: () => (/* binding */ lazy), +/* harmony export */ mapArray: () => (/* binding */ mapArray), +/* harmony export */ mergeProps: () => (/* binding */ mergeProps), +/* harmony export */ observable: () => (/* binding */ observable), +/* harmony export */ on: () => (/* binding */ on), +/* harmony export */ onCleanup: () => (/* binding */ onCleanup), +/* harmony export */ onError: () => (/* binding */ onError), +/* harmony export */ onMount: () => (/* binding */ onMount), +/* harmony export */ requestCallback: () => (/* binding */ requestCallback), +/* harmony export */ resetErrorBoundaries: () => (/* binding */ resetErrorBoundaries), +/* harmony export */ runWithOwner: () => (/* binding */ runWithOwner), +/* harmony export */ sharedConfig: () => (/* binding */ sharedConfig), +/* harmony export */ splitProps: () => (/* binding */ splitProps), +/* harmony export */ startTransition: () => (/* binding */ startTransition), +/* harmony export */ untrack: () => (/* binding */ untrack), +/* harmony export */ useContext: () => (/* binding */ useContext), +/* harmony export */ useTransition: () => (/* binding */ useTransition) +/* harmony export */ }); +let taskIdCounter = 1, + isCallbackScheduled = false, + isPerformingWork = false, + taskQueue = [], + currentTask = null, + shouldYieldToHost = null, + yieldInterval = 5, + deadline = 0, + maxYieldInterval = 300, + scheduleCallback = null, + scheduledCallback = null; +const maxSigned31BitInt = 1073741823; +function setupScheduler() { + const channel = new MessageChannel(), + port = channel.port2; + scheduleCallback = () => port.postMessage(null); + channel.port1.onmessage = () => { + if (scheduledCallback !== null) { + const currentTime = performance.now(); + deadline = currentTime + yieldInterval; + const hasTimeRemaining = true; + try { + const hasMoreWork = scheduledCallback(hasTimeRemaining, currentTime); + if (!hasMoreWork) { + scheduledCallback = null; + } else port.postMessage(null); + } catch (error) { + port.postMessage(null); + throw error; + } + } + }; + if (navigator && navigator.scheduling && navigator.scheduling.isInputPending) { + const scheduling = navigator.scheduling; + shouldYieldToHost = () => { + const currentTime = performance.now(); + if (currentTime >= deadline) { + if (scheduling.isInputPending()) { + return true; + } + return currentTime >= maxYieldInterval; + } else { + return false; + } + }; + } else { + shouldYieldToHost = () => performance.now() >= deadline; + } +} +function enqueue(taskQueue, task) { + function findIndex() { + let m = 0; + let n = taskQueue.length - 1; + while (m <= n) { + const k = n + m >> 1; + const cmp = task.expirationTime - taskQueue[k].expirationTime; + if (cmp > 0) m = k + 1;else if (cmp < 0) n = k - 1;else return k; + } + return m; + } + taskQueue.splice(findIndex(), 0, task); +} +function requestCallback(fn, options) { + if (!scheduleCallback) setupScheduler(); + let startTime = performance.now(), + timeout = maxSigned31BitInt; + if (options && options.timeout) timeout = options.timeout; + const newTask = { + id: taskIdCounter++, + fn, + startTime, + expirationTime: startTime + timeout + }; + enqueue(taskQueue, newTask); + if (!isCallbackScheduled && !isPerformingWork) { + isCallbackScheduled = true; + scheduledCallback = flushWork; + scheduleCallback(); + } + return newTask; +} +function cancelCallback(task) { + task.fn = null; +} +function flushWork(hasTimeRemaining, initialTime) { + isCallbackScheduled = false; + isPerformingWork = true; + try { + return workLoop(hasTimeRemaining, initialTime); + } finally { + currentTask = null; + isPerformingWork = false; + } +} +function workLoop(hasTimeRemaining, initialTime) { + let currentTime = initialTime; + currentTask = taskQueue[0] || null; + while (currentTask !== null) { + if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) { + break; + } + const callback = currentTask.fn; + if (callback !== null) { + currentTask.fn = null; + const didUserCallbackTimeout = currentTask.expirationTime <= currentTime; + callback(didUserCallbackTimeout); + currentTime = performance.now(); + if (currentTask === taskQueue[0]) { + taskQueue.shift(); + } + } else taskQueue.shift(); + currentTask = taskQueue[0] || null; + } + return currentTask !== null; +} + +const sharedConfig = { + context: undefined, + registry: undefined, + effects: undefined, + done: false, + getContextId() { + return getContextId(this.context.count); + }, + getNextContextId() { + return getContextId(this.context.count++); + } +}; +function getContextId(count) { + const num = String(count), + len = num.length - 1; + return sharedConfig.context.id + (len ? String.fromCharCode(96 + len) : "") + num; +} +function setHydrateContext(context) { + sharedConfig.context = context; +} +function nextHydrateContext() { + return { + ...sharedConfig.context, + id: sharedConfig.getNextContextId(), + count: 0 + }; +} + +const equalFn = (a, b) => a === b; +const $PROXY = Symbol("solid-proxy"); +const $TRACK = Symbol("solid-track"); +const $DEVCOMP = Symbol("solid-dev-component"); +const signalOptions = { + equals: equalFn +}; +let ERROR = null; +let runEffects = runQueue; +const STALE = 1; +const PENDING = 2; +const UNOWNED = { + owned: null, + cleanups: null, + context: null, + owner: null +}; +const NO_INIT = {}; +var Owner = null; +let Transition = null; +let Scheduler = null; +let ExternalSourceConfig = null; +let Listener = null; +let Updates = null; +let Effects = null; +let ExecCount = 0; +const DevHooks = { + afterUpdate: null, + afterCreateOwner: null, + afterCreateSignal: null +}; +function createRoot(fn, detachedOwner) { + const listener = Listener, + owner = Owner, + unowned = fn.length === 0, + current = detachedOwner === undefined ? owner : detachedOwner, + root = unowned ? { + owned: null, + cleanups: null, + context: null, + owner: null + } : { + owned: null, + cleanups: null, + context: current ? current.context : null, + owner: current + }, + updateFn = unowned ? () => fn(() => { + throw new Error("Dispose method must be an explicit argument to createRoot function"); + }) : () => fn(() => untrack(() => cleanNode(root))); + DevHooks.afterCreateOwner && DevHooks.afterCreateOwner(root); + Owner = root; + Listener = null; + try { + return runUpdates(updateFn, true); + } finally { + Listener = listener; + Owner = owner; + } +} +function createSignal(value, options) { + options = options ? Object.assign({}, signalOptions, options) : signalOptions; + const s = { + value, + observers: null, + observerSlots: null, + comparator: options.equals || undefined + }; + { + if (options.name) s.name = options.name; + if (DevHooks.afterCreateSignal) DevHooks.afterCreateSignal(s); + if (!options.internal) registerGraph(s); + } + const setter = value => { + if (typeof value === "function") { + if (Transition && Transition.running && Transition.sources.has(s)) value = value(s.tValue);else value = value(s.value); + } + return writeSignal(s, value); + }; + return [readSignal.bind(s), setter]; +} +function createComputed(fn, value, options) { + const c = createComputation(fn, value, true, STALE, options ); + if (Scheduler && Transition && Transition.running) Updates.push(c);else updateComputation(c); +} +function createRenderEffect(fn, value, options) { + const c = createComputation(fn, value, false, STALE, options ); + if (Scheduler && Transition && Transition.running) Updates.push(c);else updateComputation(c); +} +function createEffect(fn, value, options) { + runEffects = runUserEffects; + const c = createComputation(fn, value, false, STALE, options ), + s = SuspenseContext && useContext(SuspenseContext); + if (s) c.suspense = s; + if (!options || !options.render) c.user = true; + Effects ? Effects.push(c) : updateComputation(c); +} +function createReaction(onInvalidate, options) { + let fn; + const c = createComputation(() => { + fn ? fn() : untrack(onInvalidate); + fn = undefined; + }, undefined, false, 0, options ), + s = SuspenseContext && useContext(SuspenseContext); + if (s) c.suspense = s; + c.user = true; + return tracking => { + fn = tracking; + updateComputation(c); + }; +} +function createMemo(fn, value, options) { + options = options ? Object.assign({}, signalOptions, options) : signalOptions; + const c = createComputation(fn, value, true, 0, options ); + c.observers = null; + c.observerSlots = null; + c.comparator = options.equals || undefined; + if (Scheduler && Transition && Transition.running) { + c.tState = STALE; + Updates.push(c); + } else updateComputation(c); + return readSignal.bind(c); +} +function isPromise(v) { + return v && typeof v === "object" && "then" in v; +} +function createResource(pSource, pFetcher, pOptions) { + let source; + let fetcher; + let options; + if (arguments.length === 2 && typeof pFetcher === "object" || arguments.length === 1) { + source = true; + fetcher = pSource; + options = pFetcher || {}; + } else { + source = pSource; + fetcher = pFetcher; + options = pOptions || {}; + } + let pr = null, + initP = NO_INIT, + id = null, + loadedUnderTransition = false, + scheduled = false, + resolved = ("initialValue" in options), + dynamic = typeof source === "function" && createMemo(source); + const contexts = new Set(), + [value, setValue] = (options.storage || createSignal)(options.initialValue), + [error, setError] = createSignal(undefined), + [track, trigger] = createSignal(undefined, { + equals: false + }), + [state, setState] = createSignal(resolved ? "ready" : "unresolved"); + if (sharedConfig.context) { + id = sharedConfig.getNextContextId(); + if (options.ssrLoadFrom === "initial") initP = options.initialValue;else if (sharedConfig.load && sharedConfig.has(id)) initP = sharedConfig.load(id); + } + function loadEnd(p, v, error, key) { + if (pr === p) { + pr = null; + key !== undefined && (resolved = true); + if ((p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, { + value: v + })); + initP = NO_INIT; + if (Transition && p && loadedUnderTransition) { + Transition.promises.delete(p); + loadedUnderTransition = false; + runUpdates(() => { + Transition.running = true; + completeLoad(v, error); + }, false); + } else completeLoad(v, error); + } + return v; + } + function completeLoad(v, err) { + runUpdates(() => { + if (err === undefined) setValue(() => v); + setState(err !== undefined ? "errored" : resolved ? "ready" : "unresolved"); + setError(err); + for (const c of contexts.keys()) c.decrement(); + contexts.clear(); + }, false); + } + function read() { + const c = SuspenseContext && useContext(SuspenseContext), + v = value(), + err = error(); + if (err !== undefined && !pr) throw err; + if (Listener && !Listener.user && c) { + createComputed(() => { + track(); + if (pr) { + if (c.resolved && Transition && loadedUnderTransition) Transition.promises.add(pr);else if (!contexts.has(c)) { + c.increment(); + contexts.add(c); + } + } + }); + } + return v; + } + function load(refetching = true) { + if (refetching !== false && scheduled) return; + scheduled = false; + const lookup = dynamic ? dynamic() : source; + loadedUnderTransition = Transition && Transition.running; + if (lookup == null || lookup === false) { + loadEnd(pr, untrack(value)); + return; + } + if (Transition && pr) Transition.promises.delete(pr); + const p = initP !== NO_INIT ? initP : untrack(() => fetcher(lookup, { + value: value(), + refetching + })); + if (!isPromise(p)) { + loadEnd(pr, p, undefined, lookup); + return p; + } + pr = p; + if ("value" in p) { + if (p.status === "success") loadEnd(pr, p.value, undefined, lookup);else loadEnd(pr, undefined, castError(p.value), lookup); + return p; + } + scheduled = true; + queueMicrotask(() => scheduled = false); + runUpdates(() => { + setState(resolved ? "refreshing" : "pending"); + trigger(); + }, false); + return p.then(v => loadEnd(p, v, undefined, lookup), e => loadEnd(p, undefined, castError(e), lookup)); + } + Object.defineProperties(read, { + state: { + get: () => state() + }, + error: { + get: () => error() + }, + loading: { + get() { + const s = state(); + return s === "pending" || s === "refreshing"; + } + }, + latest: { + get() { + if (!resolved) return read(); + const err = error(); + if (err && !pr) throw err; + return value(); + } + } + }); + if (dynamic) createComputed(() => load(false));else load(false); + return [read, { + refetch: load, + mutate: setValue + }]; +} +function createDeferred(source, options) { + let t, + timeout = options ? options.timeoutMs : undefined; + const node = createComputation(() => { + if (!t || !t.fn) t = requestCallback(() => setDeferred(() => node.value), timeout !== undefined ? { + timeout + } : undefined); + return source(); + }, undefined, true); + const [deferred, setDeferred] = createSignal(Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value, options); + updateComputation(node); + setDeferred(() => Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value); + return deferred; +} +function createSelector(source, fn = equalFn, options) { + const subs = new Map(); + const node = createComputation(p => { + const v = source(); + for (const [key, val] of subs.entries()) if (fn(key, v) !== fn(key, p)) { + for (const c of val.values()) { + c.state = STALE; + if (c.pure) Updates.push(c);else Effects.push(c); + } + } + return v; + }, undefined, true, STALE, options ); + updateComputation(node); + return key => { + const listener = Listener; + if (listener) { + let l; + if (l = subs.get(key)) l.add(listener);else subs.set(key, l = new Set([listener])); + onCleanup(() => { + l.delete(listener); + !l.size && subs.delete(key); + }); + } + return fn(key, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value); + }; +} +function batch(fn) { + return runUpdates(fn, false); +} +function untrack(fn) { + if (!ExternalSourceConfig && Listener === null) return fn(); + const listener = Listener; + Listener = null; + try { + if (ExternalSourceConfig) return ExternalSourceConfig.untrack(fn); + return fn(); + } finally { + Listener = listener; + } +} +function on(deps, fn, options) { + const isArray = Array.isArray(deps); + let prevInput; + let defer = options && options.defer; + return prevValue => { + let input; + if (isArray) { + input = Array(deps.length); + for (let i = 0; i < deps.length; i++) input[i] = deps[i](); + } else input = deps(); + if (defer) { + defer = false; + return prevValue; + } + const result = untrack(() => fn(input, prevInput, prevValue)); + prevInput = input; + return result; + }; +} +function onMount(fn) { + createEffect(() => untrack(fn)); +} +function onCleanup(fn) { + if (Owner === null) console.warn("cleanups created outside a `createRoot` or `render` will never be run");else if (Owner.cleanups === null) Owner.cleanups = [fn];else Owner.cleanups.push(fn); + return fn; +} +function catchError(fn, handler) { + ERROR || (ERROR = Symbol("error")); + Owner = createComputation(undefined, undefined, true); + Owner.context = { + ...Owner.context, + [ERROR]: [handler] + }; + if (Transition && Transition.running) Transition.sources.add(Owner); + try { + return fn(); + } catch (err) { + handleError(err); + } finally { + Owner = Owner.owner; + } +} +function getListener() { + return Listener; +} +function getOwner() { + return Owner; +} +function runWithOwner(o, fn) { + const prev = Owner; + const prevListener = Listener; + Owner = o; + Listener = null; + try { + return runUpdates(fn, true); + } catch (err) { + handleError(err); + } finally { + Owner = prev; + Listener = prevListener; + } +} +function enableScheduling(scheduler = requestCallback) { + Scheduler = scheduler; +} +function startTransition(fn) { + if (Transition && Transition.running) { + fn(); + return Transition.done; + } + const l = Listener; + const o = Owner; + return Promise.resolve().then(() => { + Listener = l; + Owner = o; + let t; + if (Scheduler || SuspenseContext) { + t = Transition || (Transition = { + sources: new Set(), + effects: [], + promises: new Set(), + disposed: new Set(), + queue: new Set(), + running: true + }); + t.done || (t.done = new Promise(res => t.resolve = res)); + t.running = true; + } + runUpdates(fn, false); + Listener = Owner = null; + return t ? t.done : undefined; + }); +} +const [transPending, setTransPending] = /*@__PURE__*/createSignal(false); +function useTransition() { + return [transPending, startTransition]; +} +function resumeEffects(e) { + Effects.push.apply(Effects, e); + e.length = 0; +} +function devComponent(Comp, props) { + const c = createComputation(() => untrack(() => { + Object.assign(Comp, { + [$DEVCOMP]: true + }); + return Comp(props); + }), undefined, true, 0); + c.props = props; + c.observers = null; + c.observerSlots = null; + c.name = Comp.name; + c.component = Comp; + updateComputation(c); + return c.tValue !== undefined ? c.tValue : c.value; +} +function registerGraph(value) { + if (!Owner) return; + if (Owner.sourceMap) Owner.sourceMap.push(value);else Owner.sourceMap = [value]; + value.graph = Owner; +} +function createContext(defaultValue, options) { + const id = Symbol("context"); + return { + id, + Provider: createProvider(id, options), + defaultValue + }; +} +function useContext(context) { + let value; + return Owner && Owner.context && (value = Owner.context[context.id]) !== undefined ? value : context.defaultValue; +} +function children(fn) { + const children = createMemo(fn); + const memo = createMemo(() => resolveChildren(children()), undefined, { + name: "children" + }) ; + memo.toArray = () => { + const c = memo(); + return Array.isArray(c) ? c : c != null ? [c] : []; + }; + return memo; +} +let SuspenseContext; +function getSuspenseContext() { + return SuspenseContext || (SuspenseContext = createContext()); +} +function enableExternalSource(factory, untrack = fn => fn()) { + if (ExternalSourceConfig) { + const { + factory: oldFactory, + untrack: oldUntrack + } = ExternalSourceConfig; + ExternalSourceConfig = { + factory: (fn, trigger) => { + const oldSource = oldFactory(fn, trigger); + const source = factory(x => oldSource.track(x), trigger); + return { + track: x => source.track(x), + dispose() { + source.dispose(); + oldSource.dispose(); + } + }; + }, + untrack: fn => oldUntrack(() => untrack(fn)) + }; + } else { + ExternalSourceConfig = { + factory, + untrack + }; + } +} +function readSignal() { + const runningTransition = Transition && Transition.running; + if (this.sources && (runningTransition ? this.tState : this.state)) { + if ((runningTransition ? this.tState : this.state) === STALE) updateComputation(this);else { + const updates = Updates; + Updates = null; + runUpdates(() => lookUpstream(this), false); + Updates = updates; + } + } + if (Listener) { + const sSlot = this.observers ? this.observers.length : 0; + if (!Listener.sources) { + Listener.sources = [this]; + Listener.sourceSlots = [sSlot]; + } else { + Listener.sources.push(this); + Listener.sourceSlots.push(sSlot); + } + if (!this.observers) { + this.observers = [Listener]; + this.observerSlots = [Listener.sources.length - 1]; + } else { + this.observers.push(Listener); + this.observerSlots.push(Listener.sources.length - 1); + } + } + if (runningTransition && Transition.sources.has(this)) return this.tValue; + return this.value; +} +function writeSignal(node, value, isComp) { + let current = Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value; + if (!node.comparator || !node.comparator(current, value)) { + if (Transition) { + const TransitionRunning = Transition.running; + if (TransitionRunning || !isComp && Transition.sources.has(node)) { + Transition.sources.add(node); + node.tValue = value; + } + if (!TransitionRunning) node.value = value; + } else node.value = value; + if (node.observers && node.observers.length) { + runUpdates(() => { + for (let i = 0; i < node.observers.length; i += 1) { + const o = node.observers[i]; + const TransitionRunning = Transition && Transition.running; + if (TransitionRunning && Transition.disposed.has(o)) continue; + if (TransitionRunning ? !o.tState : !o.state) { + if (o.pure) Updates.push(o);else Effects.push(o); + if (o.observers) markDownstream(o); + } + if (!TransitionRunning) o.state = STALE;else o.tState = STALE; + } + if (Updates.length > 10e5) { + Updates = []; + if (true) throw new Error("Potential Infinite Loop Detected."); + throw new Error(); + } + }, false); + } + } + return value; +} +function updateComputation(node) { + if (!node.fn) return; + cleanNode(node); + const time = ExecCount; + runComputation(node, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value, time); + if (Transition && !Transition.running && Transition.sources.has(node)) { + queueMicrotask(() => { + runUpdates(() => { + Transition && (Transition.running = true); + Listener = Owner = node; + runComputation(node, node.tValue, time); + Listener = Owner = null; + }, false); + }); + } +} +function runComputation(node, value, time) { + let nextValue; + const owner = Owner, + listener = Listener; + Listener = Owner = node; + try { + nextValue = node.fn(value); + } catch (err) { + if (node.pure) { + if (Transition && Transition.running) { + node.tState = STALE; + node.tOwned && node.tOwned.forEach(cleanNode); + node.tOwned = undefined; + } else { + node.state = STALE; + node.owned && node.owned.forEach(cleanNode); + node.owned = null; + } + } + node.updatedAt = time + 1; + return handleError(err); + } finally { + Listener = listener; + Owner = owner; + } + if (!node.updatedAt || node.updatedAt <= time) { + if (node.updatedAt != null && "observers" in node) { + writeSignal(node, nextValue, true); + } else if (Transition && Transition.running && node.pure) { + Transition.sources.add(node); + node.tValue = nextValue; + } else node.value = nextValue; + node.updatedAt = time; + } +} +function createComputation(fn, init, pure, state = STALE, options) { + const c = { + fn, + state: state, + updatedAt: null, + owned: null, + sources: null, + sourceSlots: null, + cleanups: null, + value: init, + owner: Owner, + context: Owner ? Owner.context : null, + pure + }; + if (Transition && Transition.running) { + c.state = 0; + c.tState = state; + } + if (Owner === null) console.warn("computations created outside a `createRoot` or `render` will never be disposed");else if (Owner !== UNOWNED) { + if (Transition && Transition.running && Owner.pure) { + if (!Owner.tOwned) Owner.tOwned = [c];else Owner.tOwned.push(c); + } else { + if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c); + } + } + if (options && options.name) c.name = options.name; + if (ExternalSourceConfig && c.fn) { + const [track, trigger] = createSignal(undefined, { + equals: false + }); + const ordinary = ExternalSourceConfig.factory(c.fn, trigger); + onCleanup(() => ordinary.dispose()); + const triggerInTransition = () => startTransition(trigger).then(() => inTransition.dispose()); + const inTransition = ExternalSourceConfig.factory(c.fn, triggerInTransition); + c.fn = x => { + track(); + return Transition && Transition.running ? inTransition.track(x) : ordinary.track(x); + }; + } + DevHooks.afterCreateOwner && DevHooks.afterCreateOwner(c); + return c; +} +function runTop(node) { + const runningTransition = Transition && Transition.running; + if ((runningTransition ? node.tState : node.state) === 0) return; + if ((runningTransition ? node.tState : node.state) === PENDING) return lookUpstream(node); + if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node); + const ancestors = [node]; + while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) { + if (runningTransition && Transition.disposed.has(node)) return; + if (runningTransition ? node.tState : node.state) ancestors.push(node); + } + for (let i = ancestors.length - 1; i >= 0; i--) { + node = ancestors[i]; + if (runningTransition) { + let top = node, + prev = ancestors[i + 1]; + while ((top = top.owner) && top !== prev) { + if (Transition.disposed.has(top)) return; + } + } + if ((runningTransition ? node.tState : node.state) === STALE) { + updateComputation(node); + } else if ((runningTransition ? node.tState : node.state) === PENDING) { + const updates = Updates; + Updates = null; + runUpdates(() => lookUpstream(node, ancestors[0]), false); + Updates = updates; + } + } +} +function runUpdates(fn, init) { + if (Updates) return fn(); + let wait = false; + if (!init) Updates = []; + if (Effects) wait = true;else Effects = []; + ExecCount++; + try { + const res = fn(); + completeUpdates(wait); + return res; + } catch (err) { + if (!wait) Effects = null; + Updates = null; + handleError(err); + } +} +function completeUpdates(wait) { + if (Updates) { + if (Scheduler && Transition && Transition.running) scheduleQueue(Updates);else runQueue(Updates); + Updates = null; + } + if (wait) return; + let res; + if (Transition) { + if (!Transition.promises.size && !Transition.queue.size) { + const sources = Transition.sources; + const disposed = Transition.disposed; + Effects.push.apply(Effects, Transition.effects); + res = Transition.resolve; + for (const e of Effects) { + "tState" in e && (e.state = e.tState); + delete e.tState; + } + Transition = null; + runUpdates(() => { + for (const d of disposed) cleanNode(d); + for (const v of sources) { + v.value = v.tValue; + if (v.owned) { + for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]); + } + if (v.tOwned) v.owned = v.tOwned; + delete v.tValue; + delete v.tOwned; + v.tState = 0; + } + setTransPending(false); + }, false); + } else if (Transition.running) { + Transition.running = false; + Transition.effects.push.apply(Transition.effects, Effects); + Effects = null; + setTransPending(true); + return; + } + } + const e = Effects; + Effects = null; + if (e.length) runUpdates(() => runEffects(e), false);else DevHooks.afterUpdate && DevHooks.afterUpdate(); + if (res) res(); +} +function runQueue(queue) { + for (let i = 0; i < queue.length; i++) runTop(queue[i]); +} +function scheduleQueue(queue) { + for (let i = 0; i < queue.length; i++) { + const item = queue[i]; + const tasks = Transition.queue; + if (!tasks.has(item)) { + tasks.add(item); + Scheduler(() => { + tasks.delete(item); + runUpdates(() => { + Transition.running = true; + runTop(item); + }, false); + Transition && (Transition.running = false); + }); + } + } +} +function runUserEffects(queue) { + let i, + userLength = 0; + for (i = 0; i < queue.length; i++) { + const e = queue[i]; + if (!e.user) runTop(e);else queue[userLength++] = e; + } + if (sharedConfig.context) { + if (sharedConfig.count) { + sharedConfig.effects || (sharedConfig.effects = []); + sharedConfig.effects.push(...queue.slice(0, userLength)); + return; + } + setHydrateContext(); + } + if (sharedConfig.effects && (sharedConfig.done || !sharedConfig.count)) { + queue = [...sharedConfig.effects, ...queue]; + userLength += sharedConfig.effects.length; + delete sharedConfig.effects; + } + for (i = 0; i < userLength; i++) runTop(queue[i]); +} +function lookUpstream(node, ignore) { + const runningTransition = Transition && Transition.running; + if (runningTransition) node.tState = 0;else node.state = 0; + for (let i = 0; i < node.sources.length; i += 1) { + const source = node.sources[i]; + if (source.sources) { + const state = runningTransition ? source.tState : source.state; + if (state === STALE) { + if (source !== ignore && (!source.updatedAt || source.updatedAt < ExecCount)) runTop(source); + } else if (state === PENDING) lookUpstream(source, ignore); + } + } +} +function markDownstream(node) { + const runningTransition = Transition && Transition.running; + for (let i = 0; i < node.observers.length; i += 1) { + const o = node.observers[i]; + if (runningTransition ? !o.tState : !o.state) { + if (runningTransition) o.tState = PENDING;else o.state = PENDING; + if (o.pure) Updates.push(o);else Effects.push(o); + o.observers && markDownstream(o); + } + } +} +function cleanNode(node) { + let i; + if (node.sources) { + while (node.sources.length) { + const source = node.sources.pop(), + index = node.sourceSlots.pop(), + obs = source.observers; + if (obs && obs.length) { + const n = obs.pop(), + s = source.observerSlots.pop(); + if (index < obs.length) { + n.sourceSlots[s] = index; + obs[index] = n; + source.observerSlots[index] = s; + } + } + } + } + if (Transition && Transition.running && node.pure) { + if (node.tOwned) { + for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]); + delete node.tOwned; + } + reset(node, true); + } else if (node.owned) { + for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]); + node.owned = null; + } + if (node.cleanups) { + for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i](); + node.cleanups = null; + } + if (Transition && Transition.running) node.tState = 0;else node.state = 0; + delete node.sourceMap; +} +function reset(node, top) { + if (!top) { + node.tState = 0; + Transition.disposed.add(node); + } + if (node.owned) { + for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]); + } +} +function castError(err) { + if (err instanceof Error) return err; + return new Error(typeof err === "string" ? err : "Unknown error", { + cause: err + }); +} +function runErrors(err, fns, owner) { + try { + for (const f of fns) f(err); + } catch (e) { + handleError(e, owner && owner.owner || null); + } +} +function handleError(err, owner = Owner) { + const fns = ERROR && owner && owner.context && owner.context[ERROR]; + const error = castError(err); + if (!fns) throw error; + if (Effects) Effects.push({ + fn() { + runErrors(error, fns, owner); + }, + state: STALE + });else runErrors(error, fns, owner); +} +function resolveChildren(children) { + if (typeof children === "function" && !children.length) return resolveChildren(children()); + if (Array.isArray(children)) { + const results = []; + for (let i = 0; i < children.length; i++) { + const result = resolveChildren(children[i]); + Array.isArray(result) ? results.push.apply(results, result) : results.push(result); + } + return results; + } + return children; +} +function createProvider(id, options) { + return function provider(props) { + let res; + createRenderEffect(() => res = untrack(() => { + Owner.context = { + ...Owner.context, + [id]: props.value + }; + return children(() => props.children); + }), undefined, options); + return res; + }; +} +function onError(fn) { + ERROR || (ERROR = Symbol("error")); + if (Owner === null) console.warn("error handlers created outside a `createRoot` or `render` will never be run");else if (Owner.context === null || !Owner.context[ERROR]) { + Owner.context = { + ...Owner.context, + [ERROR]: [fn] + }; + mutateContext(Owner, ERROR, [fn]); + } else Owner.context[ERROR].push(fn); +} +function mutateContext(o, key, value) { + if (o.owned) { + for (let i = 0; i < o.owned.length; i++) { + if (o.owned[i].context === o.context) mutateContext(o.owned[i], key, value); + if (!o.owned[i].context) { + o.owned[i].context = o.context; + mutateContext(o.owned[i], key, value); + } else if (!o.owned[i].context[key]) { + o.owned[i].context[key] = value; + mutateContext(o.owned[i], key, value); + } + } + } +} + +function observable(input) { + return { + subscribe(observer) { + if (!(observer instanceof Object) || observer == null) { + throw new TypeError("Expected the observer to be an object."); + } + const handler = typeof observer === "function" ? observer : observer.next && observer.next.bind(observer); + if (!handler) { + return { + unsubscribe() {} + }; + } + const dispose = createRoot(disposer => { + createEffect(() => { + const v = input(); + untrack(() => handler(v)); + }); + return disposer; + }); + if (getOwner()) onCleanup(dispose); + return { + unsubscribe() { + dispose(); + } + }; + }, + [Symbol.observable || "@@observable"]() { + return this; + } + }; +} +function from(producer) { + const [s, set] = createSignal(undefined, { + equals: false + }); + if ("subscribe" in producer) { + const unsub = producer.subscribe(v => set(() => v)); + onCleanup(() => "unsubscribe" in unsub ? unsub.unsubscribe() : unsub()); + } else { + const clean = producer(set); + onCleanup(clean); + } + return s; +} + +const FALLBACK = Symbol("fallback"); +function dispose(d) { + for (let i = 0; i < d.length; i++) d[i](); +} +function mapArray(list, mapFn, options = {}) { + let items = [], + mapped = [], + disposers = [], + len = 0, + indexes = mapFn.length > 1 ? [] : null; + onCleanup(() => dispose(disposers)); + return () => { + let newItems = list() || [], + newLen = newItems.length, + i, + j; + newItems[$TRACK]; + return untrack(() => { + let newIndices, newIndicesNext, temp, tempdisposers, tempIndexes, start, end, newEnd, item; + if (newLen === 0) { + if (len !== 0) { + dispose(disposers); + disposers = []; + items = []; + mapped = []; + len = 0; + indexes && (indexes = []); + } + if (options.fallback) { + items = [FALLBACK]; + mapped[0] = createRoot(disposer => { + disposers[0] = disposer; + return options.fallback(); + }); + len = 1; + } + } + else if (len === 0) { + mapped = new Array(newLen); + for (j = 0; j < newLen; j++) { + items[j] = newItems[j]; + mapped[j] = createRoot(mapper); + } + len = newLen; + } else { + temp = new Array(newLen); + tempdisposers = new Array(newLen); + indexes && (tempIndexes = new Array(newLen)); + for (start = 0, end = Math.min(len, newLen); start < end && items[start] === newItems[start]; start++); + for (end = len - 1, newEnd = newLen - 1; end >= start && newEnd >= start && items[end] === newItems[newEnd]; end--, newEnd--) { + temp[newEnd] = mapped[end]; + tempdisposers[newEnd] = disposers[end]; + indexes && (tempIndexes[newEnd] = indexes[end]); + } + newIndices = new Map(); + newIndicesNext = new Array(newEnd + 1); + for (j = newEnd; j >= start; j--) { + item = newItems[j]; + i = newIndices.get(item); + newIndicesNext[j] = i === undefined ? -1 : i; + newIndices.set(item, j); + } + for (i = start; i <= end; i++) { + item = items[i]; + j = newIndices.get(item); + if (j !== undefined && j !== -1) { + temp[j] = mapped[i]; + tempdisposers[j] = disposers[i]; + indexes && (tempIndexes[j] = indexes[i]); + j = newIndicesNext[j]; + newIndices.set(item, j); + } else disposers[i](); + } + for (j = start; j < newLen; j++) { + if (j in temp) { + mapped[j] = temp[j]; + disposers[j] = tempdisposers[j]; + if (indexes) { + indexes[j] = tempIndexes[j]; + indexes[j](j); + } + } else mapped[j] = createRoot(mapper); + } + mapped = mapped.slice(0, len = newLen); + items = newItems.slice(0); + } + return mapped; + }); + function mapper(disposer) { + disposers[j] = disposer; + if (indexes) { + const [s, set] = createSignal(j, { + name: "index" + }) ; + indexes[j] = set; + return mapFn(newItems[j], s); + } + return mapFn(newItems[j]); + } + }; +} +function indexArray(list, mapFn, options = {}) { + let items = [], + mapped = [], + disposers = [], + signals = [], + len = 0, + i; + onCleanup(() => dispose(disposers)); + return () => { + const newItems = list() || [], + newLen = newItems.length; + newItems[$TRACK]; + return untrack(() => { + if (newLen === 0) { + if (len !== 0) { + dispose(disposers); + disposers = []; + items = []; + mapped = []; + len = 0; + signals = []; + } + if (options.fallback) { + items = [FALLBACK]; + mapped[0] = createRoot(disposer => { + disposers[0] = disposer; + return options.fallback(); + }); + len = 1; + } + return mapped; + } + if (items[0] === FALLBACK) { + disposers[0](); + disposers = []; + items = []; + mapped = []; + len = 0; + } + for (i = 0; i < newLen; i++) { + if (i < items.length && items[i] !== newItems[i]) { + signals[i](() => newItems[i]); + } else if (i >= items.length) { + mapped[i] = createRoot(mapper); + } + } + for (; i < items.length; i++) { + disposers[i](); + } + len = signals.length = disposers.length = newLen; + items = newItems.slice(0); + return mapped = mapped.slice(0, len); + }); + function mapper(disposer) { + disposers[i] = disposer; + const [s, set] = createSignal(newItems[i], { + name: "value" + }) ; + signals[i] = set; + return mapFn(s, i); + } + }; +} + +let hydrationEnabled = false; +function enableHydration() { + hydrationEnabled = true; +} +function createComponent(Comp, props) { + if (hydrationEnabled) { + if (sharedConfig.context) { + const c = sharedConfig.context; + setHydrateContext(nextHydrateContext()); + const r = devComponent(Comp, props || {}) ; + setHydrateContext(c); + return r; + } + } + return devComponent(Comp, props || {}); +} +function trueFn() { + return true; +} +const propTraps = { + get(_, property, receiver) { + if (property === $PROXY) return receiver; + return _.get(property); + }, + has(_, property) { + if (property === $PROXY) return true; + return _.has(property); + }, + set: trueFn, + deleteProperty: trueFn, + getOwnPropertyDescriptor(_, property) { + return { + configurable: true, + enumerable: true, + get() { + return _.get(property); + }, + set: trueFn, + deleteProperty: trueFn + }; + }, + ownKeys(_) { + return _.keys(); + } +}; +function resolveSource(s) { + return !(s = typeof s === "function" ? s() : s) ? {} : s; +} +function resolveSources() { + for (let i = 0, length = this.length; i < length; ++i) { + const v = this[i](); + if (v !== undefined) return v; + } +} +function mergeProps(...sources) { + let proxy = false; + for (let i = 0; i < sources.length; i++) { + const s = sources[i]; + proxy = proxy || !!s && $PROXY in s; + sources[i] = typeof s === "function" ? (proxy = true, createMemo(s)) : s; + } + if (proxy) { + return new Proxy({ + get(property) { + for (let i = sources.length - 1; i >= 0; i--) { + const v = resolveSource(sources[i])[property]; + if (v !== undefined) return v; + } + }, + has(property) { + for (let i = sources.length - 1; i >= 0; i--) { + if (property in resolveSource(sources[i])) return true; + } + return false; + }, + keys() { + const keys = []; + for (let i = 0; i < sources.length; i++) keys.push(...Object.keys(resolveSource(sources[i]))); + return [...new Set(keys)]; + } + }, propTraps); + } + const sourcesMap = {}; + const defined = Object.create(null); + for (let i = sources.length - 1; i >= 0; i--) { + const source = sources[i]; + if (!source) continue; + const sourceKeys = Object.getOwnPropertyNames(source); + for (let i = sourceKeys.length - 1; i >= 0; i--) { + const key = sourceKeys[i]; + if (key === "__proto__" || key === "constructor") continue; + const desc = Object.getOwnPropertyDescriptor(source, key); + if (!defined[key]) { + defined[key] = desc.get ? { + enumerable: true, + configurable: true, + get: resolveSources.bind(sourcesMap[key] = [desc.get.bind(source)]) + } : desc.value !== undefined ? desc : undefined; + } else { + const sources = sourcesMap[key]; + if (sources) { + if (desc.get) sources.push(desc.get.bind(source));else if (desc.value !== undefined) sources.push(() => desc.value); + } + } + } + } + const target = {}; + const definedKeys = Object.keys(defined); + for (let i = definedKeys.length - 1; i >= 0; i--) { + const key = definedKeys[i], + desc = defined[key]; + if (desc && desc.get) Object.defineProperty(target, key, desc);else target[key] = desc ? desc.value : undefined; + } + return target; +} +function splitProps(props, ...keys) { + if ($PROXY in props) { + const blocked = new Set(keys.length > 1 ? keys.flat() : keys[0]); + const res = keys.map(k => { + return new Proxy({ + get(property) { + return k.includes(property) ? props[property] : undefined; + }, + has(property) { + return k.includes(property) && property in props; + }, + keys() { + return k.filter(property => property in props); + } + }, propTraps); + }); + res.push(new Proxy({ + get(property) { + return blocked.has(property) ? undefined : props[property]; + }, + has(property) { + return blocked.has(property) ? false : property in props; + }, + keys() { + return Object.keys(props).filter(k => !blocked.has(k)); + } + }, propTraps)); + return res; + } + const otherObject = {}; + const objects = keys.map(() => ({})); + for (const propName of Object.getOwnPropertyNames(props)) { + const desc = Object.getOwnPropertyDescriptor(props, propName); + const isDefaultDesc = !desc.get && !desc.set && desc.enumerable && desc.writable && desc.configurable; + let blocked = false; + let objectIndex = 0; + for (const k of keys) { + if (k.includes(propName)) { + blocked = true; + isDefaultDesc ? objects[objectIndex][propName] = desc.value : Object.defineProperty(objects[objectIndex], propName, desc); + } + ++objectIndex; + } + if (!blocked) { + isDefaultDesc ? otherObject[propName] = desc.value : Object.defineProperty(otherObject, propName, desc); + } + } + return [...objects, otherObject]; +} +function lazy(fn) { + let comp; + let p; + const wrap = props => { + const ctx = sharedConfig.context; + if (ctx) { + const [s, set] = createSignal(); + sharedConfig.count || (sharedConfig.count = 0); + sharedConfig.count++; + (p || (p = fn())).then(mod => { + !sharedConfig.done && setHydrateContext(ctx); + sharedConfig.count--; + set(() => mod.default); + setHydrateContext(); + }); + comp = s; + } else if (!comp) { + const [s] = createResource(() => (p || (p = fn())).then(mod => mod.default)); + comp = s; + } + let Comp; + return createMemo(() => (Comp = comp()) ? untrack(() => { + if (true) Object.assign(Comp, { + [$DEVCOMP]: true + }); + if (!ctx || sharedConfig.done) return Comp(props); + const c = sharedConfig.context; + setHydrateContext(ctx); + const r = Comp(props); + setHydrateContext(c); + return r; + }) : ""); + }; + wrap.preload = () => p || ((p = fn()).then(mod => comp = () => mod.default), p); + return wrap; +} +let counter = 0; +function createUniqueId() { + const ctx = sharedConfig.context; + return ctx ? sharedConfig.getNextContextId() : `cl-${counter++}`; +} + +const narrowedError = name => `Attempting to access a stale value from <${name}> that could possibly be undefined. This may occur because you are reading the accessor returned from the component at a time where it has already been unmounted. We recommend cleaning up any stale timers or async, or reading from the initial condition.` ; +function For(props) { + const fallback = "fallback" in props && { + fallback: () => props.fallback + }; + return createMemo(mapArray(() => props.each, props.children, fallback || undefined), undefined, { + name: "value" + }) ; +} +function Index(props) { + const fallback = "fallback" in props && { + fallback: () => props.fallback + }; + return createMemo(indexArray(() => props.each, props.children, fallback || undefined), undefined, { + name: "value" + }) ; +} +function Show(props) { + const keyed = props.keyed; + const condition = createMemo(() => props.when, undefined, { + equals: (a, b) => keyed ? a === b : !a === !b, + name: "condition" + } ); + return createMemo(() => { + const c = condition(); + if (c) { + const child = props.children; + const fn = typeof child === "function" && child.length > 0; + return fn ? untrack(() => child(keyed ? c : () => { + if (!untrack(condition)) throw narrowedError("Show"); + return props.when; + })) : child; + } + return props.fallback; + }, undefined, { + name: "value" + } ); +} +function Switch(props) { + let keyed = false; + const equals = (a, b) => (keyed ? a[1] === b[1] : !a[1] === !b[1]) && a[2] === b[2]; + const conditions = children(() => props.children), + evalConditions = createMemo(() => { + let conds = conditions(); + if (!Array.isArray(conds)) conds = [conds]; + for (let i = 0; i < conds.length; i++) { + const c = conds[i].when; + if (c) { + keyed = !!conds[i].keyed; + return [i, c, conds[i]]; + } + } + return [-1]; + }, undefined, { + equals, + name: "eval conditions" + } ); + return createMemo(() => { + const [index, when, cond] = evalConditions(); + if (index < 0) return props.fallback; + const c = cond.children; + const fn = typeof c === "function" && c.length > 0; + return fn ? untrack(() => c(keyed ? when : () => { + if (untrack(evalConditions)[0] !== index) throw narrowedError("Match"); + return cond.when; + })) : c; + }, undefined, { + name: "value" + } ); +} +function Match(props) { + return props; +} +let Errors; +function resetErrorBoundaries() { + Errors && [...Errors].forEach(fn => fn()); +} +function ErrorBoundary(props) { + let err; + if (sharedConfig.context && sharedConfig.load) err = sharedConfig.load(sharedConfig.getContextId()); + const [errored, setErrored] = createSignal(err, { + name: "errored" + } ); + Errors || (Errors = new Set()); + Errors.add(setErrored); + onCleanup(() => Errors.delete(setErrored)); + return createMemo(() => { + let e; + if (e = errored()) { + const f = props.fallback; + if ((typeof f !== "function" || f.length == 0)) console.error(e); + return typeof f === "function" && f.length ? untrack(() => f(e, () => setErrored())) : f; + } + return catchError(() => props.children, setErrored); + }, undefined, { + name: "value" + } ); +} + +const suspenseListEquals = (a, b) => a.showContent === b.showContent && a.showFallback === b.showFallback; +const SuspenseListContext = /* #__PURE__ */createContext(); +function SuspenseList(props) { + let [wrapper, setWrapper] = createSignal(() => ({ + inFallback: false + })), + show; + const listContext = useContext(SuspenseListContext); + const [registry, setRegistry] = createSignal([]); + if (listContext) { + show = listContext.register(createMemo(() => wrapper()().inFallback)); + } + const resolved = createMemo(prev => { + const reveal = props.revealOrder, + tail = props.tail, + { + showContent = true, + showFallback = true + } = show ? show() : {}, + reg = registry(), + reverse = reveal === "backwards"; + if (reveal === "together") { + const all = reg.every(inFallback => !inFallback()); + const res = reg.map(() => ({ + showContent: all && showContent, + showFallback + })); + res.inFallback = !all; + return res; + } + let stop = false; + let inFallback = prev.inFallback; + const res = []; + for (let i = 0, len = reg.length; i < len; i++) { + const n = reverse ? len - i - 1 : i, + s = reg[n](); + if (!stop && !s) { + res[n] = { + showContent, + showFallback + }; + } else { + const next = !stop; + if (next) inFallback = true; + res[n] = { + showContent: next, + showFallback: !tail || next && tail === "collapsed" ? showFallback : false + }; + stop = true; + } + } + if (!stop) inFallback = false; + res.inFallback = inFallback; + return res; + }, { + inFallback: false + }); + setWrapper(() => resolved); + return createComponent(SuspenseListContext.Provider, { + value: { + register: inFallback => { + let index; + setRegistry(registry => { + index = registry.length; + return [...registry, inFallback]; + }); + return createMemo(() => resolved()[index], undefined, { + equals: suspenseListEquals + }); + } + }, + get children() { + return props.children; + } + }); +} +function Suspense(props) { + let counter = 0, + show, + ctx, + p, + flicker, + error; + const [inFallback, setFallback] = createSignal(false), + SuspenseContext = getSuspenseContext(), + store = { + increment: () => { + if (++counter === 1) setFallback(true); + }, + decrement: () => { + if (--counter === 0) setFallback(false); + }, + inFallback, + effects: [], + resolved: false + }, + owner = getOwner(); + if (sharedConfig.context && sharedConfig.load) { + const key = sharedConfig.getContextId(); + let ref = sharedConfig.load(key); + if (ref) { + if (typeof ref !== "object" || ref.status !== "success") p = ref;else sharedConfig.gather(key); + } + if (p && p !== "$$f") { + const [s, set] = createSignal(undefined, { + equals: false + }); + flicker = s; + p.then(() => { + if (sharedConfig.done) return set(); + sharedConfig.gather(key); + setHydrateContext(ctx); + set(); + setHydrateContext(); + }, err => { + error = err; + set(); + }); + } + } + const listContext = useContext(SuspenseListContext); + if (listContext) show = listContext.register(store.inFallback); + let dispose; + onCleanup(() => dispose && dispose()); + return createComponent(SuspenseContext.Provider, { + value: store, + get children() { + return createMemo(() => { + if (error) throw error; + ctx = sharedConfig.context; + if (flicker) { + flicker(); + return flicker = undefined; + } + if (ctx && p === "$$f") setHydrateContext(); + const rendered = createMemo(() => props.children); + return createMemo(prev => { + const inFallback = store.inFallback(), + { + showContent = true, + showFallback = true + } = show ? show() : {}; + if ((!inFallback || p && p !== "$$f") && showContent) { + store.resolved = true; + dispose && dispose(); + dispose = ctx = p = undefined; + resumeEffects(store.effects); + return rendered(); + } + if (!showFallback) return; + if (dispose) return prev; + return createRoot(disposer => { + dispose = disposer; + if (ctx) { + setHydrateContext({ + id: ctx.id + "F", + count: 0 + }); + ctx = undefined; + } + return props.fallback; + }, owner); + }); + }); + } + }); +} + +const DEV = { + hooks: DevHooks, + writeSignal, + registerGraph +} ; +if (globalThis) { + if (!globalThis.Solid$$) globalThis.Solid$$ = true;else console.warn("You appear to have multiple instances of Solid. This can lead to unexpected behavior."); +} + + + + +/***/ }), + +/***/ "./node_modules/solid-js/web/dist/dev.js": +/*!***********************************************!*\ + !*** ./node_modules/solid-js/web/dist/dev.js ***! + \***********************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Aliases: () => (/* binding */ Aliases), +/* harmony export */ Assets: () => (/* binding */ voidFn), +/* harmony export */ ChildProperties: () => (/* binding */ ChildProperties), +/* harmony export */ DOMElements: () => (/* binding */ DOMElements), +/* harmony export */ DelegatedEvents: () => (/* binding */ DelegatedEvents), +/* harmony export */ Dynamic: () => (/* binding */ Dynamic), +/* harmony export */ ErrorBoundary: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.ErrorBoundary), +/* harmony export */ For: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.For), +/* harmony export */ Hydration: () => (/* binding */ Hydration), +/* harmony export */ HydrationScript: () => (/* binding */ voidFn), +/* harmony export */ Index: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Index), +/* harmony export */ Match: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Match), +/* harmony export */ NoHydration: () => (/* binding */ NoHydration), +/* harmony export */ Portal: () => (/* binding */ Portal), +/* harmony export */ Properties: () => (/* binding */ Properties), +/* harmony export */ RequestContext: () => (/* binding */ RequestContext), +/* harmony export */ SVGElements: () => (/* binding */ SVGElements), +/* harmony export */ SVGNamespace: () => (/* binding */ SVGNamespace), +/* harmony export */ Show: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Show), +/* harmony export */ Suspense: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Suspense), +/* harmony export */ SuspenseList: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.SuspenseList), +/* harmony export */ Switch: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Switch), +/* harmony export */ addEventListener: () => (/* binding */ addEventListener), +/* harmony export */ assign: () => (/* binding */ assign), +/* harmony export */ classList: () => (/* binding */ classList), +/* harmony export */ className: () => (/* binding */ className), +/* harmony export */ clearDelegatedEvents: () => (/* binding */ clearDelegatedEvents), +/* harmony export */ createComponent: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.createComponent), +/* harmony export */ delegateEvents: () => (/* binding */ delegateEvents), +/* harmony export */ dynamicProperty: () => (/* binding */ dynamicProperty), +/* harmony export */ effect: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect), +/* harmony export */ escape: () => (/* binding */ escape), +/* harmony export */ generateHydrationScript: () => (/* binding */ voidFn), +/* harmony export */ getAssets: () => (/* binding */ voidFn), +/* harmony export */ getHydrationKey: () => (/* binding */ getHydrationKey), +/* harmony export */ getNextElement: () => (/* binding */ getNextElement), +/* harmony export */ getNextMarker: () => (/* binding */ getNextMarker), +/* harmony export */ getNextMatch: () => (/* binding */ getNextMatch), +/* harmony export */ getOwner: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.getOwner), +/* harmony export */ getPropAlias: () => (/* binding */ getPropAlias), +/* harmony export */ getRequestEvent: () => (/* binding */ voidFn), +/* harmony export */ hydrate: () => (/* binding */ hydrate), +/* harmony export */ innerHTML: () => (/* binding */ innerHTML), +/* harmony export */ insert: () => (/* binding */ insert), +/* harmony export */ isDev: () => (/* binding */ isDev), +/* harmony export */ isServer: () => (/* binding */ isServer), +/* harmony export */ memo: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo), +/* harmony export */ mergeProps: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.mergeProps), +/* harmony export */ render: () => (/* binding */ render), +/* harmony export */ renderToStream: () => (/* binding */ renderToStream), +/* harmony export */ renderToString: () => (/* binding */ renderToString), +/* harmony export */ renderToStringAsync: () => (/* binding */ renderToStringAsync), +/* harmony export */ resolveSSRNode: () => (/* binding */ resolveSSRNode), +/* harmony export */ runHydrationEvents: () => (/* binding */ runHydrationEvents), +/* harmony export */ setAttribute: () => (/* binding */ setAttribute), +/* harmony export */ setAttributeNS: () => (/* binding */ setAttributeNS), +/* harmony export */ setProperty: () => (/* binding */ setProperty), +/* harmony export */ spread: () => (/* binding */ spread), +/* harmony export */ ssr: () => (/* binding */ ssr), +/* harmony export */ ssrAttribute: () => (/* binding */ ssrAttribute), +/* harmony export */ ssrClassList: () => (/* binding */ ssrClassList), +/* harmony export */ ssrElement: () => (/* binding */ ssrElement), +/* harmony export */ ssrHydrationKey: () => (/* binding */ ssrHydrationKey), +/* harmony export */ ssrSpread: () => (/* binding */ ssrSpread), +/* harmony export */ ssrStyle: () => (/* binding */ ssrStyle), +/* harmony export */ style: () => (/* binding */ style), +/* harmony export */ template: () => (/* binding */ template), +/* harmony export */ untrack: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack), +/* harmony export */ use: () => (/* binding */ use), +/* harmony export */ useAssets: () => (/* binding */ voidFn) +/* harmony export */ }); +/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); + + + +const booleans = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "disabled", "formnovalidate", "hidden", "indeterminate", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "seamless", "selected"]; +const Properties = /*#__PURE__*/new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]); +const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]); +const Aliases = /*#__PURE__*/Object.assign(Object.create(null), { + className: "class", + htmlFor: "for" +}); +const PropAliases = /*#__PURE__*/Object.assign(Object.create(null), { + class: "className", + formnovalidate: { + $: "formNoValidate", + BUTTON: 1, + INPUT: 1 + }, + ismap: { + $: "isMap", + IMG: 1 + }, + nomodule: { + $: "noModule", + SCRIPT: 1 + }, + playsinline: { + $: "playsInline", + VIDEO: 1 + }, + readonly: { + $: "readOnly", + INPUT: 1, + TEXTAREA: 1 + } +}); +function getPropAlias(prop, tagName) { + const a = PropAliases[prop]; + return typeof a === "object" ? a[tagName] ? a["$"] : undefined : a; +} +const DelegatedEvents = /*#__PURE__*/new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]); +const SVGElements = /*#__PURE__*/new Set([ +"altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "font", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignObject", "g", "glyph", "glyphRef", "hkern", "image", "line", "linearGradient", "marker", "mask", "metadata", "missing-glyph", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", +"set", "stop", +"svg", "switch", "symbol", "text", "textPath", +"tref", "tspan", "use", "view", "vkern"]); +const SVGNamespace = { + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace" +}; +const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input", "h1", "h2", "h3", "h4", "h5", "h6"]); + +function reconcileArrays(parentNode, a, b) { + let bLength = b.length, + aEnd = a.length, + bEnd = bLength, + aStart = 0, + bStart = 0, + after = a[aEnd - 1].nextSibling, + map = null; + while (aStart < aEnd || bStart < bEnd) { + if (a[aStart] === b[bStart]) { + aStart++; + bStart++; + continue; + } + while (a[aEnd - 1] === b[bEnd - 1]) { + aEnd--; + bEnd--; + } + if (aEnd === aStart) { + const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after; + while (bStart < bEnd) parentNode.insertBefore(b[bStart++], node); + } else if (bEnd === bStart) { + while (aStart < aEnd) { + if (!map || !map.has(a[aStart])) a[aStart].remove(); + aStart++; + } + } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) { + const node = a[--aEnd].nextSibling; + parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling); + parentNode.insertBefore(b[--bEnd], node); + a[aEnd] = b[bEnd]; + } else { + if (!map) { + map = new Map(); + let i = bStart; + while (i < bEnd) map.set(b[i], i++); + } + const index = map.get(a[aStart]); + if (index != null) { + if (bStart < index && index < bEnd) { + let i = aStart, + sequence = 1, + t; + while (++i < aEnd && i < bEnd) { + if ((t = map.get(a[i])) == null || t !== index + sequence) break; + sequence++; + } + if (sequence > index - bStart) { + const node = a[aStart]; + while (bStart < index) parentNode.insertBefore(b[bStart++], node); + } else parentNode.replaceChild(b[bStart++], a[aStart++]); + } else aStart++; + } else a[aStart++].remove(); + } + } +} + +const $$EVENTS = "_$DX_DELEGATE"; +function render(code, element, init, options = {}) { + if (!element) { + throw new Error("The `element` passed to `render(..., element)` doesn't exist. Make sure `element` exists in the document."); + } + let disposer; + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRoot)(dispose => { + disposer = dispose; + element === document ? code() : insert(element, code(), element.firstChild ? null : undefined, init); + }, options.owner); + return () => { + disposer(); + element.textContent = ""; + }; +} +function template(html, isCE, isSVG) { + let node; + const create = () => { + if (isHydrating()) throw new Error("Failed attempt to create new DOM elements during hydration. Check that the libraries you are using support hydration."); + const t = document.createElement("template"); + t.innerHTML = html; + return isSVG ? t.content.firstChild.firstChild : t.content.firstChild; + }; + const fn = isCE ? () => (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack)(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true); + fn.cloneNode = fn; + return fn; +} +function delegateEvents(eventNames, document = window.document) { + const e = document[$$EVENTS] || (document[$$EVENTS] = new Set()); + for (let i = 0, l = eventNames.length; i < l; i++) { + const name = eventNames[i]; + if (!e.has(name)) { + e.add(name); + document.addEventListener(name, eventHandler); + } + } +} +function clearDelegatedEvents(document = window.document) { + if (document[$$EVENTS]) { + for (let name of document[$$EVENTS].keys()) document.removeEventListener(name, eventHandler); + delete document[$$EVENTS]; + } +} +function setProperty(node, name, value) { + if (isHydrating(node)) return; + node[name] = value; +} +function setAttribute(node, name, value) { + if (isHydrating(node)) return; + if (value == null) node.removeAttribute(name);else node.setAttribute(name, value); +} +function setAttributeNS(node, namespace, name, value) { + if (isHydrating(node)) return; + if (value == null) node.removeAttributeNS(namespace, name);else node.setAttributeNS(namespace, name, value); +} +function className(node, value) { + if (isHydrating(node)) return; + if (value == null) node.removeAttribute("class");else node.className = value; +} +function addEventListener(node, name, handler, delegate) { + if (delegate) { + if (Array.isArray(handler)) { + node[`$$${name}`] = handler[0]; + node[`$$${name}Data`] = handler[1]; + } else node[`$$${name}`] = handler; + } else if (Array.isArray(handler)) { + const handlerFn = handler[0]; + node.addEventListener(name, handler[0] = e => handlerFn.call(node, handler[1], e)); + } else node.addEventListener(name, handler); +} +function classList(node, value, prev = {}) { + const classKeys = Object.keys(value || {}), + prevKeys = Object.keys(prev); + let i, len; + for (i = 0, len = prevKeys.length; i < len; i++) { + const key = prevKeys[i]; + if (!key || key === "undefined" || value[key]) continue; + toggleClassKey(node, key, false); + delete prev[key]; + } + for (i = 0, len = classKeys.length; i < len; i++) { + const key = classKeys[i], + classValue = !!value[key]; + if (!key || key === "undefined" || prev[key] === classValue || !classValue) continue; + toggleClassKey(node, key, true); + prev[key] = classValue; + } + return prev; +} +function style(node, value, prev) { + if (!value) return prev ? setAttribute(node, "style") : value; + const nodeStyle = node.style; + if (typeof value === "string") return nodeStyle.cssText = value; + typeof prev === "string" && (nodeStyle.cssText = prev = undefined); + prev || (prev = {}); + value || (value = {}); + let v, s; + for (s in prev) { + value[s] == null && nodeStyle.removeProperty(s); + delete prev[s]; + } + for (s in value) { + v = value[s]; + if (v !== prev[s]) { + nodeStyle.setProperty(s, v); + prev[s] = v; + } + } + return prev; +} +function spread(node, props = {}, isSVG, skipChildren) { + const prevProps = {}; + if (!skipChildren) { + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => prevProps.children = insertExpression(node, props.children, prevProps.children)); + } + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => typeof props.ref === "function" && use(props.ref, node)); + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => assign(node, props, isSVG, true, prevProps, true)); + return prevProps; +} +function dynamicProperty(props, key) { + const src = props[key]; + Object.defineProperty(props, key, { + get() { + return src(); + }, + enumerable: true + }); + return props; +} +function use(fn, element, arg) { + return (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack)(() => fn(element, arg)); +} +function insert(parent, accessor, marker, initial) { + if (marker !== undefined && !initial) initial = []; + if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker); + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(current => insertExpression(parent, accessor(), current, marker), initial); +} +function assign(node, props, isSVG, skipChildren, prevProps = {}, skipRef = false) { + props || (props = {}); + for (const prop in prevProps) { + if (!(prop in props)) { + if (prop === "children") continue; + prevProps[prop] = assignProp(node, prop, null, prevProps[prop], isSVG, skipRef); + } + } + for (const prop in props) { + if (prop === "children") { + if (!skipChildren) insertExpression(node, props.children); + continue; + } + const value = props[prop]; + prevProps[prop] = assignProp(node, prop, value, prevProps[prop], isSVG, skipRef); + } +} +function hydrate$1(code, element, options = {}) { + if (globalThis._$HY.done) return render(code, element, [...element.childNodes], options); + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed = globalThis._$HY.completed; + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events = globalThis._$HY.events; + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.load = id => globalThis._$HY.r[id]; + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.has = id => id in globalThis._$HY.r; + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.gather = root => gatherHydratable(element, root); + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry = new Map(); + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context = { + id: options.renderId || "", + count: 0 + }; + try { + gatherHydratable(element, options.renderId); + return render(code, element, [...element.childNodes], options); + } finally { + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context = null; + } +} +function getNextElement(template) { + let node, + key, + hydrating = isHydrating(); + if (!hydrating || !(node = solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.get(key = getHydrationKey()))) { + if (hydrating) throw new Error(`Hydration Mismatch. Unable to find DOM nodes for hydration key: ${key}`); + return template(); + } + if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed) solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed.add(node); + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.delete(key); + return node; +} +function getNextMatch(el, nodeName) { + while (el && el.localName !== nodeName) el = el.nextSibling; + return el; +} +function getNextMarker(start) { + let end = start, + count = 0, + current = []; + if (isHydrating(start)) { + while (end) { + if (end.nodeType === 8) { + const v = end.nodeValue; + if (v === "$") count++;else if (v === "/") { + if (count === 0) return [end, current]; + count--; + } + } + current.push(end); + end = end.nextSibling; + } + } + return [end, current]; +} +function runHydrationEvents() { + if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events.queued) { + queueMicrotask(() => { + const { + completed, + events + } = solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig; + events.queued = false; + while (events.length) { + const [el, e] = events[0]; + if (!completed.has(el)) return; + events.shift(); + eventHandler(e); + } + if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done) { + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events = _$HY.events = null; + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed = _$HY.completed = null; + } + }); + solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events.queued = true; + } +} +function isHydrating(node) { + return !!solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done && (!node || node.isConnected); +} +function toPropertyName(name) { + return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase()); +} +function toggleClassKey(node, key, value) { + const classNames = key.trim().split(/\s+/); + for (let i = 0, nameLen = classNames.length; i < nameLen; i++) node.classList.toggle(classNames[i], value); +} +function assignProp(node, prop, value, prev, isSVG, skipRef) { + let isCE, isProp, isChildProp, propAlias, forceProp; + if (prop === "style") return style(node, value, prev); + if (prop === "classList") return classList(node, value, prev); + if (value === prev) return prev; + if (prop === "ref") { + if (!skipRef) value(node); + } else if (prop.slice(0, 3) === "on:") { + const e = prop.slice(3); + prev && node.removeEventListener(e, prev); + value && node.addEventListener(e, value); + } else if (prop.slice(0, 10) === "oncapture:") { + const e = prop.slice(10); + prev && node.removeEventListener(e, prev, true); + value && node.addEventListener(e, value, true); + } else if (prop.slice(0, 2) === "on") { + const name = prop.slice(2).toLowerCase(); + const delegate = DelegatedEvents.has(name); + if (!delegate && prev) { + const h = Array.isArray(prev) ? prev[0] : prev; + node.removeEventListener(name, h); + } + if (delegate || value) { + addEventListener(node, name, value, delegate); + delegate && delegateEvents([name]); + } + } else if (prop.slice(0, 5) === "attr:") { + setAttribute(node, prop.slice(5), value); + } else if ((forceProp = prop.slice(0, 5) === "prop:") || (isChildProp = ChildProperties.has(prop)) || !isSVG && ((propAlias = getPropAlias(prop, node.tagName)) || (isProp = Properties.has(prop))) || (isCE = node.nodeName.includes("-"))) { + if (forceProp) { + prop = prop.slice(5); + isProp = true; + } else if (isHydrating(node)) return value; + if (prop === "class" || prop === "className") className(node, value);else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value;else node[propAlias || prop] = value; + } else { + const ns = isSVG && prop.indexOf(":") > -1 && SVGNamespace[prop.split(":")[0]]; + if (ns) setAttributeNS(node, ns, prop, value);else setAttribute(node, Aliases[prop] || prop, value); + } + return value; +} +function eventHandler(e) { + if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry && solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events) { + if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events.find(([el, ev]) => ev === e)) return; + } + const key = `$$${e.type}`; + let node = e.composedPath && e.composedPath()[0] || e.target; + if (e.target !== node) { + Object.defineProperty(e, "target", { + configurable: true, + value: node + }); + } + Object.defineProperty(e, "currentTarget", { + configurable: true, + get() { + return node || document; + } + }); + if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done) solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done = _$HY.done = true; + while (node) { + const handler = node[key]; + if (handler && !node.disabled) { + const data = node[`${key}Data`]; + data !== undefined ? handler.call(node, data, e) : handler.call(node, e); + if (e.cancelBubble) return; + } + node = node._$host || node.parentNode || node.host; + } +} +function insertExpression(parent, value, current, marker, unwrapArray) { + const hydrating = isHydrating(parent); + if (hydrating) { + !current && (current = [...parent.childNodes]); + let cleaned = []; + for (let i = 0; i < current.length; i++) { + const node = current[i]; + if (node.nodeType === 8 && node.data.slice(0, 2) === "!$") node.remove();else cleaned.push(node); + } + current = cleaned; + } + while (typeof current === "function") current = current(); + if (value === current) return current; + const t = typeof value, + multi = marker !== undefined; + parent = multi && current[0] && current[0].parentNode || parent; + if (t === "string" || t === "number") { + if (hydrating) return current; + if (t === "number") { + value = value.toString(); + if (value === current) return current; + } + if (multi) { + let node = current[0]; + if (node && node.nodeType === 3) { + node.data !== value && (node.data = value); + } else node = document.createTextNode(value); + current = cleanChildren(parent, current, marker, node); + } else { + if (current !== "" && typeof current === "string") { + current = parent.firstChild.data = value; + } else current = parent.textContent = value; + } + } else if (value == null || t === "boolean") { + if (hydrating) return current; + current = cleanChildren(parent, current, marker); + } else if (t === "function") { + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => { + let v = value(); + while (typeof v === "function") v = v(); + current = insertExpression(parent, v, current, marker); + }); + return () => current; + } else if (Array.isArray(value)) { + const array = []; + const currentArray = current && Array.isArray(current); + if (normalizeIncomingArray(array, value, current, unwrapArray)) { + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => current = insertExpression(parent, array, current, marker, true)); + return () => current; + } + if (hydrating) { + if (!array.length) return current; + if (marker === undefined) return current = [...parent.childNodes]; + let node = array[0]; + if (node.parentNode !== parent) return current; + const nodes = [node]; + while ((node = node.nextSibling) !== marker) nodes.push(node); + return current = nodes; + } + if (array.length === 0) { + current = cleanChildren(parent, current, marker); + if (multi) return current; + } else if (currentArray) { + if (current.length === 0) { + appendNodes(parent, array, marker); + } else reconcileArrays(parent, current, array); + } else { + current && cleanChildren(parent); + appendNodes(parent, array); + } + current = array; + } else if (value.nodeType) { + if (hydrating && value.parentNode) return current = multi ? [value] : value; + if (Array.isArray(current)) { + if (multi) return current = cleanChildren(parent, current, marker, value); + cleanChildren(parent, current, null, value); + } else if (current == null || current === "" || !parent.firstChild) { + parent.appendChild(value); + } else parent.replaceChild(value, parent.firstChild); + current = value; + } else console.warn(`Unrecognized value. Skipped inserting`, value); + return current; +} +function normalizeIncomingArray(normalized, array, current, unwrap) { + let dynamic = false; + for (let i = 0, len = array.length; i < len; i++) { + let item = array[i], + prev = current && current[normalized.length], + t; + if (item == null || item === true || item === false) ; else if ((t = typeof item) === "object" && item.nodeType) { + normalized.push(item); + } else if (Array.isArray(item)) { + dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic; + } else if (t === "function") { + if (unwrap) { + while (typeof item === "function") item = item(); + dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic; + } else { + normalized.push(item); + dynamic = true; + } + } else { + const value = String(item); + if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev);else normalized.push(document.createTextNode(value)); + } + } + return dynamic; +} +function appendNodes(parent, array, marker = null) { + for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker); +} +function cleanChildren(parent, current, marker, replacement) { + if (marker === undefined) return parent.textContent = ""; + const node = replacement || document.createTextNode(""); + if (current.length) { + let inserted = false; + for (let i = current.length - 1; i >= 0; i--) { + const el = current[i]; + if (node !== el) { + const isParent = el.parentNode === parent; + if (!inserted && !i) isParent ? parent.replaceChild(node, el) : parent.insertBefore(node, marker);else isParent && el.remove(); + } else inserted = true; + } + } else parent.insertBefore(node, marker); + return [node]; +} +function gatherHydratable(element, root) { + const templates = element.querySelectorAll(`*[data-hk]`); + for (let i = 0; i < templates.length; i++) { + const node = templates[i]; + const key = node.getAttribute("data-hk"); + if ((!root || key.startsWith(root)) && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.has(key)) solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.set(key, node); + } +} +function getHydrationKey() { + return solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.getNextContextId(); +} +function NoHydration(props) { + return solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context ? undefined : props.children; +} +function Hydration(props) { + return props.children; +} +const voidFn = () => undefined; +const RequestContext = Symbol(); +function innerHTML(parent, content) { + !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context && (parent.innerHTML = content); +} + +function throwInBrowser(func) { + const err = new Error(`${func.name} is not supported in the browser, returning undefined`); + console.error(err); +} +function renderToString(fn, options) { + throwInBrowser(renderToString); +} +function renderToStringAsync(fn, options) { + throwInBrowser(renderToStringAsync); +} +function renderToStream(fn, options) { + throwInBrowser(renderToStream); +} +function ssr(template, ...nodes) {} +function ssrElement(name, props, children, needsId) {} +function ssrClassList(value) {} +function ssrStyle(value) {} +function ssrAttribute(key, value) {} +function ssrHydrationKey() {} +function resolveSSRNode(node) {} +function escape(html) {} +function ssrSpread(props, isSVG, skipChildren) {} + +const isServer = false; +const isDev = true; +const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; +function createElement(tagName, isSVG = false) { + return isSVG ? document.createElementNS(SVG_NAMESPACE, tagName) : document.createElement(tagName); +} +const hydrate = (...args) => { + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.enableHydration)(); + return hydrate$1(...args); +}; +function Portal(props) { + const { + useShadow + } = props, + marker = document.createTextNode(""), + mount = () => props.mount || document.body, + owner = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.getOwner)(); + let content; + let hydrating = !!solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context; + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createEffect)(() => { + if (hydrating) (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.getOwner)().user = hydrating = false; + content || (content = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.runWithOwner)(owner, () => (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo)(() => props.children))); + const el = mount(); + if (el instanceof HTMLHeadElement) { + const [clean, setClean] = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createSignal)(false); + const cleanup = () => setClean(true); + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRoot)(dispose => insert(el, () => !clean() ? content() : dispose(), null)); + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.onCleanup)(cleanup); + } else { + const container = createElement(props.isSVG ? "g" : "div", props.isSVG), + renderRoot = useShadow && container.attachShadow ? container.attachShadow({ + mode: "open" + }) : container; + Object.defineProperty(container, "_$host", { + get() { + return marker.parentNode; + }, + configurable: true + }); + insert(renderRoot, content); + el.appendChild(container); + props.ref && props.ref(container); + (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.onCleanup)(() => el.removeChild(container)); + } + }, undefined, { + render: !hydrating + }); + return marker; +} +function Dynamic(props) { + const [p, others] = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.splitProps)(props, ["component"]); + const cached = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo)(() => p.component); + return (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo)(() => { + const component = cached(); + switch (typeof component) { + case "function": + Object.assign(component, { + [solid_js__WEBPACK_IMPORTED_MODULE_0__.$DEVCOMP]: true + }); + return (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack)(() => component(others)); + case "string": + const isSvg = SVGElements.has(component); + const el = solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context ? getNextElement() : createElement(component, isSvg); + spread(el, others, isSvg); + return el; + } + }); +} + + + + +/***/ }), + +/***/ "./node_modules/solid-styled-components/src/index.js": +/*!***********************************************************!*\ + !*** ./node_modules/solid-styled-components/src/index.js ***! + \***********************************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ThemeProvider: () => (/* binding */ ThemeProvider), +/* harmony export */ createGlobalStyles: () => (/* binding */ createGlobalStyles), +/* harmony export */ css: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.css), +/* harmony export */ extractCss: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.extractCss), +/* harmony export */ glob: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.glob), +/* harmony export */ keyframes: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.keyframes), +/* harmony export */ setup: () => (/* binding */ setup), +/* harmony export */ shouldForwardProp: () => (/* binding */ shouldForwardProp), +/* harmony export */ styled: () => (/* binding */ styled), +/* harmony export */ useTheme: () => (/* binding */ useTheme) +/* harmony export */ }); +/* harmony import */ var goober__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! goober */ "./node_modules/goober/dist/goober.modern.js"); +/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); +/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/web/dist/dev.js"); + + + + + +let getForwardProps = null; + +function shouldForwardProp(predicate) { + return props => props.filter(predicate); +} + +function setup(prefixer, shouldForwardProp = null) { + (0,goober__WEBPACK_IMPORTED_MODULE_0__.setup)(null, prefixer); + getForwardProps = shouldForwardProp; +} +const ThemeContext = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.createContext)(); +function ThemeProvider(props) { + return (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.createComponent)(ThemeContext.Provider, { + value: props.theme, + get children() { + return props.children; + } + }); +} +function useTheme() { + return (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.useContext)(ThemeContext); +} + +function makeStyled(tag) { + let _ctx = this || {}; + return (...args) => { + const Styled = props => { + const theme = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.useContext)(ThemeContext); + const withTheme = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.mergeProps)(props, { theme }); + const clone = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.mergeProps)(withTheme, { + get class() { + const pClass = withTheme.class, + append = "class" in withTheme && /^go[0-9]+/.test(pClass); + // Call `css` with the append flag and pass the props + let className = goober__WEBPACK_IMPORTED_MODULE_0__.css.apply( + { target: _ctx.target, o: append, p: withTheme, g: _ctx.g }, + args + ); + return [pClass, className].filter(Boolean).join(" "); + } + }); + const [local, newProps] = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.splitProps)(clone, ["as", "theme"]); + const htmlProps = getForwardProps + ? (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.splitProps)(newProps, getForwardProps(Object.keys(newProps)))[0] + : newProps; + const createTag = local.as || tag; + let el; + + if (typeof createTag === "function") { + el = createTag(htmlProps); + } else { + if (solid_js_web__WEBPACK_IMPORTED_MODULE_2__.isServer) { + const [local, others] = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.splitProps)(htmlProps, ["children", "theme"]); + el = (0,solid_js_web__WEBPACK_IMPORTED_MODULE_2__.Dynamic)({ + component: createTag, + get children() { + return local.children; + }, + ...others + }); + } else { + if (_ctx.g == 1) { + // When using Global Styles we don't want to hydrate the unused nodes + el = document.createElement(createTag); + (0,solid_js_web__WEBPACK_IMPORTED_MODULE_2__.spread)(el, htmlProps); + } else { + el = (0,solid_js_web__WEBPACK_IMPORTED_MODULE_2__.Dynamic)((0,solid_js__WEBPACK_IMPORTED_MODULE_1__.mergeProps)({ component: createTag }, htmlProps)); + } + } + } + return el; + }; + Styled.class = props => { + return (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.untrack)(() => { + return goober__WEBPACK_IMPORTED_MODULE_0__.css.apply({ target: _ctx.target, p: props, g: _ctx.g }, args); + }); + }; + + return Styled; + }; +} + +const styled = new Proxy(makeStyled, { + get(target, tag) { + return target(tag); + } +}); + +function createGlobalStyles() { + const fn = makeStyled.call({ g: 1 }, "div").apply(null, arguments); + + return function GlobalStyles(props) { + fn(props); + return null; + }; +} + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat get default export */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!**********************!*\ + !*** ./src/main.tsx ***! + \**********************/ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/web/dist/dev.js"); +/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/dist/dev.js"); +/* harmony import */ var solid_styled_components__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! solid-styled-components */ "./node_modules/solid-styled-components/src/index.js"); +/* harmony import */ var _state_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./state.ts */ "./src/state.ts"); +/* harmony import */ var _timeline__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./timeline */ "./src/timeline/index.ts"); + + + + +var _tmpl$ = /*#__PURE__*/(0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.template)(`
Hello, world!
\r\n
\r\n \r\n \r\n}\r\n\r\n\r\nconst AppRoot = styled.div`\r\n display: grid;\r\n grid-template: auto 1fr / 1fr;\r\n margin: auto;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n`\r\n\r\n\r\nSolidWeb.render(\r\n App,\r\n document.getElementById(\"app\")!)"],"names":["makeNew","timeline","bkgColor","bkgAlternateMeasureColor","bkgInactiveOverlayColor","trackVBorderColor","trackHBorderColor","selectionCursorColor","selectionBkgColor","playbackCursorColor","trackSeparatorColor","measureColor","submeasureColor","halfSubmeasureColor","measureLabelColor","octaveLabelColor","meterChangeColor","keyChangeColor","noteVelocityMarkerColor","noteVelocityMarkerInactiveColor","keyPan","keyPencil","keySelectMultiple","keySelectRange","keySelectRect","keySelectClone","keyDisplaceCursor2","keyDisplaceFast","keyDisplaceChromatically","keyDisplaceStretch","mouseDoubleClickThresholdMs","mouseDragXLockedDistance","mouseDragYLockedDistance","mouseEdgeScrollThreshold","mouseEdgeScrollSpeed","Range","MinVolumeDb","MaxVolumeDb","DefaultVolumeDb","DefaultChordVolumeDb","elemModify","original","changes","makeTrackNotes","type","trackType","id","parentId","range","dummy","name","mute","solo","makeTrackChords","trackDisplayName","track","makeTrackKeyChanges","makeTrackMeterChanges","makeMeterChange","time","meter","fromPoint","makeKeyChange","key","makeNote","midiPitch","makeChord","chord","Project","BinarySearch","measureCacheKey","measureCache","firstMeterCh","lastMeterCh","ensureMeasureCacheRefreshed","project","meterChangeTrackId","meterChangeList","lists","get","num","elem1","elem2","iterAllPairwise","meterCh1","meterCh2","numLocal","measureN","measureD","time1","time2","iterMeasuresPairwise","start","compare","push","min","meterCh","iterMeasuresAtRange","measureStart","findPreviousOrEqual","m","subtract","fullCycleDuration","add","lastMeasureNum","measureIndex","length","measure","end","Immutable","Theory","Rational","ListOfRanges","MAX_RATIONAL_DENOMINATOR","makeEmpty","nextId","baseBpm","tracks","Map","elems","keyChangeTrackId","chordTrackId","noteTrackId","track1Id","upsertTrack","track2Id","upsertElement","Key","parse","Meter","track3Id","track4Id","makeTest","i","fromStartDuration","Utils","midiMiddleC","remove","insertBefore","trackIndex","findIndex","t","slice","delete","set","elem","prevElem","changeParent","list","upsert","prevList","removeById","nextList","keyAt","trackId","keyChangeTrackTimedElems","defaultKey","keyCh","findActiveAt","firstKeyCh","findFirst","meterChangeAt","meterChangeTrackTimedElems","meterAt","defaultMeter","withRefreshedRange","merge","getTotalRange","getElem","getTrack","cloneElem","fromProject","toProject","newElem","newId","innerList","innerElem","iterAll","newInnerElem","splitElem","splitRange","origProject","absRange","getAbsoluteRange","overlapsRange","removeElem","splitInnerElem","newParentId","relativeDisplace","keepRange","iterSlices","newElemPart","getRelativeRange","newElemPartId","innerRelativeDisplace","parentTrackFor","elemId","getAbsoluteTime","getRelativeTime","displace","getRangeForElems","elemIds","getMillisecondsAt","measuresPerSecond","asFloat","Solid","Timeline","Prefs","state","setState","createSignal","test","prefs","root","refresh","MathUtils","chordKinds","pitches","symbol","startGroup","Chord","kinds","constructor","rootChroma","kind","inversion","modifiers","withChanges","obj","Object","assign","kindFromId","k","kindFromPitches","every","p","suggestChordsForPitches","suggestions","rootPitch","matches","Set","misses","pitch","relPitch","mod","kindMatch","size","sort","a","b","kindId","romanBase","degree","degreeForMidi","chordKind","roman","Math","floor","accidental","baseStr","accidentalToStr","degreeToRomanStr","toLowerCase","romanSup","supStr","add9","add11","add13","no3","no5","romanSub","subStr","sus2","sus4","chordData","rootMidi","splice","strummingPitches","octave","map","x","y","sum","reduce","shift","unshift","default","Pitch","PitchName","Scale","tonic","scale","_chromaToDegree","chromas","chroma","midi","nextDegree","nextChroma","testNextChroma","fromTonicAndScale","str","trim","separator","indexOf","tonicStr","substr","scaleStr","toString","degreeForChroma","degreeForPitch","octavedDegreeForMidi","degreeOctave","octavedDegreeForPitch","midiForDegree","octavedDegree","pitchForDegree","fromMidi","chromaForDegree","nameForMidi","letter1","letter","accidental1","letterToChroma","letter2","accidental2","letter3","accidental3","attempts","abs","nameForPitch","nameForChroma","nameForDegree","namedPitches","numerator","denominator","nextTime","alternatingMeasureCount","src","split","parseInt","isFinite","fromOctaveAndChroma","fromOctaveAndName","pitchName","c","charCodeAt","undefined","isNaN","frequency","pow","chromaToLetter","chromaToAccidental","fromChroma","letterStr","strToLetter","altered","additionalAccidental","simplified","letterToStr","accidentalStr","strUnicode","knownScales","mode","names","metadata","find","s","index","fromChromas","fromId","knownScale","some","n","alterationsFromMajor","join","chromaToDegreeInCMajor","d","e","f","g","degreeToColor","degreeToColorFaded","useUnicode","repeat","Global","Rect","Element","props","div","canvas","createEffect","cleanup","registerHandlers","onCleanup","_el$","_tmpl$","_el$2","firstChild","_ref$","_$use","style","setProperty","_ref$2","canvasResize","pixelRatio","window","devicePixelRatio","domRect","getBoundingClientRect","w","width","h","height","rect","resize","ctx","getContext","transformMousePos","ev","clientX","left","clientY","top","setCursor","action","mouse","down","hover","cursor","MouseAction","DragTime","DragRow","DragTimeAndRow","StretchTimeStart","StretchTimeEnd","onResize","layout","draw","onMouseMove","preventDefault","mouseMove","mouseDrag","onMouseDown","mouseDown","button","onMouseUp","mouseUp","onMouseWheel","mouseWheel","deltaX","deltaY","onKeyDown","keyDown","onKeyUp","keyUp","addEventListener","removeEventListener","State","save","translate","fillStyle","fillRect","renderRect","drawElements","elements","visible","timeMin","timeMax","max","drawCursorBeam","restore","element","beginPath","clip","drawLaneBkgSolid","drawLaneBkgMeasures","drawCursorBkg","subElements","drawLaneFrgOutline","drawLaneBkgOctaves","roundRect","noteRowH","fill","selection","has","strokeStyle","lineWidth","stroke","drawLaneBkgCenterStroke","lane","yCenter","moveTo","lineTo","mainLinePass","measureHalfH","submeasureHalfH","measures","x1","xAtTime","x2","submeasureSize","submeasureX","round","rowAtTop","rowAtY","rowAtBottom","octaveAtTop","ceil","octaveAtBottom","font","textAlign","textBaseline","keyRegion","keyRegions","tonicRowOffset","keyCh1","needsOctaveLabels","drewOctaveLabels","yForRow","labelX","fillText","j","ySuboctave","tipOffsetSide","laneIndexMin","cursorGetLaneIndexMin","laneIndexMax","cursorGetLaneIndexMax","laneMin","lanes","laneMax","lineCap","headYSize","headXSize","y1","y2","laneIndex","keysDown","Layout","elementCount","parent","visibleTimeRange","iterKeyChangePairsAtRange","laneMarkerH","laneChordH","laneMarginH","laneKeyChanges","laneMeterChanges","laneChords","laneNotesY","laneNotes","layoutLaneNotes","console","log","pair","iterActiveAtRangePairwise","keyCh2","iterElementsAtRegion","verticalRegion","iterNotesAtRegion","note","keyChPair","iterNotesAndKeyChanges","row","rowForPitch","cutStart","cutEnd","rectForNote","rectStretchStart","withX1","rectStretchEnd","withX2","priority","iterNotes","iterAtRange","pitchForRow","yScroll","noteRange","noteRow","keyChXStart","keyChXEnd","clampY","noteOrigX1","noteOrigX2","noteY","noteX1","noteX2","noteW","rightButton","prevDownDate","downDate","Date","None","selectMultiple","selectRange","selectClone","selectRect","forcePan","doubleClick","getTime","drag","origin","point","timeScroll","xLocked","yLocked","posDelta","timeDelta","rowDelta","trackDelta","trackInsertionBefore","notePreviewLast","Pan","hoverIsSelected","selectionClear","SelectCursor","cursorSetTime","rectY1","rectY2","trackPos","laneIndex1","laneIndex2","selectionToggle","selectionRange","pointPrev","pointAt","pos","handlePanning","handleSelectCursor","handleDragElements","timeScale","selectionAddAtCursor","newProject","quantize","stretch","snap","timeSnap","sorted","newPitch","hoverRecursive","wheelDate","prevMouseTime","timeAtX","newTimeScale","newMouseTime","newTimeScroll","timeSnapAdjustThresholdUpper","timeSnapAdjustThresholdLower","newTimeSnap","timeSnapBase","divide","trackMeasuresH","trackControlX","trackControlY","trackControlSize","originTrackPos","insertion","nearMidiPitch","duration","needsKeyFinish","rangeSelectOriginTrackIndex","fromFloat","timeRangeAtX","laneIndexAtY","clear","alreadySelected","selectionAdd","l","cursorSetTrack","trackIndex1","trackIndex2","array","compareFn","lo","hi","mi","findExact","value","findPreviousNotEqual","findNextNotEqual","iterEqual","assert","Bucket","idMap","buckets","bucketFn","clone","cloned","_ensureBucketsAtRange","newBuckets","newBucket","_iterBucketIndicesAtRange","bucket","update","newList","newElemIndex","upsertMany","removeId","elemIndex","findById","elemStart","firstBucket","iterAtPoint","item","prevItem","findPrevious","nextItem","firstElem","lastElem","result","findPreviousAnchor","previous","endB","nearestItem","nearestPoint","itemRange","findPreviousDeletionAnchor","anchor","anchorRange","deepEqual","elem3","elem4","elem5","elem1_2","step","midiToHertz","dbToLinearGain","db","linearGainToDb","linearGain","log10","minMidiDbLevel","dbToMidiVolume","midiVolumeToDb","midiVol","midiVolumeToLinearGain","startInclusive","endInclusive","setDuration","newDuration","lessThan","greaterThan","other","r1","r2","intersect","atZero","offset","pivot","grow","shrink","isPoint","equalTo","overlapsPoint","compStart","compEnd","checkStart","checkEnd","containsRangeCompletely","maxDenom","toJson","fromJson","json","simplifyInPlace","floatValue","maxDenominator","integer","frac","fromIntegerPlusRational","numeratorWithoutInteger","negate","absolute","multiply","multiplyByFloat","simplify","dist","move","isZero","thisNumerator","otherNumerator","notEqualTo","lessThanOrEqual","greaterThanOrEqual","trySimplifyInPlaceBy","divider","fromVertices","fromElement","clientRect","xCenter","withX","withY","withW","withH","withY1","withY2","expand","amount","expandW","contains","overlaps","SolidWeb","styled","App","_$createComponent","AppRoot","children","_el$3","nextSibling","_el$4","_$insert","$$click","render","document","getElementById","_$delegateEvents"],"sourceRoot":""} \ No newline at end of file diff --git a/build-ghpages.bat b/build-ghpages.bat deleted file mode 100644 index 411c58b..0000000 --- a/build-ghpages.bat +++ /dev/null @@ -1,10 +0,0 @@ -git branch -D ghpages -git checkout -b ghpages -del .gitignore -move .gitignore.ghpages .gitignore -cmd /C npm run build -git describe --tags --match v* > build/build_version.txt -git add -A -git commit -m "build GitHub Pages" -git push -f origin ghpages -git checkout main \ No newline at end of file diff --git a/index.html b/index.html index a891ab1..c406557 100644 --- a/index.html +++ b/index.html @@ -5,28 +5,26 @@ - TheoryTracker + TheoryTracker2 -
+
- + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8490349..5f5f255 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,34 +1,22 @@ { - "name": "theorytracker", + "name": "theorytracker2", "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "theorytracker", + "name": "theorytracker2", "version": "0.1.0", "dependencies": { - "@babel/core": "^7.22.5", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/preset-env": "^7.22.5", - "@babel/preset-react": "^7.22.5", - "@types/node": "^20.2.5", - "@types/react": "^18.2.9", - "@types/react-dom": "^18.2.4", - "@types/styled-components": "^5.1.26", - "@types/wicg-file-system-access": "^2020.9.6", - "babel-loader": "^9.1.2", - "core-js": "^3.30.2", - "immutable": "^4.3.0", - "pako": "^2.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "regenerator-runtime": "^0.13.11", - "source-map-loader": "^4.0.1", - "styled-components": "^5.3.11", - "ts-loader": "^9.4.3", - "typescript": "^5.1.3", - "webpack": "^5.86.0", + "@babel/preset-typescript": "^7.24.6", + "babel-loader": "^9.1.3", + "babel-preset-solid": "^1.8.17", + "immutable": "^4.3.7", + "solid-js": "^1.8.17", + "solid-styled-components": "^0.28.5", + "ts-node": "^10.9.2", + "typescript": "^5.4.5", + "webpack": "^5.91.0", "webpack-cli": "^5.1.4" } }, @@ -36,6 +24,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -45,11 +34,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -59,6 +49,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", + "peer": true, "engines": { "node": ">=6.9.0" } @@ -67,6 +58,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.5", @@ -93,13 +85,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dependencies": { - "@babel/types": "^7.22.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -107,35 +99,24 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "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==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", - "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -145,6 +126,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", + "peer": true, "dependencies": { "@babel/compat-data": "^7.22.5", "@babel/helper-validator-option": "^7.22.5", @@ -163,6 +145,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "peer": true, "dependencies": { "yallist": "^3.0.2" } @@ -170,38 +153,21 @@ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz", - "integrity": "sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==", - "dependencies": { - "@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.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz", - "integrity": "sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.0" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -210,121 +176,74 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz", - "integrity": "sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg==", - "dependencies": { - "@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" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", - "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", - "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz", - "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -333,89 +252,50 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz", - "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-simple-access": { - "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "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==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "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==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz", - "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==", - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - }, + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "engines": { "node": ">=6.9.0" } @@ -424,6 +304,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", + "peer": true, "dependencies": { "@babel/template": "^7.22.5", "@babel/traverse": "^7.22.5", @@ -434,22 +315,26 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -457,43 +342,42 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.5", - "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.5.tgz", - "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", - "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.13.0" + "@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==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -502,10 +386,17 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "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==", + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", + "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" + }, "engines": { "node": ">=6.9.0" }, @@ -513,1620 +404,1537 @@ "@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==", + "node_modules/@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" }, "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", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "node_modules/@babel/traverse": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", + "globals": "^11.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@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==", + "node_modules/@babel/types": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@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==", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@jridgewell/trace-mapping": "0.3.9" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=12" } }, - "node_modules/@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==", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", + "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10.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==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" }, "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6.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", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "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==", + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6.0.0" } }, - "node_modules/@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==", + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, - "node_modules/@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==", + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "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==" }, - "node_modules/@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==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" }, - "node_modules/@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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, - "node_modules/@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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, - "node_modules/@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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, - "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==", + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "node_modules/@types/node": { + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dependencies": { - "@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" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "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==", + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz", - "integrity": "sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==", + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "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==", + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dependencies": { - "@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" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "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==", + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "engines": { - "node": ">=6.9.0" + "node": ">=14.15.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", - "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "engines": { - "node": ">=6.9.0" + "node": ">=14.15.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, - "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==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "engines": { - "node": ">=6.9.0" + "node": ">=14.15.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=6.9.0" - }, + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "peerDependencies": { - "@babel/core": "^7.12.0" + "acorn": "^8" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz", - "integrity": "sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ==", + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@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.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "globals": "^11.1.0" + "acorn": "^8.11.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.4.0" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "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==", + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.5" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6.9.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", - "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "fast-deep-equal": "^3.1.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "ajv": "^8.8.2" } }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "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==", + "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==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "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==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 14.15.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.12.0", + "webpack": ">=5" } }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "node_modules/babel-plugin-jsx-dom-expressions": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.38.5.tgz", + "integrity": "sha512-JfjHYKOKGwoiOYQ56Oo8gbZPb9wNMpPuEEUhSCjMpnuHM9K21HFIUBm83TZPB40Av4caCIW4Tfjzpkp/MtFpMw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-module-imports": "7.18.6", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.20.7", + "html-entities": "2.3.3", + "validate-html-nesting": "^1.2.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.20.12" } }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "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==", + "node_modules/babel-plugin-jsx-dom-expressions/node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "node_modules/babel-preset-solid": { + "version": "1.8.22", + "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.8.22.tgz", + "integrity": "sha512-nKwisb//lZsiRF2NErlRP64zVTJqa1OSZiDnSl0YbcTiCZoMt52CY2Pg+9fsYAPtjYMT7RHBmzU41pxK6hFOcg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "babel-plugin-jsx-dom-expressions": "^0.38.5" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "node_modules/browserslist": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, - "engines": { - "node": ">=6.9.0" + "bin": { + "browserslist": "cli.js" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@babel/plugin-transform-function-name": { - "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==", + "node_modules/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==" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001655", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", + "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "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==", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6.0" } }, - "node_modules/@babel/plugin-transform-literals": { - "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==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "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==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "color-name": "1.1.3" } }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "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==", + "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==" + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "node_modules/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==" + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "safe-buffer": "~5.1.1" } }, - "node_modules/@babel/plugin-transform-modules-amd": { - "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==", + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 8" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" + "ms": "2.1.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5" - }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.3.1" } }, - "node_modules/@babel/plugin-transform-modules-umd": { - "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==", + "node_modules/electron-to-chromium": { + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10.13.0" } }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "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==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "bin": { + "envinfo": "dist/cli.js" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=4" } }, - "node_modules/@babel/plugin-transform-new-target": { - "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/es-module-lexer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", + "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.8.0" } }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8.0.0" } }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.5" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4.0" } }, - "node_modules/@babel/plugin-transform-object-super": { - "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==", - "dependencies": { - "@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/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "engines": { + "node": ">=4.0" } }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4.0" } }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz", - "integrity": "sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ==", - "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" - }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.8.x" } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.16" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/find-cache-dir/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "node_modules/find-cache-dir/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "p-locate": "^6.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-property-literals": { - "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==", + "node_modules/find-cache-dir/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", - "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", + "node_modules/find-cache-dir/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "p-limit": "^4.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", - "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" - }, + "node_modules/find-cache-dir/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" + "find-up": "^6.3.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.16" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", - "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", - "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/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==", + "peer": true, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "engines": { - "node": ">=6.9.0" - }, + "node": ">=4" + } + }, + "node_modules/goober": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", + "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", "peerDependencies": { - "@babel/core": "^7.0.0-0" + "csstype": "^3.0.10" } }, - "node_modules/@babel/plugin-transform-spread": { - "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==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "function-bind": "^1.1.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4.0" } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-transform-template-literals": { - "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==", + "node_modules/html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" }, - "engines": { - "node": ">=6.9.0" + "bin": { + "import-local-fixture": "fixtures/cli.js" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10.13.0" } }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", - "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "has": "^1.0.3" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "isobject": "^3.0.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.10.0" } }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "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==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.10.0" } }, - "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==", + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">= 10.13.0" } }, - "node_modules/@babel/preset-env": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.5.tgz", - "integrity": "sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==", - "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", - "@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.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", - "@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-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.5", - "@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.5", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.5", - "@babel/plugin-transform-classes": "^7.22.5", - "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.5", - "@babel/plugin-transform-dotall-regex": "^7.22.5", - "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.5", - "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.5", - "@babel/plugin-transform-for-of": "^7.22.5", - "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.5", - "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", - "@babel/plugin-transform-member-expression-literals": "^7.22.5", - "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-modules-systemjs": "^7.22.5", - "@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.5", - "@babel/plugin-transform-numeric-separator": "^7.22.5", - "@babel/plugin-transform-object-rest-spread": "^7.22.5", - "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5", - "@babel/plugin-transform-parameters": "^7.22.5", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.5", - "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.5", - "@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.5", - "@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.5", - "@babel/types": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.3", - "babel-plugin-polyfill-corejs3": "^0.8.1", - "babel-plugin-polyfill-regenerator": "^0.5.0", - "core-js-compat": "^3.30.2", - "semver": "^6.3.0" - }, + "node_modules/jest-worker/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": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "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==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dependencies": { - "@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" + "has-flag": "^4.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@babel/preset-react": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", - "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-transform-react-display-name": "^7.22.5", - "@babel/plugin-transform-react-jsx": "^7.22.5", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.22.5" + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@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==" + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, - "node_modules/@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", - "dependencies": { - "regenerator-runtime": "^0.13.11" + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "peer": true, + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": ">=6.9.0" + "node": ">=6" } }, - "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", - "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" - }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" } }, - "node_modules/@babel/traverse": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", - "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", - "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@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.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, + "node_modules/loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", "engines": { - "node": ">=6.9.0" + "node": ">=6.11.5" } }, - "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "to-fast-properties": "^2.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", - "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", "engines": { - "node": ">=10.0.0" + "node": ">= 0.6" } }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "node_modules/mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "dependencies": { - "@emotion/memoize": "^0.8.0" + "mime-db": "1.48.0" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, - "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "p-try": "^2.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { - "node": ">=6.0.0" + "node": ">=6" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" } }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "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==" + "node_modules/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==" }, - "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==", + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/eslint": { - "version": "8.4.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", - "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" + "safe-buffer": "^5.1.0" } }, - "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" - }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" - }, - "node_modules/@types/node": { - "version": "20.2.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", - "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/@types/react": { - "version": "18.2.9", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.9.tgz", - "integrity": "sha512-pL3JAesUkF7PEQGxh5XOwdXGV907te6m1/Qe1ERJLgomojS6Ne790QiA7GUl434JEkFA2aAaB6qJ5z4e1zJn/w==", + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/react-dom": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz", - "integrity": "sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dependencies": { - "@types/react": "*" + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" - }, - "node_modules/@types/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", - "dependencies": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "csstype": "^3.0.2" + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" } }, - "node_modules/@types/wicg-file-system-access": { - "version": "2020.9.6", - "resolved": "https://registry.npmjs.org/@types/wicg-file-system-access/-/wicg-file-system-access-2020.9.6.tgz", - "integrity": "sha512-6hogE75Hl2Ov/jgp8ZhDaGmIF/q3J07GtXf8nCJCwKTHq7971po5+DId7grft09zG7plBwpF6ZU0yx9Du4/e1A==" + "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/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "node_modules/schema-utils": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz", + "integrity": "sha512-Jw+GZVbP5IggB2WAn6UHI02LBwGmsIeYN/lNbSMZyDziQ7jmtAUrqKqDja+W89YHVs+KL/3IkIMltAklqB1vAw==", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" + "randombytes": "^2.1.0" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + "node_modules/seroval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.1.1.tgz", + "integrity": "sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==", + "engines": { + "node": ">=10" + } }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "node_modules/seroval-plugins": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.1.1.tgz", + "integrity": "sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "seroval": "^1.0" } }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dependencies": { - "@xtuc/ieee754": "^1.2.0" + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dependencies": { - "@xtuc/long": "4.2.2" + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "node_modules/solid-js": { + "version": "1.8.22", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.22.tgz", + "integrity": "sha512-VBzN5j+9Y4rqIKEnK301aBk+S7fvFSTs9ljg+YEdFxjNjH0hkjXPiQRcws9tE5fUzMznSS6KToL5hwMfHDgpLA==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "csstype": "^3.1.0", + "seroval": "^1.1.0", + "seroval-plugins": "^1.1.0" } }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "node_modules/solid-styled-components": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/solid-styled-components/-/solid-styled-components-0.28.5.tgz", + "integrity": "sha512-vwTcdp76wZNnESIzB6rRZ3U55NgcSAQXCiiRIiEFhxTFqT0bEh/warNT1qaRZu4OkAzrBkViOngF35ktI8sc4A==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "csstype": "^3.1.0", + "goober": "^2.1.10" + }, + "peerDependencies": { + "solid-js": "^1.4.4" } }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "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==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "node_modules/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==", "engines": { - "node": ">=14.15.0" + "node": ">= 0.4" }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "engines": { - "node": ">=14.15.0" + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, "engines": { - "node": ">=14.15.0" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "^5.1.0" }, "peerDependenciesMeta": { - "webpack-dev-server": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { "optional": true } } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dependencies": { "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { @@ -2134,131 +1942,102 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "peerDependencies": { - "ajv": "^8.8.2" + "ajv": "^6.9.1" } }, - "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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, - "node_modules/babel-loader": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", - "integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==", + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dependencies": { - "find-cache-dir": "^3.3.2", - "schema-utils": "^4.0.0" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 10.13.0" }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz", - "integrity": "sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw==", - "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.4.0", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "engines": { + "node": ">=4" } }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz", - "integrity": "sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.0", - "core-js-compat": "^3.30.1" + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz", - "integrity": "sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.0" + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-styled-components": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", - "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11", - "picomatch": "^2.3.0" + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" }, - "peerDependencies": { - "styled-components": ">= 2" + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=8" + "node": ">=14.17" } }, - "node_modules/browserslist": { - "version": "4.21.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.7.tgz", - "integrity": "sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==", + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "funding": [ { "type": "opencollective", @@ -2274,2807 +2053,599 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001489", - "electron-to-chromium": "^1.4.411", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { - "browserslist": "cli.js" + "update-browserslist-db": "cli.js" }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/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==" + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } }, - "node_modules/camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, - "node_modules/caniuse-lite": { - "version": "1.0.30001497", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001497.tgz", - "integrity": "sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] + "node_modules/validate-html-nesting": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", + "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==" }, - "node_modules/chalk": { + "node_modules/watchpack": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "node_modules/webpack": { + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "dependencies": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, "engines": { - "node": ">=6.0" + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=6" + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } } }, - "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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "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==" - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" - }, - "node_modules/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==" - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/core-js": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz", - "integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz", - "integrity": "sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==", - "dependencies": { - "browserslist": "^4.21.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/csstype": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.427", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.427.tgz", - "integrity": "sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==" - }, - "node_modules/enhanced-resolve": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", - "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", - "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" - }, - "node_modules/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==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "engines": { - "node": ">= 0.4.0" + "node": ">=14" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==" - }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/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==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", - "dependencies": { - "mime-db": "1.48.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/node-releases": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", - "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==" - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/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==" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "peer": true - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "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/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz", - "integrity": "sha512-Jw+GZVbP5IggB2WAn6UHI02LBwGmsIeYN/lNbSMZyDziQ7jmtAUrqKqDja+W89YHVs+KL/3IkIMltAklqB1vAw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", - "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", - "dependencies": { - "abab": "^2.0.6", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.72.1" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/styled-components": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", - "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^1.1.0", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/styled-components" - }, - "peerDependencies": { - "react": ">= 16.8.0", - "react-dom": ">= 16.8.0", - "react-is": ">= 16.8.0" - } - }, - "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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", - "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/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==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-loader": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.3.tgz", - "integrity": "sha512-n3hBnm6ozJYzwiwt5YRiJZkzktftRpMiBApHaJPoWLA+qetQBAXkHqCLM6nwSdRDimqVtA5ocIkcTRLMTt7yzA==", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/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/ts-loader/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "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/ts-loader/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/ts-loader/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/ts-loader/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/ts-loader/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-loader/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/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/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==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/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==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack": { - "version": "5.86.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", - "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", - "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", - "requires": { - "@babel/highlight": "^7.22.5" - } - }, - "@babel/compat-data": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", - "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==" - }, - "@babel/core": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", - "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helpers": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - } - }, - "@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", - "requires": { - "@babel/types": "^7.22.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", - "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", - "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", - "requires": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "dependencies": { - "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==", - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz", - "integrity": "sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==", - "requires": { - "@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.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz", - "integrity": "sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.0" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz", - "integrity": "sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg==", - "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" - } - }, - "@babel/helper-environment-visitor": { - "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==" - }, - "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", - "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-transforms": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", - "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-optimise-call-expression": { - "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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz", - "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-replace-supers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz", - "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-simple-access": { - "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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "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==" - }, - "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" - }, - "@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==" - }, - "@babel/helper-wrap-function": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz", - "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==", - "requires": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/helpers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", - "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", - "requires": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.5", - "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.5.tgz", - "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", - "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5" - } - }, - "@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==", - "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-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==", - "requires": {} - }, - "@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==", - "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==", - "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==", - "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==", - "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==", - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-import-assertions": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@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==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@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==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@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==", - "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==", - "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==", - "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==", - "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==", - "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==", - "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==", - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@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==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-async-generator-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz", - "integrity": "sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-transform-async-to-generator": { - "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==", - "requires": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", - "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@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==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-class-static-block": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz", - "integrity": "sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@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.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.5" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", - "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-dotall-regex": { - "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==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-dynamic-import": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "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==", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-export-namespace-from": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-function-name": { - "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==", - "requires": { - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-json-strings": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-transform-literals": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "node_modules/webpack-merge": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", + "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "@babel/plugin-transform-member-expression-literals": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" } }, - "@babel/plugin-transform-modules-amd": { - "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==", - "requires": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", - "requires": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" } }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", - "requires": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5" - } + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, - "@babel/plugin-transform-modules-umd": { - "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==", - "requires": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", + "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "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==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "@babel/plugin-transform-new-target": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } + "node_modules/wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, - "@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" } }, - "@babel/plugin-transform-numeric-separator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } - }, - "@babel/plugin-transform-object-rest-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "peer": true, "requires": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.5" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "@babel/plugin-transform-object-super": { - "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==", + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" } }, - "@babel/plugin-transform-optional-catch-binding": { + "@babel/compat-data": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", + "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", + "peer": true }, - "@babel/plugin-transform-optional-chaining": { + "@babel/core": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz", - "integrity": "sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ==", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", + "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", + "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" } }, - "@babel/plugin-transform-parameters": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "@babel/generator": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + } } }, - "@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==", + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/types": "^7.24.7" } }, - "@babel/plugin-transform-private-property-in-object": { + "@babel/helper-compilation-targets": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", + "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", + "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/compat-data": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "dependencies": { + "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==", + "peer": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true + } } }, - "@babel/plugin-transform-property-literals": { - "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==", + "@babel/helper-create-class-features-plugin": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" } }, - "@babel/plugin-transform-react-display-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", - "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", + "@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" } }, - "@babel/plugin-transform-react-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", - "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", + "@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "@babel/helper-module-transforms": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "requires": { - "@babel/plugin-transform-react-jsx": "^7.22.5" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" } }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", - "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", + "@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/types": "^7.24.7" } }, - "@babel/plugin-transform-regenerator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", - "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.1" - } + "@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==" }, - "@babel/plugin-transform-reserved-words": { - "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==", + "@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" } }, - "@babel/plugin-transform-shorthand-properties": { - "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==", + "@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, - "@babel/plugin-transform-spread": { - "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==", + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, - "@babel/plugin-transform-sticky-regex": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } + "@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==" }, - "@babel/plugin-transform-template-literals": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" }, - "@babel/plugin-transform-typeof-symbol": { - "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==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } + "@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==" }, - "@babel/plugin-transform-unicode-escapes": { + "@babel/helpers": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", - "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", + "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", + "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" } }, - "@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==", + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" } }, - "@babel/plugin-transform-unicode-regex": { - "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==", + "@babel/parser": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/types": "^7.25.6" } }, - "@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==", + "@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.7" } }, - "@babel/preset-env": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.5.tgz", - "integrity": "sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==", + "@babel/plugin-syntax-typescript": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "requires": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", - "@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.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", - "@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-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.5", - "@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.5", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.5", - "@babel/plugin-transform-classes": "^7.22.5", - "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.5", - "@babel/plugin-transform-dotall-regex": "^7.22.5", - "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.5", - "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.5", - "@babel/plugin-transform-for-of": "^7.22.5", - "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.5", - "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", - "@babel/plugin-transform-member-expression-literals": "^7.22.5", - "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-modules-systemjs": "^7.22.5", - "@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.5", - "@babel/plugin-transform-numeric-separator": "^7.22.5", - "@babel/plugin-transform-object-rest-spread": "^7.22.5", - "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5", - "@babel/plugin-transform-parameters": "^7.22.5", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.5", - "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.5", - "@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.5", - "@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.5", - "@babel/types": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.3", - "babel-plugin-polyfill-corejs3": "^0.8.1", - "babel-plugin-polyfill-regenerator": "^0.5.0", - "core-js-compat": "^3.30.2", - "semver": "^6.3.0" + "@babel/helper-plugin-utils": "^7.24.8" } }, - "@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==", + "@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", "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/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" } }, - "@babel/preset-react": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", - "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", + "@babel/plugin-transform-typescript": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", + "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-transform-react-display-name": "^7.22.5", - "@babel/plugin-transform-react-jsx": "^7.22.5", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.22.5" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" } }, - "@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==" - }, - "@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", "requires": { - "regenerator-runtime": "^0.13.11" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" } }, "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" } }, "@babel/traverse": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", - "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", - "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@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.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5", - "debug": "^4.1.0", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" } }, - "@discoveryjs/json-ext": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", - "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==" - }, - "@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "requires": { - "@emotion/memoize": "^0.8.0" + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } } }, - "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" - }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "@discoveryjs/json-ext": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", + "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==" }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "peer": true, "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -5086,27 +2657,27 @@ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" }, "@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } } } @@ -5117,45 +2688,38 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@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.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@types/eslint": { - "version": "8.4.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", - "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" }, - "@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "@types/json-schema": { "version": "7.0.11", @@ -5167,53 +2731,10 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" }, - "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" - }, - "@types/react": { - "version": "18.2.9", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.9.tgz", - "integrity": "sha512-pL3JAesUkF7PEQGxh5XOwdXGV907te6m1/Qe1ERJLgomojS6Ne790QiA7GUl434JEkFA2aAaB6qJ5z4e1zJn/w==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-dom": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz", - "integrity": "sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==", - "requires": { - "@types/react": "*" - } - }, - "@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" - }, - "@types/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", - "requires": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "csstype": "^3.0.2" - } - }, - "@types/wicg-file-system-access": { - "version": "2020.9.6", - "resolved": "https://registry.npmjs.org/@types/wicg-file-system-access/-/wicg-file-system-access-2020.9.6.tgz", - "integrity": "sha512-6hogE75Hl2Ov/jgp8ZhDaGmIF/q3J07GtXf8nCJCwKTHq7971po5+DId7grft09zG7plBwpF6ZU0yx9Du4/e1A==" - }, "@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "requires": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -5230,9 +2751,9 @@ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" }, "@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" }, "@webassemblyjs/helper-numbers": { "version": "1.11.6", @@ -5250,14 +2771,14 @@ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/wasm-gen": "1.12.1" } }, "@webassemblyjs/ieee754": { @@ -5282,26 +2803,26 @@ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" }, "@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "requires": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", @@ -5309,22 +2830,22 @@ } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "requires": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", @@ -5333,11 +2854,11 @@ } }, "@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "requires": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -5369,22 +2890,25 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" - }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" - }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" + }, + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "requires": {} }, + "acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "requires": { + "acorn": "^8.11.0" + } + }, "ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -5420,76 +2944,59 @@ "color-convert": "^1.9.0" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "babel-loader": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", - "integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", "requires": { - "find-cache-dir": "^3.3.2", + "find-cache-dir": "^4.0.0", "schema-utils": "^4.0.0" } }, - "babel-plugin-polyfill-corejs2": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz", - "integrity": "sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw==", - "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.4.0", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz", - "integrity": "sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.4.0", - "core-js-compat": "^3.30.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz", - "integrity": "sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g==", + "babel-plugin-jsx-dom-expressions": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.38.5.tgz", + "integrity": "sha512-JfjHYKOKGwoiOYQ56Oo8gbZPb9wNMpPuEEUhSCjMpnuHM9K21HFIUBm83TZPB40Av4caCIW4Tfjzpkp/MtFpMw==", "requires": { - "@babel/helper-define-polyfill-provider": "^0.4.0" - } - }, - "babel-plugin-styled-components": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", - "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11", - "picomatch": "^2.3.0" + "@babel/helper-module-imports": "7.18.6", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.20.7", + "html-entities": "2.3.3", + "validate-html-nesting": "^1.2.1" + }, + "dependencies": { + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + } + } } }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "babel-preset-solid": { + "version": "1.8.22", + "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.8.22.tgz", + "integrity": "sha512-nKwisb//lZsiRF2NErlRP64zVTJqa1OSZiDnSl0YbcTiCZoMt52CY2Pg+9fsYAPtjYMT7RHBmzU41pxK6hFOcg==", "requires": { - "fill-range": "^7.0.1" + "babel-plugin-jsx-dom-expressions": "^0.38.5" } }, "browserslist": { - "version": "4.21.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.7.tgz", - "integrity": "sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "requires": { - "caniuse-lite": "^1.0.30001489", - "electron-to-chromium": "^1.4.411", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" } }, "buffer-from": { @@ -5497,15 +3004,10 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, "caniuse-lite": { - "version": "1.0.30001497", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001497.tgz", - "integrity": "sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw==" + "version": "1.0.30001655", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", + "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==" }, "chalk": { "version": "2.4.2", @@ -5555,31 +3057,24 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "peer": true, "requires": { "safe-buffer": "~5.1.1" } }, - "core-js": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz", - "integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==" - }, - "core-js-compat": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz", - "integrity": "sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==", - "requires": { - "browserslist": "^4.21.5" - } + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "cross-spawn": { "version": "7.0.3", @@ -5591,25 +3086,10 @@ "which": "^2.0.1" } }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" - }, - "css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, "csstype": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "debug": { "version": "4.3.1", @@ -5619,15 +3099,20 @@ "ms": "2.1.2" } }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, "electron-to-chromium": { - "version": "1.4.427", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.427.tgz", - "integrity": "sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==" + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" }, "enhanced-resolve": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", - "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -5644,9 +3129,9 @@ "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==" }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" }, "escape-string-regexp": { "version": "1.0.5", @@ -5682,11 +3167,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -5707,22 +3187,61 @@ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" }, - "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==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "dependencies": { + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "requires": { + "p-locate": "^6.0.0" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "requires": { + "p-limit": "^4.0.0" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==" + }, + "pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "requires": { + "find-up": "^6.3.0" + } + } } }, "find-up": { @@ -5735,14 +3254,15 @@ } }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "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==" + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "peer": true }, "glob-to-regexp": { "version": "0.4.1", @@ -5754,10 +3274,16 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, + "goober": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", + "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", + "requires": {} + }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "has": { "version": "1.0.3", @@ -5772,33 +3298,15 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } + "html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, "immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==" + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" }, "import-local": { "version": "3.0.2", @@ -5822,11 +3330,6 @@ "has": "^1.0.3" } }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -5893,7 +3396,8 @@ "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "peer": true }, "kind-of": { "version": "6.0.3", @@ -5913,54 +3417,16 @@ "p-locate": "^4.1.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "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==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - } + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, "mime-db": { "version": "1.48.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", @@ -5985,9 +3451,9 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node-releases": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", - "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, "p-limit": { "version": "2.3.0", @@ -6010,11 +3476,6 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, - "pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6031,14 +3492,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "pkg-dir": { "version": "4.2.0", @@ -6048,11 +3504,6 @@ "find-up": "^4.0.0" } }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -6066,29 +3517,6 @@ "safe-buffer": "^5.1.0" } }, - "react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "peer": true - }, "rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", @@ -6097,60 +3525,6 @@ "resolve": "^1.20.0" } }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "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==", - "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==" - }, - "regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "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==", - "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==", - "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==" - } - } - }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -6184,19 +3558,6 @@ "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==" - }, - "scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "requires": { - "loose-envify": "^1.1.0" - } - }, "schema-utils": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz", @@ -6209,18 +3570,29 @@ } }, "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==" }, "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "requires": { "randombytes": "^2.1.0" } }, + "seroval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.1.1.tgz", + "integrity": "sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==" + }, + "seroval-plugins": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.1.1.tgz", + "integrity": "sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==", + "requires": {} + }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -6229,11 +3601,6 @@ "kind-of": "^6.0.2" } }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6247,26 +3614,30 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, + "solid-js": { + "version": "1.8.22", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.22.tgz", + "integrity": "sha512-VBzN5j+9Y4rqIKEnK301aBk+S7fvFSTs9ljg+YEdFxjNjH0hkjXPiQRcws9tE5fUzMznSS6KToL5hwMfHDgpLA==", + "requires": { + "csstype": "^3.1.0", + "seroval": "^1.1.0", + "seroval-plugins": "^1.1.0" + } + }, + "solid-styled-components": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/solid-styled-components/-/solid-styled-components-0.28.5.tgz", + "integrity": "sha512-vwTcdp76wZNnESIzB6rRZ3U55NgcSAQXCiiRIiEFhxTFqT0bEh/warNT1qaRZu4OkAzrBkViOngF35ktI8sc4A==", + "requires": { + "csstype": "^3.1.0", + "goober": "^2.1.10" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" - }, - "source-map-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", - "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", - "requires": { - "abab": "^2.0.6", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.2" - } - }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -6276,23 +3647,6 @@ "source-map": "^0.6.0" } }, - "styled-components": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", - "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^1.1.0", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6312,9 +3666,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "terser": { - "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "requires": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -6323,15 +3677,15 @@ } }, "terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "requires": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "terser": "^5.26.0" }, "dependencies": { "ajv": { @@ -6357,9 +3711,9 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "schema-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", - "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "requires": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -6373,114 +3727,38 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-loader": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.3.tgz", - "integrity": "sha512-n3hBnm6ozJYzwiwt5YRiJZkzktftRpMiBApHaJPoWLA+qetQBAXkHqCLM6nwSdRDimqVtA5ocIkcTRLMTt7yzA==", - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": { - "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" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.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==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.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" - } - } + "ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" } }, "typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==" - }, - "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==" - }, - "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==", - "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==" - }, - "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==" + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==" }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" } }, "uri-js": { @@ -6491,43 +3769,52 @@ "punycode": "^2.1.0" } }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "validate-html-nesting": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", + "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==" + }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "webpack": { - "version": "5.86.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", - "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "requires": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.1", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { @@ -6619,10 +3906,15 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, + "yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==" } } } diff --git a/package.json b/package.json index 074a16f..8d2e542 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "theorytracker", + "name": "theorytracker2", "version": "0.1.0", "description": "", "author": "hlorenzi", @@ -7,38 +7,24 @@ "main": "index.js", "type": "module", "scripts": { + "start": "ts-node index.ts", "build": "webpack --config webpack.config.cjs", + "build-profile": "webpack --config webpack.config.cjs --profile --json > webpack.stats.json && npx webpack-bundle-analyzer webpack.stats.json ./.build/", "dev": "webpack --config webpack.config.cjs --watch --mode development", - "start": "http-server -p 80", - "test": "node ./build/test.js" + "serve": "http-server -p 80", + "test": "echo \"Error: no test specified\" && exit 1" }, - "browserslist": [ - "> 2%", - "not dead", - "not ie 11" - ], + "browserslist": "> 2%, not dead", "dependencies": { - "@babel/core": "^7.22.5", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/preset-env": "^7.22.5", - "@babel/preset-react": "^7.22.5", - "@types/node": "^20.2.5", - "@types/react": "^18.2.9", - "@types/react-dom": "^18.2.4", - "@types/styled-components": "^5.1.26", - "@types/wicg-file-system-access": "^2020.9.6", - "babel-loader": "^9.1.2", - "core-js": "^3.30.2", - "immutable": "^4.3.0", - "pako": "^2.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "regenerator-runtime": "^0.13.11", - "source-map-loader": "^4.0.1", - "styled-components": "^5.3.11", - "ts-loader": "^9.4.3", - "typescript": "^5.1.3", - "webpack": "^5.86.0", + "@babel/preset-typescript": "^7.24.6", + "babel-loader": "^9.1.3", + "babel-preset-solid": "^1.8.17", + "immutable": "^4.3.7", + "solid-js": "^1.8.17", + "solid-styled-components": "^0.28.5", + "ts-node": "^10.9.2", + "typescript": "^5.4.5", + "webpack": "^5.91.0", "webpack-cli": "^5.1.4" } } diff --git a/run_local_server.bat b/run_local_server.bat deleted file mode 100644 index ebb7225..0000000 --- a/run_local_server.bat +++ /dev/null @@ -1,5 +0,0 @@ -where /q http-server - -IF ERRORLEVEL 1 (npm i -g http-server) - -http-server -p 80 \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index d5a96c4..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import React from "react" -import * as Dockable from "./dockable" -import * as Command from "./command" -import * as Project from "./project" -import * as Playback from "./playback" -import * as Prefs from "./prefs" -import * as Popup from "./popup" -import * as Menubar from "./menubar" -import * as UI from "./ui" -import { useRefState } from "./util/refState" -import PlaybackToolbar from "./PlaybackToolbar" -import MenuFile from "./MenuFile" -import MenuEdit from "./MenuEdit" -import MenuWindow from "./MenuWindow" -import "./types" - - -let initializedGlobals = false - - -export default function App() -{ - if (!initializedGlobals) - { - initializedGlobals = true - Prefs.initGlobal() - Project.initGlobal() - Playback.initGlobal() - Dockable.initGlobal() - Popup.initGlobal() - } - - Project.useGlobal() - Playback.useGlobal() - Dockable.useGlobal() - Popup.useGlobal() - - const [version, setVersion] = React.useState("") - - React.useEffect(() => - { - ;(async () => - { - const versionFile = await fetch("build/build_version.txt") - const versionTxt = await versionFile.text() - if (versionTxt.startsWith("v0-")) - setVersion("v0." + versionTxt.match(".*?\-(.*?)\-")![1]) - })() - - }, []) - - - React.useEffect(() => - { - window.addEventListener("keydown", (ev: KeyboardEvent) => - { - if (document.activeElement && document.activeElement.tagName == "INPUT") - return - - const key = ev.key.toLowerCase() - - for (const command of Command.allCommands) - { - if (!command.shortcut) - continue - - if (command.isShortcutAvailable && !command.isShortcutAvailable()) - continue - - if (command.isAvailable && !command.isAvailable({})) - continue - - for (const shortcut of command.shortcut) - { - if (!!shortcut.ctrl !== ev.ctrlKey) - continue - - if (!!shortcut.shift !== ev.shiftKey) - continue - - if (key !== shortcut.key) - continue - - //console.log("handled keyboard command: ", command.name) - command.func({}) - ev.preventDefault() - ev.stopPropagation() - return - } - } - }) - - }, []) - - - return <> -
- - - - - - - - How to use the app - - - { version } - - - - { !Playback.global.synthLoading ? null : - - } - - - -
- - { !Popup.global.elem ? null : - - } - -} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..798f709 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,34 @@ +import * as Solid from "solid-js" +import * as SolidWeb from "solid-js/web" +import { styled } from "solid-styled-components" +import * as State from "./state.ts" +import * as Timeline from "./timeline" + + +function App() +{ + return +
+ Hello, world! { State.get().test }
+ +
+ +
+} + + +const AppRoot = styled.div` + display: grid; + grid-template: auto 1fr / 1fr; + margin: auto; + width: 100%; + height: 100%; + min-height: 0; +` + + +SolidWeb.render( + App, + document.getElementById("app")!) \ No newline at end of file diff --git a/src/playback/instrumentSflib.ts b/src/playback/instrumentSflib.ts deleted file mode 100644 index 758f64a..0000000 --- a/src/playback/instrumentSflib.ts +++ /dev/null @@ -1,256 +0,0 @@ -import * as Playback from "./index" -import * as Project from "../project" -import * as MathUtils from "../util/mathUtils" - - -const notesToDelete = new Set() - - -interface Note -{ - request: Playback.NoteRequest - zone: Playback.SflibInstrumentZone - timePassedMs: number - endTimeMs: number - nodeSrc: AudioBufferSourceNode - nodeEnvelope: GainNode - nodeVolume: GainNode -} - - -export class InstrumentSflib extends Playback.Instrument -{ - collectionId: string - instrumentId: string - sflibInstrument: Playback.SflibInstrument | null - notes: Note[] - - - constructor( - synth: Playback.SynthManager, - outputNode: AudioNode, - collectionId: string, - instrumentId: string) - { - super(synth, outputNode) - this.collectionId = collectionId - this.instrumentId = instrumentId - this.sflibInstrument = null - this.notes = [] - } - - - async prepare() - { - this.sflibInstrument = await Playback.sflibGetInstrument( - this.collectionId, this.instrumentId, this.synth.audioCtx) - - if (!this.sflibInstrument) - { - console.error("could not load sflib " + this.collectionId + "/" + this.instrumentId) - return - } - } - - - async destroy() - { - - } - - - isFinished() - { - return !this.sflibInstrument || this.notes.length == 0 - } - - - playNote(request: Playback.NoteRequest) - { - if (!this.sflibInstrument) - return - - //if (this.notes.has(request.noteId)) - // return - - const midiPitch = request.midiPitchSeq[0].value - - let zone = this.sflibInstrument.zones.find(z => - midiPitch >= z.midiPitchMin && - midiPitch <= z.midiPitchMax) - - if (!zone) - { - let nearestMidiPitchDistance = Infinity - - for (const z of this.sflibInstrument.zones) - { - const distance = Math.min( - Math.abs(z.midiPitchMin - midiPitch), - Math.abs(z.midiPitchMax - midiPitch)) - - if (distance < nearestMidiPitchDistance) - { - nearestMidiPitchDistance = distance - zone = z - } - } - } - - if (!zone) - return - - const freq = MathUtils.midiToHertz(midiPitch) - - const audioBuffer = this.sflibInstrument.audioBuffers[zone.sampleIndex] - - - const sourceNode = this.synth.audioCtx.createBufferSource() - sourceNode.playbackRate.value = freq / MathUtils.midiToHertz(zone.midiPitchBase) - sourceNode.buffer = audioBuffer - sourceNode.loop = (zone.loopMode == "loop") - sourceNode.loopStart = zone.loopStartIndex / audioBuffer.sampleRate - sourceNode.loopEnd = zone.loopEndIndex / audioBuffer.sampleRate - - - const time = 0.05 + Math.max(0, request.startMs / 1000) - const delayTime = time + zone.volEnvDelaySec - const attackTime = delayTime + (zone.volEnvAttackSec || 0.005) - const holdTime = attackTime + zone.volEnvHoldSec - const decayTime = holdTime + zone.volEnvDecaySec - const sustainLevel = zone.volEnvSustain || 0.0001 - const releaseTime = time + request.durationMs / 1000 - const endTime = releaseTime + Math.max(zone.volEnvReleaseSec, 0.05) - - /* - - Envelope parameters: - - | 100% level - | ______ - | /| |\ - | / | | \ sustainLevel - | / | | \____________ - | / | | | |\ - | / | | | | \ - | / | | | | \ - --+------------------------------------------- - ^ ^ ^ ^ ^ ^ ^ endTime - | | | | | + releaseTime - | | | | + decayTime - | | | + holdTime - | | + attackTime - | + delayTime - + time - - */ - - const releaseTimeCap = releaseTime - 0.001 - const cappedDelayTime = Math.min(delayTime, releaseTimeCap) - const cappedAttackTime = Math.min(attackTime, releaseTimeCap) - const cappedHoldTime = Math.min(holdTime, releaseTimeCap) - - const releaseF = (releaseTime - cappedHoldTime) / (decayTime - cappedHoldTime) - const releaseLevel = releaseF >= 1 ? sustainLevel : Math.pow(sustainLevel, releaseF) - - const envelopeNode = this.synth.audioCtx.createGain() - envelopeNode.gain.value = 0 - envelopeNode.gain.setValueAtTime(0.0001, cappedDelayTime) - envelopeNode.gain.exponentialRampToValueAtTime(1, cappedAttackTime) - envelopeNode.gain.setValueAtTime(1, cappedHoldTime) - - if (decayTime < releaseTime) - { - envelopeNode.gain.exponentialRampToValueAtTime(sustainLevel, decayTime) - envelopeNode.gain.setValueAtTime(sustainLevel, releaseTime) - envelopeNode.gain.exponentialRampToValueAtTime(0.0001, endTime) - } - else - { - envelopeNode.gain.exponentialRampToValueAtTime(releaseLevel, releaseTime) - envelopeNode.gain.setValueAtTime(releaseLevel, releaseTime) - envelopeNode.gain.exponentialRampToValueAtTime(0.0001, endTime) - } - - /*console.log("playNote", this.synth.audioCtx.currentTime, request) - console.log("envelope", - "del", (delayTime - time).toFixed(3), - "atk", (attackTime - time).toFixed(3), - "hld", (holdTime - time).toFixed(3), - "dec", (decayTime - time).toFixed(3), - "::", - sustainLevel.toFixed(3), - releaseLevel.toFixed(3), - "::", - "rel", (releaseTimeCap - time).toFixed(3), - "end", (endTime - time).toFixed(3))*/ - - const volumeNode = this.synth.audioCtx.createGain() - volumeNode.gain.value = MathUtils.dbToLinearGain(request.volumeSeq[0].value) - - - sourceNode.connect(envelopeNode) - envelopeNode.connect(volumeNode) - volumeNode.connect(this.outputNode) - - sourceNode.start(time) - - const note: Note = - { - request, - zone, - timePassedMs: -(time - this.synth.audioCtx.currentTime) * 1000, - endTimeMs: (endTime - time) * 1000, - nodeSrc: sourceNode, - nodeEnvelope: envelopeNode, - nodeVolume: volumeNode, - } - - this.notes.push(note) - } - - - stopNote(note: Note) - { - note.nodeSrc.stop() - note.nodeSrc.disconnect() - } - - - stopAll() - { - for (const note of this.notes) - this.stopNote(note) - - this.notes = [] - } - - - process(deltaTimeMs: number) - { - notesToDelete.clear() - - for (const note of this.notes) - { - note.timePassedMs += deltaTimeMs - - if (note.timePassedMs > note.endTimeMs) - { - this.stopNote(note) - notesToDelete.add(note) - } - else if (note.zone.loopMode != "loop") - { - const sample = this.sflibInstrument!.audioBuffers[note.zone.sampleIndex] - if (note.timePassedMs > sample.length / sample.sampleRate * 1000) - { - this.stopNote(note) - notesToDelete.add(note) - } - } - } - - this.notes = this.notes.filter(n => !notesToDelete.has(n)) - notesToDelete.clear() - } -} \ No newline at end of file diff --git a/src/prefs.ts b/src/prefs.ts new file mode 100644 index 0000000..520ce3b --- /dev/null +++ b/src/prefs.ts @@ -0,0 +1,97 @@ +export interface Prefs +{ + timeline: + { + bkgColor: string + bkgAlternateMeasureColor: string + bkgInactiveOverlayColor: string + trackVBorderColor: string + trackHBorderColor: string + + selectionCursorColor: string + selectionBkgColor: string + playbackCursorColor: string + trackSeparatorColor: string + + measureColor: string + submeasureColor: string + halfSubmeasureColor: string + + measureLabelColor: string + octaveLabelColor: string + + meterChangeColor: string + keyChangeColor: string + noteVelocityMarkerColor: string + noteVelocityMarkerInactiveColor: string + + keyPan: string + keyPencil: string + keySelectMultiple: string + keySelectRange: string + keySelectRect: string + keySelectClone: string + keyDisplaceCursor2: string + keyDisplaceFast: string + keyDisplaceChromatically: string + keyDisplaceStretch: string + + mouseDoubleClickThresholdMs: number + + mouseDragXLockedDistance: number + mouseDragYLockedDistance: number + + mouseEdgeScrollThreshold: number + mouseEdgeScrollSpeed: number + } +} + + +export function makeNew(): Prefs +{ + return { + timeline: { + bkgColor: "#202225", + bkgAlternateMeasureColor: "#1a1c1f", + bkgInactiveOverlayColor: "#0008", + trackVBorderColor: "#888", + trackHBorderColor: "#888", + + selectionCursorColor: "#0af", + selectionBkgColor: "#8cf8", + playbackCursorColor: "#f00", + trackSeparatorColor: "#aaa", + + measureColor: "#040404", + submeasureColor: "#080808", + halfSubmeasureColor: "#181818", + + measureLabelColor: "#aaa", + octaveLabelColor: "#aaa", + + meterChangeColor: "#0cf", + keyChangeColor: "#f0c", + noteVelocityMarkerColor: "#0c4", + noteVelocityMarkerInactiveColor: "#063", + + keyPan: " ", + keyPencil: "a", + keySelectMultiple: "control", + keySelectRange: "shift", + keySelectRect: "shift", + keySelectClone: "alt", + keyDisplaceCursor2: "shift", + keyDisplaceFast: "control", + keyDisplaceChromatically: "shift", + keyDisplaceStretch: "shift", + + mouseDoubleClickThresholdMs: 300, + + mouseDragXLockedDistance: 10, + mouseDragYLockedDistance: 10, + + mouseEdgeScrollThreshold: 10, + mouseEdgeScrollSpeed: 1, + } + } +} \ No newline at end of file diff --git a/src/project/elem.ts b/src/project/elem.ts index 0d46ffb..273a544 100644 --- a/src/project/elem.ts +++ b/src/project/elem.ts @@ -1,12 +1,11 @@ -import Range from "../util/range" import * as Theory from "../theory" -import * as Playback from "../playback" -import Rational from "../util/rational" -import * as Misc from "../util/misc" +import Range from "../utils/range.ts" +import Rational from "../utils/rational.ts" export type ID = number + export const MinVolumeDb = -30 export const MaxVolumeDb = 0 export const DefaultVolumeDb = 0 @@ -21,67 +20,46 @@ export interface ElementBase } -export interface InstrumentBasic -{ - type: "basic" -} - - -export interface InstrumentSflib -{ - type: "sflib" - collectionId: string - instrumentId: string -} - - -export type Instrument = - InstrumentBasic | - InstrumentSflib - - export interface TrackBase extends ElementBase { type: "track" name: string - mute: boolean - solo: boolean } -export interface TrackNotes extends TrackBase +export interface TrackKeyChanges extends TrackBase { - trackType: "notes" - instrument: Instrument - volumeDb: number + trackType: "keyChanges" } -export interface TrackChords extends TrackBase +export interface TrackMeterChanges extends TrackBase { - trackType: "chords" - instrument: Instrument - volumeDb: number + trackType: "meterChanges" } -export interface TrackKeyChanges extends TrackBase +export interface TrackChords extends TrackBase { - trackType: "keyChanges" + trackType: "chords" + mute: boolean + solo: boolean } -export interface TrackMeterChanges extends TrackBase +export interface TrackNotes extends TrackBase { - trackType: "meterChanges" + trackType: "notes" + mute: boolean + solo: boolean } export type Track = - TrackNotes | - TrackChords | TrackKeyChanges | - TrackMeterChanges + TrackMeterChanges | + TrackChords | + TrackNotes export interface KeyChange extends ElementBase @@ -98,18 +76,10 @@ export interface MeterChange extends ElementBase } -export interface NoteBlock extends ElementBase -{ - type: "noteBlock" -} - - export interface Note extends ElementBase { type: "note" midiPitch: number - volumeDb: number - velocity: number } @@ -124,7 +94,6 @@ export type Element = Track | KeyChange | MeterChange | - NoteBlock | Note | Chord @@ -145,10 +114,8 @@ export function makeTrackNotes(): TrackNotes parentId: 0, range: Range.dummy(), name: "", - volumeDb: DefaultVolumeDb, mute: false, solo: false, - instrument: makeInstrument(), } } @@ -162,97 +129,14 @@ export function makeTrackChords(): TrackChords parentId: 0, range: Range.dummy(), name: "Chords", - volumeDb: DefaultChordVolumeDb, mute: false, solo: false, - instrument: makeInstrument(), - } -} - - -export function makeInstrument(): Instrument -{ - return makeInstrumentOfKind("sflib") -} - - -export function makeInstrumentOfKind(kind: string): Instrument -{ - switch (kind) - { - case "basic": - default: - { - return { - type: "basic", - } - } - case "sflib": - { - return { - type: "sflib", - collectionId: "gm", - instrumentId: "piano_1", - } - } - } -} - - -export function instrumentName(instrument: Instrument): string -{ - switch (instrument.type) - { - case "basic": return "Basic" - case "sflib": - { - const sflibMeta = Playback.getSflibMeta() - if (!sflibMeta) - return instrument.collectionId + "/" + instrument.instrumentId - - const coll = sflibMeta.collectionsById.get(instrument.collectionId)! - const instr = coll.instrumentsById.get(instrument.instrumentId)! - const emoji = Misc.getMidiPresetEmoji(instr.midiBank, instr.midiPreset) - - return emoji + " " + coll.id + "/" + instr.name - } - - default: return "???" - } -} - - -export function instrumentEmoji(instrument: Instrument): string -{ - switch (instrument.type) - { - case "basic": return Misc.getMidiPresetEmoji(0, 0) - case "sflib": - { - const sflibMeta = Playback.getSflibMeta() - if (!sflibMeta) - return Misc.getMidiPresetEmoji(0, 0) - - const coll = sflibMeta.collectionsById.get(instrument.collectionId)! - const instr = coll.instrumentsById.get(instrument.instrumentId)! - return Misc.getMidiPresetEmoji(instr.midiBank, instr.midiPreset) - } - - default: return Misc.getMidiPresetEmoji(0, 0) } } export function trackDisplayName(track: Track): string { - if (track.trackType == "notes" || track.trackType == "chords") - { - if (track.name) - return instrumentEmoji(track.instrument) + " " + track.name - - return instrumentName(track.instrument) - } - if (track.name) return track.name @@ -260,21 +144,6 @@ export function trackDisplayName(track: Track): string } -export function trackHasInstrument(track: Track): boolean -{ - return track.trackType == "notes" || track.trackType == "chords" -} - - -export function trackGetInstrument(track: Track): Instrument | null -{ - if (track.trackType == "notes" || track.trackType == "chords") - return track.instrument - else - return null -} - - export function makeTrackKeyChanges(): TrackKeyChanges { return { @@ -284,8 +153,6 @@ export function makeTrackKeyChanges(): TrackKeyChanges parentId: 0, range: Range.dummy(), name: "Key Changes", - mute: false, - solo: false, } } @@ -299,8 +166,6 @@ export function makeTrackMeterChanges(): TrackMeterChanges parentId: 0, range: Range.dummy(), name: "Meter Changes", - mute: false, - solo: false, } } @@ -329,23 +194,10 @@ export function makeKeyChange(parentId: ID, time: Rational, key: Theory.Key): Ke } -export function makeNoteBlock(parentId: ID, range: Range): NoteBlock -{ - return { - type: "noteBlock", - id: -1, - parentId, - range, - } -} - - export function makeNote( parentId: ID, range: Range, - midiPitch: number, - volumeDb: number, - velocity: number) + midiPitch: number) : Note { return { @@ -354,8 +206,6 @@ export function makeNote( parentId, range, midiPitch, - volumeDb, - velocity, } } diff --git a/src/project/index.ts b/src/project/index.ts index 11d0d8f..04c1d40 100644 --- a/src/project/index.ts +++ b/src/project/index.ts @@ -1,8 +1,8 @@ -export * from "./_global" +//export * from "./_global" export * from "./root" export * from "./measures" export * from "./elem" -export * from "./midiImport" -export * from "./midiExport" -export * from "./jsonExport" -export * from "./jsonImport" \ No newline at end of file +//export * from "./midiImport" +//export * from "./midiExport" +//export * from "./jsonExport" +//export * from "./jsonImport" \ No newline at end of file diff --git a/src/project/jsonExport.ts b/src/project/jsonExport.ts index 612d2b4..1ed6d16 100644 --- a/src/project/jsonExport.ts +++ b/src/project/jsonExport.ts @@ -1,8 +1,8 @@ -import * as Project from "./index" +import * as Project from "./index.ts" import * as Theory from "../theory" -import Rational from "../util/rational" -import Range from "../util/range" -import * as MathUtils from "../util/mathUtils" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" +import * as MathUtils from "../utils/mathUtils.ts" export function jsonExport(project: Project.Root): string diff --git a/src/project/jsonImport.ts b/src/project/jsonImport.ts index 878c062..846562d 100644 --- a/src/project/jsonImport.ts +++ b/src/project/jsonImport.ts @@ -1,8 +1,8 @@ -import * as Project from "./index" +import * as Project from "./index.ts" import * as Theory from "../theory" -import Rational from "../util/rational" -import Range from "../util/range" -import * as MathUtils from "../util/mathUtils" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" +import * as MathUtils from "../utils/mathUtils.ts" export function jsonImport(json: any): Project.Root diff --git a/src/project/measures.ts b/src/project/measures.ts index 2767091..6ea7ff8 100644 --- a/src/project/measures.ts +++ b/src/project/measures.ts @@ -1,10 +1,10 @@ -import * as Project from "./index" -import * as Theory from "../theory" import Immutable from "immutable" -import BinarySearch from "../util/binarySearch" -import Rational from "../util/rational" -import ListOfRanges from "../util/listOfRanges" -import Range from "../util/range" +import * as Project from "./index.ts" +import * as Theory from "../theory" +import BinarySearch from "../utils/binarySearch.ts" +import Rational from "../utils/rational.ts" +import ListOfRanges from "../utils/listOfRanges.ts" +import Range from "../utils/range.ts" export interface Measure @@ -23,10 +23,10 @@ let firstMeterCh: Project.MeterChange | null = null let lastMeterCh: Project.MeterChange | null = null -export function ensureMeasureCacheRefreshed(project: Project.Root) +export function ensureMeasureCacheRefreshed(project: Project.ImmutableRoot) { const meterChangeTrackId = Project.meterChangeTrackId(project) - const meterChangeList = Project.global.project.lists.get(meterChangeTrackId)! + const meterChangeList = project.lists.get(meterChangeTrackId)! if (meterChangeList === measureCacheKey) return @@ -75,7 +75,7 @@ export function ensureMeasureCacheRefreshed(project: Project.Root) export function *iterMeasuresAtRange( - project: Project.Root, + project: Project.ImmutableRoot, range: Range) : Generator { @@ -114,7 +114,7 @@ export function *iterMeasuresAtRange( } let lastMeasureNum = -1 - let measureIndex = measureStart || 0 + let measureIndex = measureStart ?? 0 while (true) { if (measureIndex >= measureCache.length) diff --git a/src/project/root.ts b/src/project/root.ts index f2fab0a..ac92a2f 100644 --- a/src/project/root.ts +++ b/src/project/root.ts @@ -1,30 +1,38 @@ -import * as Project from "./index" -import * as Theory from "../theory" import Immutable from "immutable" -import Range from "../util/range" -import Rational from "../util/rational" -import ListOfRanges from "../util/listOfRanges" +import * as Project from "./index.ts" +import * as Theory from "../theory" +import Range from "../utils/range.ts" +import Rational from "../utils/rational.ts" +import ListOfRanges from "../utils/listOfRanges.ts" // Least Common Multiple of 2, 3, 4, 5, 6, 7, 8, 9, and 10. export const MAX_RATIONAL_DENOMINATOR = 2520 -export interface Root +export interface Mutable +{ + root: ImmutableRoot +} + + +export interface ImmutableRoot { nextId: Project.ID range: Range baseBpm: number + tracks: Project.Track[] lists: Immutable.Map> elems: Immutable.Map keyChangeTrackId: number meterChangeTrackId: number chordTrackId: number + noteTrackId: number } -export function makeEmpty(): Root +export function makeEmpty(): ImmutableRoot { return { nextId: 1, @@ -36,11 +44,12 @@ export function makeEmpty(): Root keyChangeTrackId: -1, meterChangeTrackId: -1, chordTrackId: -1, + noteTrackId: -1, } } -export function makeNew(): Root +export function makeNew(): ImmutableRoot { let project = makeEmpty() @@ -63,64 +72,32 @@ export function makeNew(): Root project = upsertTrack(project, Project.makeTrackChords()) const track4Id = project.nextId + project.noteTrackId = track4Id project = upsertTrack(project, Project.makeTrackNotes()) return project } -export function getDefault(): Root +export function makeTest(): ImmutableRoot { - let project = makeEmpty() + let project = makeNew() - const track1Id = project.nextId - project.keyChangeTrackId = track1Id - project = upsertTrack(project, Project.makeTrackKeyChanges()) - - const track2Id = project.nextId - project.meterChangeTrackId = track2Id - project = upsertTrack(project, Project.makeTrackMeterChanges()) - - project = upsertElement(project, Project.makeKeyChange( - track1Id, new Rational(0), Theory.Key.parse("C Major"))) - - project = upsertElement(project, Project.makeMeterChange( - track2Id, new Rational(0), new Theory.Meter(4, 4))) - - const track3Id = project.nextId - project.chordTrackId = track3Id - project = upsertTrack(project, Project.makeTrackChords()) - - project = upsertElement(project, Project.makeChord( - track3Id, - Range.fromStartDuration(new Rational(0), new Rational(1)), - new Theory.Chord(0, 0, 0, []))) - - const track4Id = project.nextId - project = upsertTrack(project, Project.makeTrackNotes()) - - const noteBlockId = project.nextId - project = upsertElement(project, Project.makeNoteBlock( - track4Id, - Range.fromStartDuration(new Rational(0), new Rational(4)))) - - for (let i = 0; i < 16; i++) + for (let i = 0; i < 24; i++) project = upsertElement(project, Project.makeNote( - noteBlockId, + project.noteTrackId, Range.fromStartDuration(new Rational(i, 4), new Rational(1, 4)), - 60 + i, - 0, - 1)) + Theory.Utils.midiMiddleC + i)) return project } export function upsertTrack( - project: Root, + project: ImmutableRoot, track: Project.Track, remove: boolean = false, - insertBefore: number = -1): Root + insertBefore: number = -1): ImmutableRoot { let nextId = project.nextId let tracks = project.tracks @@ -174,7 +151,7 @@ export function upsertTrack( } -export function upsertElement(project: Root, elem: Project.Element): Root +export function upsertElement(project: ImmutableRoot, elem: Project.Element): ImmutableRoot { let nextId = project.nextId @@ -189,7 +166,7 @@ export function upsertElement(project: Root, elem: Project.Element): Root if (!changeParent) { - let list = project.lists.get(elem.parentId) || new ListOfRanges() + let list = project.lists.get(elem.parentId) ?? new ListOfRanges() list = list.upsert(elem) let elems = project.elems.set(elem.id, elem) @@ -198,32 +175,22 @@ export function upsertElement(project: Root, elem: Project.Element): Root } else if (elem.parentId < 0) { - let prevList = project.lists.get(prevElem!.parentId) || new ListOfRanges() + let prevList = project.lists.get(prevElem!.parentId) ?? new ListOfRanges() prevList = prevList.removeById(prevElem!.id) let elems = project.elems.delete(elem.id) let lists = project.lists.set(prevElem!.parentId, prevList) - /*console.log("delete elem " + elem.id + " from " + prevElem!.parentId) - console.log(prevList.findById(elem.id)) - console.log(elems.get(elem.id))*/ - return { ...project, nextId, elems, lists } } else { - let prevList = project.lists.get(prevElem!.parentId) || new ListOfRanges() + let prevList = project.lists.get(prevElem!.parentId) ?? new ListOfRanges() prevList = prevList.removeById(prevElem!.id) - let nextList = project.lists.get(elem.parentId) || new ListOfRanges() + let nextList = project.lists.get(elem.parentId) ?? new ListOfRanges() nextList = nextList.upsert(elem) - /*console.log("change parent from " + prevElem!.parentId + " to " + elem.parentId) - console.log(prevElem!) - console.log(prevList.findById(elem.id)) - console.log(elem) - console.log(nextList.findById(elem.id))*/ - let elems = project.elems.set(elem.id, elem) let lists = project.lists .set(prevElem!.parentId, prevList) @@ -234,19 +201,19 @@ export function upsertElement(project: Root, elem: Project.Element): Root } -export function keyChangeTrackId(project: Root): Project.ID +export function keyChangeTrackId(project: ImmutableRoot): Project.ID { return project.keyChangeTrackId } -export function meterChangeTrackId(project: Root): Project.ID +export function meterChangeTrackId(project: ImmutableRoot): Project.ID { return project.meterChangeTrackId } -export function keyAt(project: Root, trackId: Project.ID, time: Rational): Theory.Key +export function keyAt(project: ImmutableRoot, trackId: Project.ID, time: Rational): Theory.Key { const keyChangeTrackId = Project.keyChangeTrackId(project) const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId) @@ -265,7 +232,7 @@ export function keyAt(project: Root, trackId: Project.ID, time: Rational): Theor } -export function meterChangeAt(project: Root, trackId: Project.ID, time: Rational): Project.MeterChange | null +export function meterChangeAt(project: ImmutableRoot, trackId: Project.ID, time: Rational): Project.MeterChange | null { const meterChangeTrackId = Project.meterChangeTrackId(project) const meterChangeTrackTimedElems = project.lists.get(meterChangeTrackId) @@ -284,7 +251,7 @@ export function meterChangeAt(project: Root, trackId: Project.ID, time: Rational } -export function meterAt(project: Root, trackId: Project.ID, time: Rational): Theory.Meter +export function meterAt(project: ImmutableRoot, trackId: Project.ID, time: Rational): Theory.Meter { const meterCh = meterChangeAt(project, trackId, time) if (meterCh) @@ -294,7 +261,7 @@ export function meterAt(project: Root, trackId: Project.ID, time: Rational): The } -export function withRefreshedRange(project: Root): Root +export function withRefreshedRange(project: ImmutableRoot): ImmutableRoot { let range = new Range(new Rational(0), new Rational(4)); @@ -314,7 +281,7 @@ export function withRefreshedRange(project: Root): Root export function getElem( - project: Root, + project: ImmutableRoot, id: Project.ID, type: T) : Extract | null @@ -328,7 +295,7 @@ export function getElem( export function getTrack( - project: Root, + project: ImmutableRoot, id: Project.ID, trackType: T) : Extract | null @@ -342,10 +309,10 @@ export function getTrack( export function cloneElem( - fromProject: Root, + fromProject: ImmutableRoot, elem: Project.Element, - toProject: Root) - : Root + toProject: ImmutableRoot) + : ImmutableRoot { const newElem = { ...elem } newElem.id = -1 @@ -370,10 +337,10 @@ export function cloneElem( export function splitElem( - project: Root, + project: ImmutableRoot, elem: Project.Element, splitRange: Range) - : Root + : ImmutableRoot { const origProject = project const absRange = getAbsoluteRange(origProject, elem.parentId, elem.range) @@ -398,14 +365,14 @@ export function splitElem( function splitInnerElem( - origProject: Root, - project: Root, + origProject: ImmutableRoot, + project: ImmutableRoot, newParentId: Project.ID, elem: Project.Element, relativeDisplace: Rational, splitRange: Range, keepRange: Range) - : Root + : ImmutableRoot { const innerList = origProject.lists.get(elem.id) @@ -448,7 +415,7 @@ function splitInnerElem( } -export function parentTrackFor(project: Root, elemId: Project.ID): Project.Track +export function parentTrackFor(project: ImmutableRoot, elemId: Project.ID): Project.Track { while (true) { @@ -464,7 +431,7 @@ export function parentTrackFor(project: Root, elemId: Project.ID): Project.Track } -export function getAbsoluteTime(project: Root, parentId: Project.ID, time: Rational): Rational +export function getAbsoluteTime(project: ImmutableRoot, parentId: Project.ID, time: Rational): Rational { while (true) { @@ -481,7 +448,7 @@ export function getAbsoluteTime(project: Root, parentId: Project.ID, time: Ratio } -export function getRelativeTime(project: Root, parentId: Project.ID, time: Rational): Rational +export function getRelativeTime(project: ImmutableRoot, parentId: Project.ID, time: Rational): Rational { while (true) { @@ -498,7 +465,7 @@ export function getRelativeTime(project: Root, parentId: Project.ID, time: Ratio } -export function getAbsoluteRange(project: Root, parentId: Project.ID, range: Range): Range +export function getAbsoluteRange(project: ImmutableRoot, parentId: Project.ID, range: Range): Range { while (true) { @@ -515,7 +482,7 @@ export function getAbsoluteRange(project: Root, parentId: Project.ID, range: Ran } -export function getRelativeRange(project: Root, parentId: Project.ID, range: Range): Range +export function getRelativeRange(project: ImmutableRoot, parentId: Project.ID, range: Range): Range { while (true) { @@ -532,7 +499,10 @@ export function getRelativeRange(project: Root, parentId: Project.ID, range: Ran } -export function getRangeForElems(project: Root, elemIds: Iterable): Range | null +export function getRangeForElems( + project: ImmutableRoot, + elemIds: Iterable) + : Range | null { let range: Range | null = null @@ -553,7 +523,7 @@ export function getRangeForElems(project: Root, elemIds: Iterable): } -export function getMillisecondsAt(project: Root, time: Rational): number +export function getMillisecondsAt(project: ImmutableRoot, time: Rational): number { const measuresPerSecond = (project.baseBpm / 4 / 60) return time.subtract(project.range.start).asFloat() / measuresPerSecond * 1000 diff --git a/src/state.ts b/src/state.ts new file mode 100644 index 0000000..2222368 --- /dev/null +++ b/src/state.ts @@ -0,0 +1,40 @@ +import * as Solid from "solid-js" +import * as Project from "./project" +import * as Timeline from "./timeline" +import * as Prefs from "./prefs" + + +const [state, setState] = + Solid.createSignal(makeNew()) + + +export interface State +{ + test: number + prefs: Prefs.Prefs + project: Project.Mutable + timeline: Timeline.State +} + + +export function makeNew(): State +{ + return { + test: 0, + prefs: Prefs.makeNew(), + project: { root: Project.makeTest() }, + timeline: Timeline.makeNew(), + } +} + + +export function get(): State +{ + return state() +} + + +export function refresh() +{ + setState({ ...state() }) +} \ No newline at end of file diff --git a/src/theory/chord.ts b/src/theory/chord.ts index 016324c..fec63ac 100644 --- a/src/theory/chord.ts +++ b/src/theory/chord.ts @@ -1,6 +1,6 @@ -import * as MathUtils from "../util/mathUtils" -import Key from "./key" -import Utils from "./utils" +import * as MathUtils from "../utils/mathUtils.ts" +import Key from "./key.ts" +import Utils from "./utils.ts" interface ChordMetadata @@ -229,7 +229,7 @@ export default class Chord const rootMidi = Utils.mod(this.rootChroma, 12) - let pitches = [] + const pitches: number[] = [] for (let i = 0; i < chordData.pitches.length; i++) pitches.push(rootMidi + chordData.pitches[i]) diff --git a/src/theory/index.ts b/src/theory/index.ts index c08938e..b02f255 100644 --- a/src/theory/index.ts +++ b/src/theory/index.ts @@ -1,7 +1,7 @@ -export { default as Pitch } from "./pitch" -export { default as PitchName } from "./pitchName" -export { default as Scale } from "./scale" -export { default as Key } from "./key" -export { default as Meter } from "./meter" -export { default as Chord } from "./chord" -export { default as Utils } from "./utils" \ No newline at end of file +export { default as Pitch } from "./pitch.ts" +export { default as PitchName } from "./pitchName.ts" +export { default as Scale } from "./scale.ts" +export { default as Key } from "./key.ts" +export { default as Meter } from "./meter.ts" +export { default as Chord } from "./chord.ts" +export { default as Utils } from "./utils.ts" \ No newline at end of file diff --git a/src/theory/key.ts b/src/theory/key.ts index 3bebda3..392f5b8 100644 --- a/src/theory/key.ts +++ b/src/theory/key.ts @@ -1,7 +1,7 @@ -import PitchName from "./pitchName" -import Pitch from "./pitch" -import Scale from "./scale" -import Utils from "./utils" +import PitchName from "./pitchName.ts" +import Pitch from "./pitch.ts" +import Scale from "./scale.ts" +import Utils from "./utils.ts" export default class Key diff --git a/src/theory/meter.ts b/src/theory/meter.ts index b432c26..d06df17 100644 --- a/src/theory/meter.ts +++ b/src/theory/meter.ts @@ -1,4 +1,4 @@ -import Rational from "../util/rational" +import Rational from "../utils/rational.ts" export default class Meter diff --git a/src/theory/pitch.ts b/src/theory/pitch.ts index d1d41b1..1b6338c 100644 --- a/src/theory/pitch.ts +++ b/src/theory/pitch.ts @@ -1,5 +1,5 @@ -import PitchName from "./pitchName" -import Utils from "./utils" +import PitchName from "./pitchName.ts" +import Utils from "./utils.ts" export default class Pitch diff --git a/src/theory/pitchName.ts b/src/theory/pitchName.ts index c8a88d6..a4ee8a9 100644 --- a/src/theory/pitchName.ts +++ b/src/theory/pitchName.ts @@ -1,4 +1,4 @@ -import Utils from "./utils" +import Utils from "./utils.ts" export default class PitchName diff --git a/src/theory/scale.ts b/src/theory/scale.ts index 2237013..9f942b7 100644 --- a/src/theory/scale.ts +++ b/src/theory/scale.ts @@ -1,4 +1,4 @@ -import PitchName from "./pitchName" +import PitchName from "./pitchName.ts" interface ScaleMetadata diff --git a/src/theory/utils.ts b/src/theory/utils.ts index 6edb860..f7e289a 100644 --- a/src/theory/utils.ts +++ b/src/theory/utils.ts @@ -5,6 +5,7 @@ export default class Utils return (x % m + m) % m } + static midiMiddleC = 60 static chromaToLetter = (chroma: number): number => [0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][chroma] static chromaToAccidental = (chroma: number): number => [0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0][chroma] diff --git a/src/timeline/Element.tsx b/src/timeline/Element.tsx index 53b28b2..021e20c 100644 --- a/src/timeline/Element.tsx +++ b/src/timeline/Element.tsx @@ -1,393 +1,189 @@ -import React from "react" -import * as Timeline from "./index" -import * as Project from "../project" -import * as Playback from "../playback" -import * as Prefs from "../prefs" -import * as Popup from "../popup" -import * as Dockable from "../dockable" -import * as UI from "../ui" -import { useRefState, RefState } from "../util/refState" -import Rect from "../util/rect" -import styled from "styled-components" - - -const StyledTrackButton = styled.button` - pointer-events: auto; - color: #fff; - border: 1px solid #888; - border-radius: 0.5em; - background-color: #2f3136; - padding: 0.1em 0.3em; - cursor: pointer; - - &:hover - { - border: 1px solid #fff; - } -` +import * as Solid from "solid-js" +import * as Global from "../state.ts" +import * as Timeline from "./index.ts" +import Rect from "../utils/rect.ts" -export function TimelineElement(props: { state?: RefState }) +export function Element(props: {}) { - const refDiv = React.useRef(null) - const refCanvas = React.useRef(null) - - const editorState = props.state ?? useRefState(() => Timeline.init()) - const dockableWindow = Dockable.useWindow() + let div: HTMLDivElement | undefined = undefined + let canvas: HTMLCanvasElement | undefined = undefined - const lastTimelineRenderRef = React.useRef(0) - - const render = (force?: boolean) => - { - if (!refCanvas.current) + Solid.createEffect(() => { + if (!div || !canvas) return - const now = new Date().getTime() - if (!force && now < lastTimelineRenderRef.current + 15) - return + const cleanup = registerHandlers(div, canvas) - //console.log("Timeline render") - lastTimelineRenderRef.current = now + Solid.onCleanup(cleanup) + }) - Timeline.render( - editorState.ref.current, - refCanvas.current.getContext("2d")!) - } - const onResize = () => - { - if (!refDiv.current || !refCanvas.current) - return - - const pixelRatio = window.devicePixelRatio || 1 - - const rect = refDiv.current.getBoundingClientRect() - const x = Math.floor(rect.x) - const y = Math.floor(rect.y) - const w = Math.floor(rect.width * pixelRatio) - const h = Math.floor(rect.height * pixelRatio) - - refCanvas.current.style.width = Math.floor(rect.width) + "px" - refCanvas.current.style.height = Math.floor(rect.height) + "px" - refCanvas.current.width = w - refCanvas.current.height = h - - const renderRect = new Rect(x, y, w, h) - - Timeline.resize(editorState.ref.current, pixelRatio, renderRect) - render(true) - } - - React.useLayoutEffect(() => - { - if (!refDiv.current) - return - - const observer = new ResizeObserver(entries => - { - onResize() - }) - - const elem = refDiv.current - observer.observe(elem) - - onResize() - return () => observer.unobserve(elem) + return
+ +
+} - }, [refDiv.current]) - React.useEffect(() => - { - Timeline.scrollPlaybackTimeIntoView(editorState.ref.current) - render(!Playback.global.playing) - - }, [Playback.globalObservable.updateToken]) +function canvasResize( + div: HTMLDivElement, + canvas: HTMLCanvasElement, + timeline: Timeline.State) +{ + const pixelRatio = window.devicePixelRatio || 1 + + const domRect = div.getBoundingClientRect() + const x = Math.floor(domRect.x) + const y = Math.floor(domRect.y) + const w = Math.floor(domRect.width * pixelRatio) + const h = Math.floor(domRect.height * pixelRatio) + + canvas.style.width = domRect.width + "px" + canvas.style.height = domRect.height + "px" + canvas.width = w + canvas.height = h + + const rect = new Rect(0, 0, w, h) + + Timeline.resize(timeline, pixelRatio, rect) +} - React.useEffect(() => - { - Timeline.refreshTracks(editorState.ref.current) - render(true) - }, [Project.global.project.tracks]) +function registerHandlers( + div: HTMLDivElement, + canvas: HTMLCanvasElement) +{ + const ctx = canvas.getContext("2d")! - React.useEffect(() => + const transformMousePos = (canvas: HTMLCanvasElement, ev: MouseEvent) => { - const refCanvasCurrent = refCanvas.current - if (!refCanvasCurrent) - return - - const transformMousePos = (canvas: HTMLCanvasElement, ev: MouseEvent) => - { - const rect = canvas.getBoundingClientRect() - return { - x: (ev.clientX - rect.left) * editorState.ref.current.pixelRatio, - y: (ev.clientY - rect.top) * editorState.ref.current.pixelRatio, - } - } - - const preventDefault = (ev: Event) => ev.preventDefault() - - const setCursor = (state: Timeline.State) => - { - let cursor = "text" - const mouseAction = - state.mouse.down ? state.mouse.action : - state.hoverControl != Timeline.TrackControl.None ? Timeline.MouseAction.DragTrackControl : - state.hover ? state.hover.action : - Timeline.MouseAction.None - - if (state.tracks.some((tr: any) => !!tr.pencil) || - mouseAction == Timeline.MouseAction.Pencil) - cursor = "crosshair" - else if (mouseAction == Timeline.MouseAction.DragTrackControl) - cursor = "crosshair" - else if (mouseAction == Timeline.MouseAction.DragClone) - cursor = "crosshair" - else if (mouseAction == Timeline.MouseAction.DragTime || - mouseAction == Timeline.MouseAction.DragTimeAndRow || - mouseAction == Timeline.MouseAction.DragRow || - mouseAction == Timeline.MouseAction.DragTrackHeader) - cursor = (state.mouse.down ? "grabbing" : "grab") - else if (mouseAction == Timeline.MouseAction.Pan) - cursor = "move" - else if (mouseAction == Timeline.MouseAction.StretchTimeStart || - mouseAction == Timeline.MouseAction.StretchTimeEnd) - cursor = "col-resize" - - refCanvasCurrent.style.cursor = cursor + const rect = canvas.getBoundingClientRect() + const timeline = Global.get().timeline + return { + x: (ev.clientX - rect.left) * timeline.pixelRatio, + y: (ev.clientY - rect.top) * timeline.pixelRatio, } + } - const onMouseMove = (ev: MouseEvent) => - { - const state = editorState.ref.current - if (state.mouse.down) - ev.preventDefault() - - const pos = transformMousePos(refCanvasCurrent, ev) - const projectBefore = Project.global.project - const needsRender1 = Timeline.mouseMove(state, pos) - const needsRender2 = Timeline.mouseDrag(state, pos, false) - - if (projectBefore !== Project.global.project) - Project.notifyObservers() + const setCursor = () => { + const timeline = Global.get().timeline + + const action = timeline.mouse.down ? + timeline.mouse.action : + timeline.hover?.action + + canvas.style.cursor = + action === Timeline.MouseAction.DragTime || + action === Timeline.MouseAction.DragRow || + action === Timeline.MouseAction.DragTimeAndRow ? + timeline.mouse.down ? "grabbing" : "grab" : + action === Timeline.MouseAction.StretchTimeStart || + action === Timeline.MouseAction.StretchTimeEnd ? + "col-resize" : + "inherit" + } - if (needsRender1 || needsRender2) - render(true) + const onResize = () => { + const timeline = Global.get().timeline + const project = Global.get().project - setCursor(state) - } - - const onMouseDown = (ev: MouseEvent) => - { - if (document.activeElement instanceof HTMLElement) - document.activeElement.blur() - - ev.preventDefault() + canvasResize(div, canvas, timeline) + Timeline.layout(timeline, project.root) + Timeline.draw(timeline, ctx) + } - Dockable.removeEphemerals(Dockable.global.state) - Dockable.notifyObservers() + const onMouseMove = (ev: MouseEvent) => { + ev.preventDefault() - const state = editorState.ref.current - const pos = transformMousePos(refCanvasCurrent, ev) - const projectBefore = Project.global.project - Timeline.mouseMove(state, pos) - Timeline.mouseDown(state, ev.button != 0) - Timeline.mouseDrag(state, pos, true) + const timeline = Global.get().timeline + const project = Global.get().project + const mouse = transformMousePos(canvas, ev) - if (projectBefore !== Project.global.project) - Project.notifyObservers() + Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) - render() - setCursor(state) - editorState.commit() - } + if (Timeline.mouseDrag(timeline, project)) + Timeline.layout(timeline, project.root) - const onMouseUp = (ev: MouseEvent) => - { - const state = editorState.ref.current - if (state.mouse.down) - ev.preventDefault() - - const pos = transformMousePos(refCanvasCurrent, ev) - const projectBefore = Project.global.project - Timeline.mouseUp(state) - - if (projectBefore !== Project.global.project) - { - Project.notifyObservers() - window.dispatchEvent(new Event("timelineRefresh")) - } - - render() - setCursor(state) - editorState.commit() - } - - const onMouseWheel = (ev: WheelEvent) => - { - Timeline.mouseWheel(editorState.ref.current, ev.deltaX, ev.deltaY) - render() - } - - const onKeyDown = (ev: KeyboardEvent) => - { - const isActiveWindow = - Dockable.global.state.activePanel === dockableWindow.panel && - (!document.activeElement || document.activeElement.tagName != "INPUT") - - const projectBefore = Project.global.project - Timeline.keyDown(editorState.ref.current, isActiveWindow, ev.key.toLowerCase()) - - if (projectBefore !== Project.global.project) - Project.notifyObservers() - - render() - editorState.commit() - } - - const onKeyUp = (ev: KeyboardEvent) => - { - Timeline.keyUp(editorState.ref.current, ev.key.toLowerCase()) - } - - const onRewind = (ev: Event) => - { - Timeline.rewind(editorState.ref.current) - editorState.commit() - render(true) - } - - const onRefresh = (ev: Event) => - { - Timeline.refreshTracks(editorState.ref.current) - editorState.commit() - render(true) - } - - const onReset = (ev: Event) => - { - const state = editorState.ref.current - Timeline.modeStackPop(state, 0) - Timeline.reset(state) - Timeline.rewind(state) - Timeline.refreshTracks(state) - editorState.commit() - render(true) - } - - refCanvasCurrent.addEventListener("mousedown", onMouseDown) - refCanvasCurrent.addEventListener("wheel", onMouseWheel) - refCanvasCurrent.addEventListener("contextmenu", preventDefault) - - window.addEventListener("mousemove", onMouseMove) - window.addEventListener("mouseup", onMouseUp) - window.addEventListener("keydown", onKeyDown) - window.addEventListener("keyup", onKeyUp) - - window.addEventListener("timelineRewind", onRewind) - window.addEventListener("timelineRefresh", onRefresh) - window.addEventListener("timelineReset", onReset) - - return () => - { - refCanvasCurrent.removeEventListener("mousedown", onMouseDown) - refCanvasCurrent.removeEventListener("wheel", onMouseWheel) - refCanvasCurrent.removeEventListener("contextmenu", preventDefault) - - window.removeEventListener("mousemove", onMouseMove) - window.removeEventListener("mouseup", onMouseUp) - window.removeEventListener("keydown", onKeyDown) - window.removeEventListener("keyup", onKeyUp) - - window.removeEventListener("timelineRewind", onRewind) - window.removeEventListener("timelineRefresh", onRefresh) - window.removeEventListener("timelineReset", onReset) - } + Timeline.draw(timeline, ctx) + setCursor() + } - }, [refCanvas.current]) + const onMouseDown = (ev: MouseEvent) => { + ev.preventDefault() + const timeline = Global.get().timeline + const project = Global.get().project + const prefs = Global.get().prefs + const mouse = transformMousePos(canvas, ev) + + Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) + Timeline.mouseDown(timeline, project.root, prefs, ev.button !== 0) + Timeline.draw(timeline, ctx) + setCursor() + } - const yTrackEnd = - editorState.ref.current.tracks.length == 0 ? - 0 : - editorState.ref.current.tracks[editorState.ref.current.tracks.length - 1].renderRect.y2 + const onMouseUp = (ev: MouseEvent) => { + ev.preventDefault() - const onAddTrack = () => - { - let proj = Project.global.project - proj = Project.upsertTrack(proj, Project.makeTrackNotes()) - Project.global.project = proj - Project.splitUndoPoint() - Project.addUndoPoint("addTrack") - Project.notifyObservers() + const timeline = Global.get().timeline + const project = Global.get().project + const mouse = transformMousePos(canvas, ev) - window.dispatchEvent(new Event("timelineRefresh")) + Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) + Timeline.mouseUp(timeline, project.root, ev.button !== 0) + Timeline.draw(timeline, ctx) + setCursor() } + + const onMouseWheel = (ev: WheelEvent) => { + ev.preventDefault() + + const timeline = Global.get().timeline + const project = Global.get().project - const onTrackSettings = (ev: React.MouseEvent, trackIndex: number) => - { - Popup.global.elem = () => - { - return - - - } - Popup.global.rect = Rect.fromElement(ev.target as HTMLElement) - Popup.notifyObservers() + Timeline.mouseWheel(timeline, ev.deltaX, ev.deltaY) + Timeline.layout(timeline, project.root) + Timeline.draw(timeline, ctx) } - const pixelRatio = window.devicePixelRatio || 1 + const onKeyDown = (ev: KeyboardEvent) => { + const timeline = Global.get().timeline - return React.useMemo(() => -
- - -
- - +{/*➕*/} - -
-
- , [ - Project.global.project.tracks, - editorState.ref.current.tracks, - editorState.ref.current.trackScroll, - ]) -} + Timeline.keyDown(timeline, ev.key.toLowerCase()) + } + const onKeyUp = (ev: KeyboardEvent) => { + const timeline = Global.get().timeline -export function sendEventRefresh() -{ - window.dispatchEvent(new Event("timelineRefresh")) -} + Timeline.keyUp(timeline, ev.key.toLowerCase()) + } + const preventDefault = (ev: MouseEvent) => { + ev.preventDefault() + } -export function sendEventReset() -{ - window.dispatchEvent(new Event("timelineReset")) + onResize() + + canvas.addEventListener("resize", onResize) + window.addEventListener("mousemove", onMouseMove) + canvas.addEventListener("mousedown", onMouseDown) + window.addEventListener("mouseup", onMouseUp) + canvas.addEventListener("wheel", onMouseWheel) + canvas.addEventListener("contextmenu", preventDefault) + window.addEventListener("keydown", onKeyDown) + window.addEventListener("keyup", onKeyUp) + + return () => { + canvas.removeEventListener("resize", onResize) + window.removeEventListener("mousemove", onMouseMove) + canvas.removeEventListener("mousedown", onMouseDown) + window.removeEventListener("mouseup", onMouseUp) + canvas.removeEventListener("wheel", onMouseWheel) + canvas.removeEventListener("contextmenu", preventDefault) + window.removeEventListener("keydown", onKeyDown) + window.removeEventListener("keyup", onKeyUp) + } } \ No newline at end of file diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts new file mode 100644 index 0000000..cff61e3 --- /dev/null +++ b/src/timeline/draw.ts @@ -0,0 +1,361 @@ +import * as State from "../state.ts" +import * as Timeline from "./index.ts" +import * as Theory from "../theory" +import Rational from "../utils/rational.ts" + + +export function draw( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D) +{ + ctx.save() + ctx.translate(0.5, 0.5) + + ctx.fillStyle = "#fff" + ctx.fillRect(0, 0, timeline.renderRect.w, timeline.renderRect.h) + + drawElements(timeline, ctx, timeline.layout.elements) + + if (timeline.cursor.visible) + { + const timeMin = timeline.cursor.time1.min(timeline.cursor.time2) + const timeMax = timeline.cursor.time1.max(timeline.cursor.time2) + drawCursorBeam(timeline, ctx, timeMin, false) + drawCursorBeam(timeline, ctx, timeMax, true) + } + + ctx.restore() +} + + +function drawElements( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + elements: Timeline.LayoutElement[]) +{ + for (const element of elements) + { + if (element.kind === "lane") + { + ctx.save() + ctx.beginPath() + ctx.rect( + element.rect.x, + element.rect.y, + element.rect.w, + element.rect.h) + ctx.clip() + + drawLaneBkgSolid(timeline, ctx, element) + drawLaneBkgMeasures(timeline, ctx, element, false) + drawLaneBkgMeasures(timeline, ctx, element, true) + drawCursorBkg(timeline, ctx, element) + + if (element.subElements) + drawElements(timeline, ctx, element.subElements) + + drawLaneFrgOutline(timeline, ctx, element) + + ctx.restore() + } + + if (element.kind === "laneNotes") + { + ctx.save() + ctx.beginPath() + ctx.rect( + element.rect.x, + element.rect.y, + element.rect.w, + element.rect.h) + ctx.clip() + + drawLaneBkgSolid(timeline, ctx, element) + drawLaneBkgOctaves(timeline, ctx, element, false) + drawLaneBkgMeasures(timeline, ctx, element, false) + drawLaneBkgOctaves(timeline, ctx, element, true) + drawLaneBkgMeasures(timeline, ctx, element, true) + drawCursorBkg(timeline, ctx, element) + + if (element.subElements) + drawElements(timeline, ctx, element.subElements) + + drawLaneFrgOutline(timeline, ctx, element) + + ctx.restore() + } + + if (element.kind === "note") + { + ctx.fillStyle = + timeline.hover?.id === element.id ? "#f88" : "#f00" + ctx.beginPath() + ctx.roundRect( + element.rect.x, + element.rect.y, + element.rect.w, + element.rect.h, + timeline.noteRowH / 4) + ctx.fill() + + if (element.id !== undefined && + timeline.selection.has(element.id)) + { + ctx.strokeStyle = "#fbb" + ctx.lineWidth = 4 + ctx.stroke() + } + } + } +} + + +export function drawLaneBkgCenterStroke( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + lane: Timeline.LayoutElementLaneMarkers) +{ + const yCenter = Math.floor(lane.rect.y + lane.rect.h / 2) + 0.5 + ctx.strokeStyle = "#fff" + ctx.lineWidth = 2 + ctx.beginPath() + ctx.moveTo(lane.rect.x, yCenter) + ctx.lineTo(lane.rect.x + lane.rect.w, yCenter) + ctx.stroke() +} + + +export function drawLaneBkgSolid( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + lane: Timeline.LayoutElementLaneMarkers | Timeline.LayoutElementLaneNotes) +{ + ctx.fillStyle = "#eee" + ctx.fillRect( + lane.rect.x, + lane.rect.y, + lane.rect.w, + lane.rect.h) +} + + +export function drawLaneFrgOutline( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + lane: Timeline.LayoutElementLaneMarkers | Timeline.LayoutElementLaneNotes) +{ + ctx.strokeStyle = "#000" + ctx.lineWidth = 1 + ctx.beginPath() + ctx.moveTo(lane.rect.x, lane.rect.y) + ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y) + ctx.moveTo(lane.rect.x, lane.rect.y + lane.rect.h) + ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y + lane.rect.h) + ctx.stroke() +} + + +export function drawLaneBkgMeasures( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + lane: Timeline.LayoutElementLaneMarkers | Timeline.LayoutElementLaneNotes, + mainLinePass: boolean) +{ + // Render alternating measure background and sub-measure dividers. + const measureHalfH = lane.rect.h / 2 + const submeasureHalfH = lane.rect.h / 2 + for (const measure of timeline.layout.measures) + { + const x1 = Math.floor(Timeline.xAtTime(timeline, measure.time1)) + const x2 = Math.floor(Timeline.xAtTime(timeline, measure.time2)) + + const submeasureSize = + Timeline.xAtTime(timeline, new Rational(1, measure.meterCh.meter.denominator)) - + Timeline.xAtTime(timeline, new Rational(0)) + + if (mainLinePass) + { + ctx.strokeStyle = "#444" + ctx.lineWidth = 2 + ctx.beginPath() + ctx.moveTo(x1 + 0.5, lane.rect.y) + ctx.lineTo(x1 + 0.5, lane.rect.y + lane.rect.h) + ctx.stroke() + } + + if (!mainLinePass && + submeasureSize > 8) + { + ctx.strokeStyle = "#fff" + ctx.lineWidth = 1 + ctx.beginPath() + + for (let n = 1; n < measure.meterCh.meter.numerator; n++) + { + const submeasureX = x1 + Math.round(submeasureSize * n) + if (submeasureX >= x2) + break + + ctx.moveTo(submeasureX, lane.rect.y) + ctx.lineTo(submeasureX, lane.rect.y + lane.rect.h) + } + + ctx.stroke() + } + } +} + + +export function drawLaneBkgOctaves( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + lane: Timeline.LayoutElementLaneNotes, + mainLinePass: boolean) +{ + const rowAtTop = Timeline.rowAtY(timeline, lane, lane.rect.y) + const rowAtBottom = Timeline.rowAtY(timeline, lane, lane.rect.y + lane.rect.h) + + const octaveAtTop = Math.ceil(rowAtTop / 7) + 1 + const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1 + + ctx.fillStyle = "#444" + ctx.font = Math.floor(timeline.noteRowH - 4) + "px system-ui" + ctx.textAlign = "left" + ctx.textBaseline = "bottom" + + for (const keyRegion of timeline.layout.keyRegions) + { + const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(keyRegion.keyCh1.key.tonic.chroma) + + let needsOctaveLabels = true + let drewOctaveLabels = false + + for (const measure of timeline.layout.measures) + { + /*if (measure.time1.lessThan(keyRegion.keyCh1.range.start) || + measure.time2.greaterThan(keyRegion.keyCh2.range.start)) + continue*/ + + const x1 = Math.floor(Timeline.xAtTime(timeline, measure.time1)) + const x2 = Math.floor(Timeline.xAtTime(timeline, measure.time2)) + + for (let i = octaveAtBottom; i <= octaveAtTop; i++) + { + const y = Math.floor( + Timeline.yForRow(timeline, lane, tonicRowOffset + i * 7) + timeline.noteRowH) + + if (mainLinePass) + { + const labelX = Math.max(x1 + 5, 5) + if (needsOctaveLabels && labelX + 30 < x2) + { + ctx.fillText(keyRegion.keyCh1.key.tonic.str + (i + 5).toString(), labelX, y - 1) + drewOctaveLabels = true + } + + ctx.strokeStyle = "#444" + ctx.beginPath() + ctx.moveTo(x1, y) + ctx.lineTo(x2, y) + ctx.moveTo(x1, y + 1) + ctx.lineTo(x2, y + 1) + ctx.stroke() + } + + if (!mainLinePass) + { + ctx.strokeStyle = "#fff" + ctx.beginPath() + for (let j = 1; j < 7; j += 1) + { + const ySuboctave = Math.floor( + Timeline.yForRow(timeline, lane, tonicRowOffset + i * 7 + j) + timeline.noteRowH) + + ctx.moveTo(x1, ySuboctave) + ctx.lineTo(x2, ySuboctave) + } + ctx.stroke() + } + } + + if (drewOctaveLabels) + needsOctaveLabels = false + } + } +} + + +function drawCursorBeam( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + time: Rational, + tipOffsetSide: boolean) +{ + const prefs = State.get().prefs + + const laneIndexMin = Timeline.cursorGetLaneIndexMin(timeline) + const laneIndexMax = Timeline.cursorGetLaneIndexMax(timeline) + + const laneMin = timeline.layout.lanes[laneIndexMin] + const laneMax = timeline.layout.lanes[laneIndexMax] + + const x = 0.5 + Math.floor(Timeline.xAtTime(timeline, time)) + + ctx.strokeStyle = prefs.timeline.selectionCursorColor + ctx.fillStyle = prefs.timeline.selectionCursorColor + ctx.lineCap = "square" + ctx.lineWidth = 2 + + const headYSize = 10 + const headXSize = headYSize * (tipOffsetSide ? -1 : 1) + + const y1 = Math.floor(laneMin.rect.y) + const y2 = Math.floor(laneMax.rect.y2) + + ctx.beginPath() + ctx.moveTo(x, y1 + headYSize) + ctx.lineTo(x + headXSize, y1) + ctx.lineTo(x, y1) + ctx.fill() + + ctx.beginPath() + ctx.moveTo(x, y2 - headYSize) + ctx.lineTo(x + headXSize, y2) + ctx.lineTo(x, y2) + ctx.fill() + + ctx.beginPath() + ctx.moveTo(x, y1 + 1) + ctx.lineTo(x, y2 - 1) + ctx.stroke() +} + + +function drawCursorBkg( + timeline: Timeline.State, + ctx: CanvasRenderingContext2D, + lane: Timeline.LayoutLane) +{ + if (!timeline.cursor.visible) + return + + const prefs = State.get().prefs + + const timeMin = timeline.cursor.time1.min(timeline.cursor.time2) + const timeMax = timeline.cursor.time1.max(timeline.cursor.time2) + const laneIndexMin = Timeline.cursorGetLaneIndexMin(timeline) + const laneIndexMax = Timeline.cursorGetLaneIndexMax(timeline) + + if (laneIndexMin > lane.laneIndex || + laneIndexMax < lane.laneIndex) + return + + const y1 = Math.floor(lane.rect.y) + const y2 = Math.floor(lane.rect.y2) + + const x1 = Timeline.xAtTime(timeline, timeMin) + const x2 = Timeline.xAtTime(timeline, timeMax) + + ctx.fillStyle = prefs.timeline.selectionBkgColor + ctx.fillRect(x1, y1, x2 - x1, y2 - y1) +} \ No newline at end of file diff --git a/src/timeline/index.ts b/src/timeline/index.ts index 924bf5f..67ee95d 100644 --- a/src/timeline/index.ts +++ b/src/timeline/index.ts @@ -1,18 +1,12 @@ -export * from "./state" -export * from "./state_keyDown" -export * from "./state_keyUp" -export * from "./state_mouseMove" -export * from "./state_mouseDown" -export * from "./state_mouseUp" -export * from "./state_mouseDrag" -export * from "./state_mouseWheel" -export * from "./state_render" -export * from "./track" -export * from "./trackKeyChanges" -export * from "./trackMeterChanges" -export * from "./trackNoteBlocks" -export * from "./trackChords" -export * from "./trackNotes" -export * from "./trackNoteVolumes" -export * from "./trackNoteVelocities" -export * from "./Element" \ No newline at end of file +export * from "./Element.tsx" +export * from "./timeline.ts" +export * from "./layout.ts" +export * from "./layout_notes.ts" +export * from "./mouse_move.ts" +export * from "./mouse_down.ts" +export * from "./mouse_drag.ts" +export * from "./mouse_up.ts" +export * from "./mouse_wheel.ts" +export * from "./key_down.ts" +export * from "./key_up.ts" +export * from "./draw.ts" \ No newline at end of file diff --git a/src/timeline/key_down.ts b/src/timeline/key_down.ts new file mode 100644 index 0000000..3f0bba4 --- /dev/null +++ b/src/timeline/key_down.ts @@ -0,0 +1,9 @@ +import * as Timeline from "./index.ts" + + +export function keyDown( + timeline: Timeline.State, + key: string) +{ + timeline.keysDown.add(key) +} \ No newline at end of file diff --git a/src/timeline/key_up.ts b/src/timeline/key_up.ts new file mode 100644 index 0000000..3a71593 --- /dev/null +++ b/src/timeline/key_up.ts @@ -0,0 +1,9 @@ +import * as Timeline from "./index.ts" + + +export function keyUp( + timeline: Timeline.State, + key: string) +{ + timeline.keysDown.delete(key) +} \ No newline at end of file diff --git a/src/timeline/layout.ts b/src/timeline/layout.ts new file mode 100644 index 0000000..4ac9209 --- /dev/null +++ b/src/timeline/layout.ts @@ -0,0 +1,222 @@ +import * as Project from "../project" +import * as Timeline from "./index.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" + + +export interface LayoutElementCommon +{ + id?: Project.ID + action?: Timeline.MouseAction + rect: Rect + priority?: number + subElements?: LayoutElement[] +} + + +export interface LayoutElementHidden extends LayoutElementCommon +{ + kind: "hidden" +} + + +export interface LayoutElementLaneCommon extends LayoutElementCommon +{ + laneIndex: number + iterElementsAtRegion?: ( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range, + verticalRegion?: { y1: number, y2: number }) + => Generator +} + + +export interface LayoutElementLaneMarkers extends LayoutElementLaneCommon +{ + kind: "lane" +} + + +export interface LayoutElementLaneNotes extends LayoutElementLaneCommon +{ + kind: "laneNotes" +} + + +export interface LayoutElementNote extends LayoutElementCommon +{ + kind: "note" +} + + +export type LayoutElement = + LayoutElementHidden | + LayoutElementLaneMarkers | + LayoutElementLaneNotes | + LayoutElementNote + + +export type LayoutLane = + LayoutElementLaneMarkers | + LayoutElementLaneNotes + + +export interface KeyRegion +{ + keyCh1: Project.KeyChange + keyCh2: Project.KeyChange + x1: number + x2: number +} + + +export class Layout +{ + range: Range + lanes: LayoutLane[] = [] + elements: LayoutElement[] = [] + elementCount: number = 0 + laneNotes?: LayoutElementLaneNotes + + measures: Project.Measure[] = [] + keyRegions: KeyRegion[] = [] + + + constructor() + { + + } + + + add(parent: LayoutElement | undefined, elem: LayoutElement) + { + this.elementCount++ + + if (parent !== undefined) + { + if (parent.subElements === undefined) + parent.subElements = [] + + parent.subElements.push(elem) + } + else + { + this.elements.push(elem) + + if (elem.kind === "lane" || + elem.kind === "laneNotes") + this.lanes.push(elem) + } + } +} + + +export function layout( + timeline: Timeline.State, + project: Project.ImmutableRoot) +{ + const layout = new Layout() + layout.range = Timeline.visibleTimeRange(timeline) + layout.measures = [...Project.iterMeasuresAtRange(project, layout.range)] + layout.keyRegions = [...iterKeyChangePairsAtRange(timeline, project, layout.range)] + + + const laneMarkerH = 32 + const laneChordH = 60 + const laneMarginH = 8 + + const laneKeyChanges: LayoutElementLaneMarkers = { + kind: "lane", + laneIndex: 0, + rect: new Rect( + 0, + 0, + timeline.renderRect.w, + laneMarkerH), + } + + const laneMeterChanges: LayoutElementLaneMarkers = { + kind: "lane", + laneIndex: 1, + rect: new Rect( + 0, + laneMarkerH + laneMarginH, + timeline.renderRect.w, + laneMarkerH), + } + + const laneChords: LayoutElementLaneMarkers = { + kind: "lane", + laneIndex: 2, + rect: new Rect( + 0, + laneMarkerH + laneMarginH + + laneMarkerH + laneMarginH, + timeline.renderRect.w, + laneChordH), + } + + const laneNotesY = + laneMarkerH + laneMarginH + + laneMarkerH + laneMarginH + + laneChordH + laneMarginH + + const laneNotes: LayoutElementLaneNotes = { + kind: "laneNotes", + laneIndex: 3, + rect: new Rect( + 0, + laneNotesY, + timeline.renderRect.w, + timeline.renderRect.h - laneNotesY), + } + + layout.add(undefined, laneKeyChanges) + layout.add(undefined, laneMeterChanges) + layout.add(undefined, laneChords) + layout.add(undefined, laneNotes) + layout.laneNotes = laneNotes + + Timeline.layoutLaneNotes(timeline, project, layout, laneNotes) + + timeline.layout = layout + console.log(layout.elementCount, layout) +} + + +function *iterKeyChangePairsAtRange( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const keyChangeTrackId = Project.keyChangeTrackId(project) + const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId) + if (!keyChangeTrackTimedElems) + return + + const firstKeyCh = keyChangeTrackTimedElems.findFirst() as (Project.KeyChange | null) + const defaultKey = firstKeyCh?.key ?? Project.defaultKey() + + for (const pair of keyChangeTrackTimedElems.iterActiveAtRangePairwise(range)) + { + const keyCh1 = + pair[0] as Project.KeyChange ?? + Project.makeKeyChange(-1, range.start, defaultKey) + + const keyCh2 = + pair[1] as Project.KeyChange ?? + Project.makeKeyChange(-1, range.end, defaultKey) + + const x1 = Timeline.xAtTime(timeline, keyCh1.range.start) + const x2 = Timeline.xAtTime(timeline, keyCh2.range.start) + + yield { + keyCh1, + keyCh2, + x1, + x2, + } + } +} \ No newline at end of file diff --git a/src/timeline/layout_notes.ts b/src/timeline/layout_notes.ts new file mode 100644 index 0000000..3b1c490 --- /dev/null +++ b/src/timeline/layout_notes.ts @@ -0,0 +1,211 @@ +import * as Project from "../project" +import * as Theory from "../theory" +import * as Timeline from "./index.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" + + +export function layoutLaneNotes( + timeline: Timeline.State, + project: Project.ImmutableRoot, + layout: Timeline.Layout, + laneNotes: Timeline.LayoutElementLaneNotes) +{ + laneNotes.iterElementsAtRegion = (timeline, project, range, verticalRegion) => + iterNotesAtRegion(timeline, project, laneNotes, range, verticalRegion) + + for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, layout)) + { + const key = keyChPair.keyCh1.key + const row = rowForPitch(note.midiPitch, key) + + const [rect, cutStart, cutEnd] = rectForNote( + timeline, + laneNotes, + note.range, + row, + keyChPair.x1, + keyChPair.x2, + true) + + if (!cutStart) + { + const rectStretchStart = rect.withX1(rect.x1 - 8) + layout.add(laneNotes, { + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rectStretchStart, + }) + } + + if (!cutEnd) + { + const rectStretchEnd = rect.withX2(rect.x2 + 8) + layout.add(laneNotes, { + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rectStretchEnd, + }) + } + + layout.add(laneNotes, { + kind: "note", + id: note.id, + action: Timeline.MouseAction.DragTimeAndRow, + rect, + priority: 1, + }) + } +} + + +function *iterNotesAndKeyChanges( + timeline: Timeline.State, + project: Project.ImmutableRoot, + layout: Timeline.Layout) + : Generator<[Project.Note, Timeline.KeyRegion], void, void> +{ + for (const keyRegion of layout.keyRegions) + { + const time1 = keyRegion.keyCh1.range.start.max(layout.range.start) + const time2 = keyRegion.keyCh2.range.start.min(layout.range.end) + + for (const note of iterNotes(timeline, project, new Range(time1, time2))) + yield [note, keyRegion] + } +} + + +function *iterNotes( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const list = project.lists.get(project.noteTrackId) + if (!list) + return + + for (const elem of list.iterAtRange(range)) + yield elem as Project.Note +} + + +export function rowForPitch( + pitch: number, + key: Theory.Key) + : number +{ + const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) + return key.octavedDegreeForMidi(pitch - Theory.Utils.midiMiddleC) + tonicRowOffset +} + + +export function pitchForRow( + row: number, + key: Theory.Key) + : number +{ + const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) + return key.midiForDegree(row - Math.floor(tonicRowOffset)) + Theory.Utils.midiMiddleC +} + + +export function yForRow( + timeline: Timeline.State, + lane: Timeline.LayoutElementLaneNotes, + row: number) + : number +{ + return lane.rect.y + + lane.rect.h / 2 - (row + 1) * timeline.noteRowH - timeline.yScroll +} + + +export function rowAtY( + timeline: Timeline.State, + lane: Timeline.LayoutElementLaneNotes, + y: number) + : number +{ + return -Math.floor((y - lane.rect.y + timeline.yScroll - lane.rect.h / 2) / timeline.noteRowH) - 1 +} + + +function rectForNote( + timeline: Timeline.State, + lane: Timeline.LayoutElementLaneNotes, + noteRange: Range, + noteRow: number, + keyChXStart: number, + keyChXEnd: number, + clampY: boolean) + : [Rect, boolean, boolean] +{ + const noteOrigX1 = Timeline.xAtTime(timeline, noteRange.start) + const noteOrigX2 = Timeline.xAtTime(timeline, noteRange.end) + + let noteY = 0.5 + Math.floor(yForRow(timeline, lane, noteRow)) + if (clampY) + { + noteY = + Math.max(lane.rect.y - timeline.noteRowH / 2, + Math.min(lane.rect.y + lane.rect.h - timeline.noteRowH / 2, + noteY)) + } + + let noteX1 = Math.max(noteOrigX1, keyChXStart) + let noteX2 = Math.min(noteOrigX2, keyChXEnd) + + const cutStart = noteOrigX1 < noteX1 + const cutEnd = noteOrigX2 > noteX2 + + //if (!cutStart) noteX1 += 1 + //if (!cutEnd) noteX2 -= 1 + + noteX1 = 0.5 + Math.floor(noteX1) + noteX2 = 0.5 + Math.floor(noteX2) + + const noteW = Math.max(2, noteX2 - noteX1) + + return [ + new Rect(noteX1, noteY, noteW, timeline.noteRowH), + cutStart, + cutEnd] +} + + +function *iterNotesAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + lane: Timeline.LayoutElementLaneNotes, + range: Range, + verticalRegion?: { y1: number, y2: number }) + : Generator +{ + for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, timeline.layout)) + { + if (!note.range.overlapsRange(range)) + continue + + if (verticalRegion !== undefined) + { + const [rect] = rectForNote( + timeline, + lane, + note.range, + rowForPitch(note.midiPitch, keyChPair.keyCh1.key), + keyChPair.x1, + keyChPair.x2, + false) + + if (verticalRegion.y1 > rect.y2 || + verticalRegion.y2 < rect.y1) + continue + } + + yield note.id + } +} \ No newline at end of file diff --git a/src/timeline/mouse_down.ts b/src/timeline/mouse_down.ts new file mode 100644 index 0000000..d845090 --- /dev/null +++ b/src/timeline/mouse_down.ts @@ -0,0 +1,121 @@ +import * as Timeline from "./index.ts" +import * as Project from "../project" +import * as Prefs from "../prefs.ts" +import Rect from "../utils/rect.ts" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" + + +export function mouseDown( + timeline: Timeline.State, + project: Project.ImmutableRoot, + prefs: Prefs.Prefs, + rightButton: boolean) +{ + if (timeline.mouse.down) + return + + const prevDownDate = timeline.mouse.downDate + + timeline.mouse.down = true + timeline.mouse.downDate = new Date() + timeline.mouse.action = Timeline.MouseAction.None + + const selectMultiple = + timeline.keysDown.has(prefs.timeline.keySelectMultiple) + const selectRange = + timeline.keysDown.has(prefs.timeline.keySelectRange) + const selectClone = + timeline.keysDown.has(prefs.timeline.keySelectClone) + const selectRect = + timeline.keysDown.has(prefs.timeline.keySelectRect) + const forcePan = + timeline.keysDown.has(prefs.timeline.keyPan) + const doubleClick = + timeline.mouse.downDate.getTime() - prevDownDate.getTime() < + prefs.timeline.mouseDoubleClickThresholdMs + + timeline.drag = + { + origin: + { + point: { ...timeline.mouse.point }, + range: null, + timeScroll: timeline.timeScroll, + yScroll: timeline.yScroll, + project, + }, + + xLocked: true, + yLocked: true, + posDelta: { x: 0, y: 0 }, + timeDelta: new Rational(0), + rowDelta: 0, + trackDelta: 0, + trackInsertionBefore: -1, + + elemId: -1, + notePreviewLast: null, + } + + if (rightButton || forcePan) + { + timeline.mouse.action = Timeline.MouseAction.Pan + return + } + + + const hoverIsSelected = + timeline.hover !== undefined && + timeline.hover.id !== undefined && + timeline.selection.has(timeline.hover.id) + + + if (!selectMultiple && !hoverIsSelected) + Timeline.selectionClear(timeline) + + + if (timeline.hover === undefined || + timeline.hover.action === undefined) + { + timeline.mouse.action = Timeline.MouseAction.SelectCursor + + timeline.cursor.visible = true//!selectRect + Timeline.cursorSetTime(timeline, timeline.mouse.point.time, timeline.mouse.point.time) + + timeline.cursor.rectY1 = timeline.cursor.rectY2 = + timeline.mouse.point.trackPos.y + + timeline.cursor.laneIndex1 = timeline.cursor.laneIndex2 = + timeline.mouse.point.laneIndex + + /*if (doubleClick) + { + const anchor = Timeline.findPreviousAnchor( + timeline, timeline.mouse.point.time, + timeline.mouse.point.trackIndex, timeline.mouse.point.trackIndex) + + Timeline.cursorSetTime(timeline, anchor, anchor) + Timeline.scrollTimeIntoView(timeline, anchor) + }*/ + + return + } + + if (timeline.hover !== undefined) + { + timeline.cursor.visible = false + + if (!hoverIsSelected) + Timeline.selectionToggle( + timeline, + project, + timeline.hover) + + timeline.drag.origin.range = + Timeline.selectionRange(timeline, project) + + timeline.mouse.action = timeline.hover.action + return + } +} \ No newline at end of file diff --git a/src/timeline/mouse_drag.ts b/src/timeline/mouse_drag.ts new file mode 100644 index 0000000..ded96c9 --- /dev/null +++ b/src/timeline/mouse_drag.ts @@ -0,0 +1,194 @@ +import * as Project from "../project" +import * as Timeline from "./index.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" + + +export function mouseDrag( + timeline: Timeline.State, + project: Project.Mutable) + : boolean +{ + if (!timeline.mouse.down) + return false + + timeline.mouse.pointPrev = timeline.mouse.point + timeline.mouse.point = Timeline.pointAt( + timeline, + timeline.mouse.point.pos.x, + timeline.mouse.point.pos.y) + + timeline.drag.posDelta = + { + x: timeline.mouse.point.pos.x - timeline.drag.origin.point.pos.x, + y: timeline.mouse.point.pos.y - timeline.drag.origin.point.pos.y, + } + + timeline.drag.timeDelta = + timeline.mouse.point.time.subtract(timeline.drag.origin.point.time) + + timeline.drag.rowDelta = + timeline.mouse.point.row - timeline.drag.origin.point.row + + timeline.drag.xLocked = + timeline.drag.xLocked && + Math.abs(timeline.drag.posDelta.x) < 10 + + timeline.drag.yLocked = + timeline.drag.yLocked && + Math.abs(timeline.drag.posDelta.y) < 10 + + + if (timeline.mouse.action === Timeline.MouseAction.Pan) + return handlePanning(timeline, project) + + else if (timeline.mouse.action === Timeline.MouseAction.SelectCursor) + return handleSelectCursor(timeline, project) + + else + return handleDragElements(timeline, project) +} + + +function handlePanning( + timeline: Timeline.State, + project: Project.Mutable) + : boolean +{ + timeline.timeScroll = + timeline.drag.origin.timeScroll - + (timeline.drag.posDelta.x / timeline.timeScale) + + timeline.yScroll = + timeline.drag.origin.yScroll - + timeline.drag.posDelta.y + + return true +} + + +function handleSelectCursor( + timeline: Timeline.State, + project: Project.Mutable) + : boolean +{ + timeline.cursor.time2 = timeline.mouse.point.time + timeline.cursor.laneIndex2 = timeline.mouse.point.laneIndex + + Timeline.selectionClear(timeline) + Timeline.selectionAddAtCursor(timeline, project.root) + return true +} + + +function handleDragElements( + timeline: Timeline.State, + project: Project.Mutable) + : boolean +{ + let action = timeline.mouse.action + + if (timeline.drag.xLocked) + { + if (action === Timeline.MouseAction.DragTime || + action === Timeline.MouseAction.StretchTimeStart || + action === Timeline.MouseAction.StretchTimeEnd) + action = Timeline.MouseAction.None + + else if (action === Timeline.MouseAction.DragTimeAndRow) + action = Timeline.MouseAction.DragRow + } + + if (timeline.drag.yLocked) + { + if (action === Timeline.MouseAction.DragTimeAndRow) + action = Timeline.MouseAction.DragTime + + else if (action === Timeline.MouseAction.DragRow) + action = Timeline.MouseAction.None + } + + + const origProject = timeline.drag.origin.project + let newProject = origProject + + for (const id of timeline.selection) + { + const elem = origProject.elems.get(id) + if (!elem) + continue + + if (elem.type === "track") + continue + + const changes: Partial = {} + + if (action == Timeline.MouseAction.DragTime || + action == Timeline.MouseAction.DragTimeAndRow) + { + changes.range = elem.range + .displace(timeline.drag.timeDelta) + .quantize(Project.MAX_RATIONAL_DENOMINATOR) + } + + + if (action == Timeline.MouseAction.StretchTimeStart && + timeline.drag.origin.range) + { + changes.range = Project.getAbsoluteRange(origProject, elem.parentId, elem.range) + changes.range = changes.range.stretch( + timeline.drag.timeDelta, + timeline.drag.origin.range.end, + timeline.drag.origin.range.start) + + if (elem.range.start.compare(timeline.drag.origin.range.start) == 0) + changes.range = new Range( + changes.range.start.snap(timeline.timeSnap), + changes.range.end) + .quantize(Project.MAX_RATIONAL_DENOMINATOR) + + changes.range = changes.range.sorted() + changes.range = Project.getRelativeRange(origProject, elem.parentId, changes.range) + } + + + if (action == Timeline.MouseAction.StretchTimeEnd && + timeline.drag.origin.range) + { + changes.range = Project.getAbsoluteRange(origProject, elem.parentId, elem.range) + changes.range = changes.range.stretch( + timeline.drag.timeDelta, + timeline.drag.origin.range.start, + timeline.drag.origin.range.end) + + if (elem.range.end.compare(timeline.drag.origin.range.end) == 0) + changes.range = new Range( + changes.range.start, + changes.range.end.snap(timeline.timeSnap)) + .quantize(Project.MAX_RATIONAL_DENOMINATOR) + + changes.range = changes.range.sorted() + changes.range = Project.getRelativeRange(origProject, elem.parentId, changes.range) + } + + + if ((action == Timeline.MouseAction.DragRow || + action == Timeline.MouseAction.DragTimeAndRow) && + elem.type === "note") + { + const note = elem as Project.Note + const trackId = project.root.noteTrackId + const key = Project.keyAt(project.root, trackId, note.range.start) + const degree = key.octavedDegreeForMidi(note.midiPitch) + const newPitch = key.midiForDegree(Math.floor(degree + timeline.drag.rowDelta)) + changes.midiPitch = newPitch + } + + newProject = Project.upsertElement( + newProject, + Project.elemModify(elem, changes)) + } + + project.root = newProject + return newProject !== origProject +} \ No newline at end of file diff --git a/src/timeline/mouse_move.ts b/src/timeline/mouse_move.ts new file mode 100644 index 0000000..04cb6e8 --- /dev/null +++ b/src/timeline/mouse_move.ts @@ -0,0 +1,44 @@ +import * as Project from "../project" +import * as Timeline from "./index.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" + + +export function mouseMove( + timeline: Timeline.State, + project: Project.ImmutableRoot, + x: number, + y: number) +{ + timeline.mouse.point = Timeline.pointAt(timeline, x, y) + + if (!timeline.mouse.down) + { + timeline.hover = undefined + hoverRecursive(timeline, timeline.layout.elements, x, y) + } +} + + +function hoverRecursive( + timeline: Timeline.State, + elements: Timeline.LayoutElement[], + x: number, + y: number) +{ + for (const elem of elements) + { + if (x >= elem.rect.x && + x < elem.rect.x + elem.rect.w && + y >= elem.rect.y && + y < elem.rect.y + elem.rect.h) + { + if (timeline.hover === undefined || + (elem.priority ?? 0) >= (timeline.hover.priority ?? 0)) + timeline.hover = elem + + if (elem.subElements) + hoverRecursive(timeline, elem.subElements, x, y) + } + } +} \ No newline at end of file diff --git a/src/timeline/mouse_up.ts b/src/timeline/mouse_up.ts new file mode 100644 index 0000000..d1dd80f --- /dev/null +++ b/src/timeline/mouse_up.ts @@ -0,0 +1,18 @@ +import * as Project from "../project" +import * as Timeline from "./index.ts" +import Rect from "../utils/rect.ts" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" + + +export function mouseUp( + timeline: Timeline.State, + project: Project.ImmutableRoot, + rightButton: boolean) +{ + if (!timeline.mouse.down) + return + + timeline.mouse.down = false + timeline.mouse.action = Timeline.MouseAction.None +} \ No newline at end of file diff --git a/src/timeline/mouse_wheel.ts b/src/timeline/mouse_wheel.ts new file mode 100644 index 0000000..853699e --- /dev/null +++ b/src/timeline/mouse_wheel.ts @@ -0,0 +1,49 @@ +import * as Timeline from "./index.ts" +import Rational from "../utils/rational.ts" + + +export function mouseWheel( + timeline: Timeline.State, + deltaX: number, + deltaY: number) +{ + if (Math.abs(deltaX) > 0) + { + timeline.timeScroll = timeline.timeScroll + 0.01 / (timeline.timeScale / 100) * deltaX + timeline.mouse.wheelDate = new Date() + } + else if (new Date().getTime() - timeline.mouse.wheelDate.getTime() > 250) + { + const snap = new Rational(1, 1024) + const prevMouseTime = Timeline.timeAtX( + timeline, + timeline.mouse.point.pos.x, + snap) + + let newTimeScale = timeline.timeScale * (deltaY > 0 ? 0.8 : 1.25) + newTimeScale = Math.max(4, Math.min(2048, newTimeScale)) + timeline.timeScale = newTimeScale + + const newMouseTime = Timeline.timeAtX( + timeline, + timeline.mouse.point.pos.x, + snap) + + const newTimeScroll = timeline.timeScroll - newMouseTime.subtract(prevMouseTime).asFloat() + + const timeSnapAdjustThresholdUpper = 24 + const timeSnapAdjustThresholdLower = 8 + let newTimeSnap = timeline.timeSnapBase + + if (newTimeSnap.asFloat() * newTimeScale > timeSnapAdjustThresholdUpper) + while (newTimeSnap.asFloat() * newTimeScale > timeSnapAdjustThresholdUpper) + newTimeSnap = newTimeSnap.divide(new Rational(2)) + + else if (newTimeSnap.asFloat() * newTimeScale < timeSnapAdjustThresholdLower) + while (newTimeSnap.asFloat() * newTimeScale < timeSnapAdjustThresholdLower) + newTimeSnap = newTimeSnap.divide(new Rational(1, 2)) + + timeline.timeScroll = newTimeScroll + timeline.timeSnap = newTimeSnap + } +} \ No newline at end of file diff --git a/src/timeline/timeline.ts b/src/timeline/timeline.ts new file mode 100644 index 0000000..1739cff --- /dev/null +++ b/src/timeline/timeline.ts @@ -0,0 +1,440 @@ +import Immutable from "immutable" +import * as Project from "../project" +import * as Timeline from "./index.ts" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" +import Rect from "../utils/rect.ts" + + +export interface State +{ + pixelRatio: number + renderRect: Rect + + trackMeasuresH: number + trackControlX: number + trackControlY: number + trackControlSize: number + + layout: Timeline.Layout + hover: Timeline.LayoutElement | undefined + + yScroll: number + timeScroll: number + timeScale: number + timeSnap: Rational + timeSnapBase: Rational + + noteRowH: number + + cursor: + { + visible: boolean + time1: Rational + time2: Rational + laneIndex1: number + laneIndex2: number + rectY1: number + rectY2: number + } + + keysDown: Set, + + mouse: + { + down: boolean + downDate: Date + + action: MouseAction + + point: Point + pointPrev: Point + + wheelDate: Date + } + + drag: + { + origin: + { + point: Point + range: Range | null + timeScroll: number + yScroll: number + project: Project.ImmutableRoot + } + + xLocked: boolean + yLocked: boolean + + posDelta: { x: number, y: number } + timeDelta: Rational + rowDelta: number + trackDelta: number + trackInsertionBefore: number + + elemId: Project.ID + notePreviewLast: number | null + } + + insertion: + { + nearMidiPitch: number + duration: Rational + } + + selection: Immutable.Set + + needsKeyFinish: boolean + rangeSelectOriginTrackIndex: number +} + + +export enum MouseAction +{ + None, + Pan, + DragTime, + DragRow, + DragTimeAndRow, + StretchTimeStart, + StretchTimeEnd, + SelectCursor, +} + + +export interface Point +{ + pos: { x: number, y: number } + time: Rational + row: number + laneIndex: number + trackPos: { x: number, y: number } + originTrackPos: { x: number, y: number } +} + + +export interface HoverData +{ + id: Project.ID + range: Range + action: MouseAction +} + + + +export function makeNew(): State +{ + return { + pixelRatio: 1, + renderRect: new Rect(0, 0, 0, 0), + + trackMeasuresH: 20, + trackControlX: 10, + trackControlY: 25, + trackControlSize: 20, + + layout: new Timeline.Layout(), + hover: undefined, + + yScroll: 0, + timeScroll: -2.5, + timeScale: 100, + timeSnap: new Rational(1, 8), + timeSnapBase: new Rational(1, 16), + + noteRowH: 16, + + cursor: + { + visible: true, + time1: new Rational(0), + time2: new Rational(0), + laneIndex1: 0, + laneIndex2: 0, + rectY1: 0, + rectY2: 0, + }, + + keysDown: new Set(), + + mouse: + { + down: false, + downDate: new Date(), + + action: MouseAction.None, + + point: + { + pos: { x: 0, y: 0 }, + time: new Rational(0), + row: 0, + laneIndex: 0, + trackPos: { x: 0, y: 0 }, + originTrackPos: { x: 0, y: 0 }, + }, + + pointPrev: + { + pos: { x: 0, y: 0 }, + time: new Rational(0), + row: 0, + laneIndex: 0, + trackPos: { x: 0, y: 0 }, + originTrackPos: { x: 0, y: 0 }, + }, + + wheelDate: new Date(), + }, + + drag: + { + origin: null!, + xLocked: true, + yLocked: true, + posDelta: { x: 0, y: 0 }, + timeDelta: new Rational(0), + rowDelta: 0, + trackDelta: 0, + trackInsertionBefore: -1, + + elemId: -1, + notePreviewLast: null, + }, + + insertion: + { + nearMidiPitch: 60, + duration: new Rational(1, 4), + }, + + selection: Immutable.Set(), + + needsKeyFinish: false, + rangeSelectOriginTrackIndex: -1, + } +} + + +export function resize( + state: State, + pixelRatio: number, + rect: Rect) +{ + state.pixelRatio = pixelRatio + state.renderRect = rect +} + + +export function xAtTime( + timeline: Timeline.State, + time: Rational) + : number +{ + return (time.asFloat() - timeline.timeScroll) * timeline.timeScale +} + + +export function timeAtX( + timeline: Timeline.State, + x: number, + timeSnap?: Rational) + : Rational +{ + timeSnap = timeSnap || timeline.timeSnap + const time = x / timeline.timeScale + timeline.timeScroll + return Rational.fromFloat(time, timeSnap.denominator) +} + + +export function timeRangeAtX( + timeline: Timeline.State, + x1: number, + x2: number, + timeSnap?: Rational) + : Range +{ + timeSnap = timeSnap || timeline.timeSnap + return new Range( + timeAtX(timeline, x1, timeSnap).subtract(timeSnap), + timeAtX(timeline, x2, timeSnap).add(timeSnap)) +} + + +export function visibleTimeRange( + timeline: Timeline.State) + : Range +{ + return new Range( + timeAtX(timeline, 0).subtract(timeline.timeSnap), + timeAtX(timeline, timeline.renderRect.w).add(timeline.timeSnap)) +} + + +export function laneIndexAtY( + timeline: Timeline.State, + y: number) + : number +{ + if (y < 0) + return -1 + + for (let i = 0; i < timeline.layout.lanes.length; i++) + { + const lane = timeline.layout.lanes[i] + + if (y < lane.rect.y2) + return i + } + + return timeline.layout.lanes.length +} + + +export function pointAt( + timeline: Timeline.State, + x: number, + y: number) + : Point +{ + const time = timeAtX(timeline, x) + + const row = timeline.layout.laneNotes ? + Timeline.rowAtY(timeline, timeline.layout.laneNotes, y) : + 0 + + const laneIndex = laneIndexAtY(timeline, y) + + /*const trackPosY = pos.y - trackY(state, state.mouse.point.trackIndex) + const trackPos = { x: pos.x, y: trackPosY } + + + let originTrackPos = trackPos + if (state.drag.origin) + { + const originTrackPosY = pos.y - trackY(state, state.drag.origin.point.trackIndex) + originTrackPos = { x: pos.x, y: originTrackPosY } + }*/ + + return { + pos: { x, y }, + time, + laneIndex, + trackPos: { x: 0, y: 0 }, + row, + originTrackPos: { x: 0, y: 0 }, + } +} + + +export function selectionClear( + timeline: Timeline.State) +{ + timeline.selection = timeline.selection.clear() +} + + +export function selectionRange( + state: Timeline.State, + project: Project.ImmutableRoot) + : Range | null +{ + return Project.getRangeForElems(project, state.selection) +} + + +export function selectionToggle( + timeline: Timeline.State, + project: Project.ImmutableRoot, + element: Timeline.LayoutElement) +{ + if (element.id === undefined || + element.action === undefined) + return + + const alreadySelected = timeline.selection.has(element.id) + + if (!alreadySelected) + timeline.selection = timeline.selection.add(element.id) + else + timeline.selection = timeline.selection.remove(element.id) +} + + +export function selectionAdd( + timeline: Timeline.State, + id: Project.ID) +{ + timeline.selection = timeline.selection.add(id) +} + + +export function selectionAddAtCursor( + timeline: Timeline.State, + project: Project.ImmutableRoot, + verticalRegion?: { y1: number, y2: number }) +{ + const time1 = timeline.cursor.time1 + const time2 = timeline.cursor.time2 + if (time1.compare(time2) === 0) + return + + const range = new Range(time1, time2, false, false).sorted() + + const laneIndexMin = cursorGetLaneIndexMin(timeline) + const laneIndexMax = cursorGetLaneIndexMax(timeline) + + for (let l = laneIndexMin; l <= laneIndexMax; l++) + { + const lane = timeline.layout.lanes[l] + if (lane.iterElementsAtRegion === undefined) + continue + + for (const id of lane.iterElementsAtRegion(timeline, project, range, verticalRegion)) + selectionAdd(timeline, id) + } +} + + +export function cursorSetTime( + timeline: Timeline.State, + time1: Rational | null, + time2?: Rational | null) +{ + timeline.cursor.time1 = time1 ?? timeline.cursor.time1 + timeline.cursor.time2 = time2 ?? timeline.cursor.time2 +} + + +export function cursorSetTrack( + timeline: Timeline.State, + trackIndex1: number | null, + trackIndex2?: number | null) +{ + timeline.cursor.laneIndex1 = + Math.max(0, Math.min(timeline.layout.lanes.length - 1, + trackIndex1 ?? timeline.cursor.laneIndex1)) + + timeline.cursor.laneIndex2 = + Math.max(0, Math.min(timeline.layout.lanes.length - 1, + trackIndex2 ?? timeline.cursor.laneIndex2)) +} + + +export function cursorGetLaneIndexMin( + timeline: Timeline.State) +{ + return Math.max(0, Math.min( + timeline.cursor.laneIndex1, + timeline.cursor.laneIndex2)) +} + + +export function cursorGetLaneIndexMax( + timeline: Timeline.State) +{ + return Math.min(timeline.layout.lanes.length - 1, Math.max( + timeline.cursor.laneIndex1, + timeline.cursor.laneIndex2)) +} \ No newline at end of file diff --git a/src/util/binarySearch.ts b/src/utils/binarySearch.ts similarity index 100% rename from src/util/binarySearch.ts rename to src/utils/binarySearch.ts diff --git a/src/util/listOfPoints.ts b/src/utils/listOfPoints.ts similarity index 98% rename from src/util/listOfPoints.ts rename to src/utils/listOfPoints.ts index 0b82697..1b0e3a5 100644 --- a/src/util/listOfPoints.ts +++ b/src/utils/listOfPoints.ts @@ -1,8 +1,8 @@ -import Rational from "./rational" -import Range from "./range" -import BinarySearch from "./binarySearch" -import Immutable from "immutable" import assert from "assert" +import Immutable from "immutable" +import Rational from "./rational.ts" +import Range from "./range.ts" +import BinarySearch from "./binarySearch.ts" interface Element diff --git a/src/util/listOfRanges.ts b/src/utils/listOfRanges.ts similarity index 99% rename from src/util/listOfRanges.ts rename to src/utils/listOfRanges.ts index d322036..0651303 100644 --- a/src/util/listOfRanges.ts +++ b/src/utils/listOfRanges.ts @@ -1,8 +1,8 @@ -import Rational from "./rational" -import Range from "./range" -import BinarySearch from "./binarySearch" -import Immutable from "immutable" import assert from "assert" +import Immutable from "immutable" +import Rational from "./rational.ts" +import Range from "./range.ts" +import BinarySearch from "./binarySearch.ts" interface Element diff --git a/src/util/mathUtils.ts b/src/utils/mathUtils.ts similarity index 100% rename from src/util/mathUtils.ts rename to src/utils/mathUtils.ts diff --git a/src/util/midi.ts b/src/utils/midi.ts similarity index 98% rename from src/util/midi.ts rename to src/utils/midi.ts index ad32bb6..79d6fc4 100644 --- a/src/util/midi.ts +++ b/src/utils/midi.ts @@ -1,5 +1,5 @@ -import { BinaryReader } from "./binaryReader" -import { BinaryWriter } from "./binaryWriter" +import { BinaryReader } from "../../src_old/util/binaryReader" +import { BinaryWriter } from "../../src_old/util/binaryWriter" import Rational from "./rational" diff --git a/src/util/range.ts b/src/utils/range.ts similarity index 99% rename from src/util/range.ts rename to src/utils/range.ts index c74700c..303d257 100644 --- a/src/util/range.ts +++ b/src/utils/range.ts @@ -1,4 +1,4 @@ -import Rational from "./rational" +import Rational from "./rational.ts" export default class Range diff --git a/src/util/rational.ts b/src/utils/rational.ts similarity index 100% rename from src/util/rational.ts rename to src/utils/rational.ts diff --git a/src/util/rect.ts b/src/utils/rect.ts similarity index 100% rename from src/util/rect.ts rename to src/utils/rect.ts diff --git a/src_old/App.tsx b/src_old/App.tsx index 889d9bd..d5a96c4 100644 --- a/src_old/App.tsx +++ b/src_old/App.tsx @@ -1,153 +1,140 @@ import React from "react" -import Dockable from "./dockable/Dockable" -import * as DockableData from "./dockable/state" -import { EditorContent } from "./editor2/EditorContent" -import { AppState, AppReducer, ContentManager, AppManager } from "./AppState" -import { AppContext } from "./AppContext" -import EditorState from "./editor2/editor" -import Project from "./project/project2" -import Immutable from "immutable" -import Rect from "./util/rect" -import MenuBar from "./popup/MenuBar" -import Popup from "./popup/Popup" -import InspectorContent from "./editor2/InspectorContent" -import TrackInstrumentContent from "./editor2/TrackInstrumentContent" -import { usePlaybackController } from "./playback/PlaybackController" -import { useSoundfontLibrary } from "./playback/library" - - -const initialAppState = AppReducer.makeNew() - - -export default function App(props: {}) +import * as Dockable from "./dockable" +import * as Command from "./command" +import * as Project from "./project" +import * as Playback from "./playback" +import * as Prefs from "./prefs" +import * as Popup from "./popup" +import * as Menubar from "./menubar" +import * as UI from "./ui" +import { useRefState } from "./util/refState" +import PlaybackToolbar from "./PlaybackToolbar" +import MenuFile from "./MenuFile" +import MenuEdit from "./MenuEdit" +import MenuWindow from "./MenuWindow" +import "./types" + + +let initializedGlobals = false + + +export default function App() { - const rootRef = React.useRef(null) - - const [, setDummy] = React.useState(0) - const appStateRef = React.useRef(initialAppState) - const appDispatch = React.useCallback((newState: AppState) => + if (!initializedGlobals) { - //console.log(newState) - appStateRef.current = newState - setDummy(dummy => dummy + 1) + initializedGlobals = true + Prefs.initGlobal() + Project.initGlobal() + Playback.initGlobal() + Dockable.initGlobal() + Popup.initGlobal() + } - }, []) + Project.useGlobal() + Playback.useGlobal() + Dockable.useGlobal() + Popup.useGlobal() - const setDockableRoot = (newRoot: DockableData.State) => appDispatch({ - ...appStateRef.current, - dockableRoot: newRoot, - }) + const [version, setVersion] = React.useState("") + + React.useEffect(() => + { + ;(async () => + { + const versionFile = await fetch("build/build_version.txt") + const versionTxt = await versionFile.text() + if (versionTxt.startsWith("v0-")) + setVersion("v0." + versionTxt.match(".*?\-(.*?)\-")![1]) + })() - const appManager = new AppManager( - () => appStateRef.current, - (newState) => appStateRef.current = newState, - (newState) => appDispatch(newState)) + }, []) - const playbackController = usePlaybackController(appManager) - const soundfontLibrary = useSoundfontLibrary(appManager) React.useEffect(() => { - if (!rootRef.current) - return - - const onResize = () => + window.addEventListener("keydown", (ev: KeyboardEvent) => { - const elemRect = rootRef.current!.getBoundingClientRect() - - appDispatch({ - ...appStateRef.current, - dockableRect: new Rect( - elemRect.x, - elemRect.y, - elemRect.width, - elemRect.height), - }) - } + if (document.activeElement && document.activeElement.tagName == "INPUT") + return - onResize() - - window.addEventListener("resize", onResize) + const key = ev.key.toLowerCase() - return () => - { - window.removeEventListener("resize", onResize) - } + for (const command of Command.allCommands) + { + if (!command.shortcut) + continue - }, [rootRef.current]) + if (command.isShortcutAvailable && !command.isShortcutAvailable()) + continue + if (command.isAvailable && !command.isAvailable({})) + continue - return -
- - -
- - - - { !appStateRef.current.popup ? null : - + for (const shortcut of command.shortcut) + { + if (!!shortcut.ctrl !== ev.ctrlKey) + continue + + if (!!shortcut.shift !== ev.shiftKey) + continue + + if (key !== shortcut.key) + continue + + //console.log("handled keyboard command: ", command.name) + command.func({}) + ev.preventDefault() + ev.stopPropagation() + return + } } + }) - -
- -} + }, []) -function contentTypeToComponent(type: string): any -{ - switch (type) - { - case "editor": return EditorContent - case "editorNotes": return EditorContent - case "inspector": return InspectorContent - case "trackInstrument": return TrackInstrumentContent + return <> +
- default: - throw "invalid content type" - } -} + + + + + + + How to use the app + + + { version } + + + + { !Playback.global.synthLoading ? null : + + } + -function contentTypeToTitle(type: string): any -{ - switch (type) - { - case "editor": return "Project" - case "editorNotes": return "Note Track" - case "inspector": return "Inspector" - case "trackInstrument": return "Instrument Select" +
- default: - throw "invalid content type" - } + { !Popup.global.elem ? null : + + } + } \ No newline at end of file diff --git a/src_old/AppContext.ts b/src_old/AppContext.ts deleted file mode 100644 index fc1b498..0000000 --- a/src_old/AppContext.ts +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react" -import { AppManager } from "./AppState" - - -interface AppContextProps -{ - appManager: AppManager -} - - -export const AppContext = React.createContext(null) - - -export function useAppManager(): AppManager -{ - return React.useContext(AppContext)!.appManager -} \ No newline at end of file diff --git a/src_old/AppState.ts b/src_old/AppState.ts deleted file mode 100644 index f322793..0000000 --- a/src_old/AppState.ts +++ /dev/null @@ -1,429 +0,0 @@ -import DockableData, * as Dock from "./dockable/state" -import Project from "./project/project2" -import Immutable from "immutable" -import Rect from "./util/rect" -import Editor from "./editor2/editor" -import Dockable from "./dockable/Dockable" -import Rational from "./util/rational" -import { SflibMeta } from "./playback/library" - - -export interface AppState -{ - contentIdNext: number - dockableRect: Rect - dockableRoot: Dock.State - dockableContents: Immutable.Map - - project: Project - selection: Immutable.Set - playback: - { - playing: boolean - time: Rational - timeAsFloat: number - timeStart: Rational - } - - sflib: SflibMeta - - popup: null | - { - rect: Rect - elem: any - props: any - } - - prefs: - { - editor: - { - bkgColor: string - trackVBorderColor: string - trackHBorderColor: string - - selectionCursorColor: string - selectionBkgColor: string - playbackCursorColor: string - trackSeparatorColor: string - - measureColor: string - submeasureColor: string - halfSubmeasureColor: string - measureAlternateBkgColor: string - - octaveDividerColor: string - noteRowAlternateBkgColor: string - - meterChangeColor: string - keyChangeColor: string - - keyPan: string - keyDraw: string - keySelectMultiple: string - keySelectRect: string - - mouseDragXLockedDistance: number - mouseDragYLockedDistance: number - - mouseEdgeScrollThreshold: number - mouseEdgeScrollSpeed: number - } - } -} - - -export class AppReducer -{ - static makeNew(): AppState - { - let root = DockableData.makeRoot() - root = DockableData.addPanel(root, 1, Dock.DockMode.Full, 1) - - return { - contentIdNext: 2, - dockableRect: new Rect(0, 0, 0, 0), - dockableRoot: root, - dockableContents: Immutable.Map() - .set(1, { - type: "editor", - state: Editor.makeNewFull(), - }), - - popup: null, - - project: Project.getDefault(), - selection: Immutable.Set(), - playback: { - playing: false, - time: new Rational(0), - timeAsFloat: 0, - timeStart: new Rational(0), - }, - - sflib: { - ready: false, - collections: [], - }, - - prefs: { - editor: { - bkgColor: "#000",//"#29242e", - trackVBorderColor: "#888", - trackHBorderColor: "#888", - - selectionCursorColor: "#0af", - selectionBkgColor: "#024", - playbackCursorColor: "#f00", - trackSeparatorColor: "#aaa", - - measureColor: "#444", - submeasureColor: "#222", - halfSubmeasureColor: "#111", - measureAlternateBkgColor: "#fff1", - - octaveDividerColor: "#444", - noteRowAlternateBkgColor: "#222",//"#19141e", - - meterChangeColor: "#0cf", - keyChangeColor: "#f0c", - - keyPan: " ", - keyDraw: "a", - keySelectMultiple: "control", - keySelectRect: "shift", - - mouseDragXLockedDistance: 10, - mouseDragYLockedDistance: 10, - - mouseEdgeScrollThreshold: 10, - mouseEdgeScrollSpeed: 1, - }, - }, - } - } - - - static merge(state: AppState, newState: Partial): AppState - { - return { - ...state, - ...newState, - } - } - - - static getContent(state: AppState, contentId: number): any - { - return state.dockableContents.get(contentId)!.state - } - - - static setContent(state: AppState, contentId: number, newState: any): AppState - { - return { - ...state, - dockableContents: state.dockableContents.set(contentId, - { - ...state.dockableContents.get(contentId)!, - state: newState, - }), - } - } - - - static mergeContent(state: AppState, contentId: number, newState: any): AppState - { - return AppReducer.setContent(state, contentId, { - ...AppReducer.getContent(state, contentId), - ...newState, - }) - } - - - static createTab(appState: AppState, nextToContentId: number, type: string, state: any): AppState - { - const panel = DockableData.findPanelWithContent(appState.dockableRoot.rootPanel, nextToContentId) - if (!panel) - return appState - - return { - ...appState, - contentIdNext: appState.contentIdNext + 1, - dockableRoot: DockableData.addPanel( - appState.dockableRoot, - panel.id, - Dock.DockMode.Full, - appState.contentIdNext), - dockableContents: appState.dockableContents.set(appState.contentIdNext, - { - type, - state, - }), - } - } - - - static createOrUpdateTab(appState: AppState, nextToContentId: number, type: string, state: any): AppState - { - const updatablePanel = DockableData.findPanelWithType(appState.dockableRoot.rootPanel, type, appState.dockableContents) - if (updatablePanel) - { - const contentId = updatablePanel.contentIds.find(c => appState.dockableContents.get(c)!.type == type)! - const contentIndex = updatablePanel.contentIds.findIndex(c => c == contentId) - - return { - ...appState, - dockableRoot: DockableData.modifyPanelFromRoot( - appState.dockableRoot, updatablePanel.id, (oldPanel) => - { - return { ...oldPanel, - curContent: contentIndex, - } - }), - dockableContents: appState.dockableContents.set(contentId, - { - type, - state, - }) - } - } - - const panel = DockableData.findPanelWithContent(appState.dockableRoot.rootPanel, nextToContentId) - if (!panel) - return appState - - return { - ...appState, - contentIdNext: appState.contentIdNext + 1, - dockableRoot: DockableData.addPanel( - appState.dockableRoot, - panel.id, - Dock.DockMode.Full, - appState.contentIdNext), - dockableContents: appState.dockableContents.set(appState.contentIdNext, - { - type, - state, - }), - } - } - - - static createFloating(appState: AppState, type: string, state: any, rect: Rect): AppState - { - return { - ...appState, - contentIdNext: appState.contentIdNext + 1, - dockableRoot: DockableData.addFloatingPanel( - appState.dockableRoot, - rect, - appState.contentIdNext), - dockableContents: appState.dockableContents.set(appState.contentIdNext, - { - type, - state, - }), - } - } - - - static removeFloating(appState: AppState, type: string): AppState - { - let root = appState.dockableRoot - for (const [key, value] of appState.dockableContents) - { - if (value.type === type) - root = DockableData.removeFloatingContent(root, key) - } - - return { - ...appState, - contentIdNext: appState.contentIdNext + 1, - dockableRoot: root, - } - } - - - static createPopup(appState: AppState, rect: Rect, elem: any, props: any): AppState - { - return { - ...appState, - popup: { - rect, - elem, - props, - } - } - } - - - static removePopup(appState: AppState): AppState - { - return { - ...appState, - popup: null, - } - } -} - - -export class AppManager -{ - getAppStateFn: () => AppState - setAppStateFn: (newState: AppState) => void - dispatchFn: (state: AppState) => void - - - constructor( - getAppState: () => AppState, - setAppState: (newState: AppState) => void, - dispatch: (state: AppState) => void) - { - this.getAppStateFn = getAppState - this.setAppStateFn = setAppState - this.dispatchFn = dispatch - } - - - get appState(): AppState - { - return this.getAppStateFn() - } - - - set appState(newState: AppState) - { - this.setAppStateFn(newState) - } - - - dispatch() - { - this.dispatchFn(this.appState) - } - - - mergeAppState(newState: Partial) - { - this.appState = { - ...this.appState, - ...newState, - } - } - - - makeContentManager(contentId: number) - { - return new ContentManager(this, contentId) - } -} - - -export class ContentManager -{ - appManager: AppManager - contentId: number - - - constructor(appManager: AppManager, contentId: number) - { - this.appManager = appManager - this.contentId = contentId - } - - - get appState(): AppState - { - return this.appManager.appState - } - - - set appState(newState: AppState) - { - this.appManager.appState = newState - } - - - dispatch() - { - this.appManager.dispatch() - } - - - mergeAppState(newState: Partial) - { - this.appManager.appState = { - ...this.appManager.appState, - ...newState, - } - } - - - get contentState(): T - { - return this.appManager.appState.dockableContents.get(this.contentId)!.state - } - - - set contentState(newState: T) - { - this.appManager.appState = { - ...this.appManager.appState, - dockableContents: this.appManager.appState.dockableContents.set(this.contentId, - { - ...this.appManager.appState.dockableContents.get(this.contentId)!, - state: newState, - }), - } - } - - - mergeContentState(newState: Partial) - { - this.contentState = { - ...this.contentState, - ...newState, - } - } -} \ No newline at end of file diff --git a/src/MenuEdit.tsx b/src_old/MenuEdit.tsx similarity index 100% rename from src/MenuEdit.tsx rename to src_old/MenuEdit.tsx diff --git a/src/MenuFile.tsx b/src_old/MenuFile.tsx similarity index 100% rename from src/MenuFile.tsx rename to src_old/MenuFile.tsx diff --git a/src/MenuWindow.tsx b/src_old/MenuWindow.tsx similarity index 100% rename from src/MenuWindow.tsx rename to src_old/MenuWindow.tsx diff --git a/src/PlaybackToolbar.tsx b/src_old/PlaybackToolbar.tsx similarity index 100% rename from src/PlaybackToolbar.tsx rename to src_old/PlaybackToolbar.tsx diff --git a/src/command/command.ts b/src_old/command/command.ts similarity index 100% rename from src/command/command.ts rename to src_old/command/command.ts diff --git a/src/command/convertNotesToChords.ts b/src_old/command/convertNotesToChords.ts similarity index 100% rename from src/command/convertNotesToChords.ts rename to src_old/command/convertNotesToChords.ts diff --git a/src/command/file.ts b/src_old/command/file.ts similarity index 100% rename from src/command/file.ts rename to src_old/command/file.ts diff --git a/src/command/history.ts b/src_old/command/history.ts similarity index 100% rename from src/command/history.ts rename to src_old/command/history.ts diff --git a/src/command/index.ts b/src_old/command/index.ts similarity index 100% rename from src/command/index.ts rename to src_old/command/index.ts diff --git a/src/command/playback.ts b/src_old/command/playback.ts similarity index 100% rename from src/command/playback.ts rename to src_old/command/playback.ts diff --git a/src/dockable/Container.tsx b/src_old/dockable/Container.tsx similarity index 100% rename from src/dockable/Container.tsx rename to src_old/dockable/Container.tsx diff --git a/src/dockable/_global.ts b/src_old/dockable/_global.ts similarity index 100% rename from src/dockable/_global.ts rename to src_old/dockable/_global.ts diff --git a/src/dockable/index.ts b/src_old/dockable/index.ts similarity index 100% rename from src/dockable/index.ts rename to src_old/dockable/index.ts diff --git a/src/dockable/state.ts b/src_old/dockable/state.ts similarity index 100% rename from src/dockable/state.ts rename to src_old/dockable/state.ts diff --git a/src_old/editor/editor.js b/src_old/editor/editor.js deleted file mode 100644 index 47904df..0000000 --- a/src_old/editor/editor.js +++ /dev/null @@ -1,1896 +0,0 @@ -import { default as Immutable } from "immutable" -import Track from "./track.js" -import Theory from "../theory.ts" -import Rational from "../util/rational.js" -import Range from "../util/range.js" -import Rect from "../util/rect.js" -import Project from "../project/project.js" -import MathUtils from "../util/math.js" - - -export default class Editor -{ - static actionPan = 0x01 - static actionSelectCursor = 0x02 - static actionSelectRect = 0x04 - static actionDraw = 0x08 - static actionDragTime = 0x10 - static actionDragPitchRow = 0x20 - static actionStretchTimeStart = 0x40 - static actionStretchTimeEnd = 0x80 - - static keyPan = " " - static keyDraw = "a" - static keySelectMultiple = "control" - static keySelectRect = "shift" - - - static reduce(state, action) - { - const shouldLog = ( - action.type !== "playbackStep" && - action.type !== "mouseMove" && - action.type !== "keyDown" && - action.type !== "keyUp" && - action.type !== "keyCommand" - ) - - if (shouldLog) - { - console.log("Editor.oldState", state) - console.log("Editor.action", action) - } - - const reducer = Editor["reduce_" + action.type] - - if (reducer) - { - const newState = reducer(state, action) - - if (shouldLog) - { - console.log("Editor.newState", newState) - console.log("") - } - - return newState - } - else - { - console.error("unhandled Editor.action", action) - return state - } - } - - - static reduce_init(state, action) - { - state = { - w: 0, - h: 0, - - tracks: [], - - timeSnap: new Rational(1, 16), - timeSnapBase: new Rational(1, 16), - timeScale: 200, - timeScroll: -1, - - insert: { - nearPitch: 60, - duration: new Rational(1, 4), - }, - - undoData: { - stack: [], - pointer: -1, - }, - - clipboard: { - elems: new Immutable.Map(), - }, - - playback: { - playing: false, - timeAsFloat: 0, - time: new Rational(0), - startTime: null, - }, - - cursor: { - visible: true, - time1: new Rational(0), - time2: new Rational(0), - track1: 0, - track2: 0, - }, - - rectSelection: null, - - mouse: { - down: false, - action: 0, - dragOrig: null, - drag: null, - x: 0, - y: 0, - xPrev: 0, - yPrev: 0, - hover: null, - draw: null, - lastDownDate: new Date(), - lastWheelDate: new Date(), - }, - - keys: {}, - pendingKeyCommandFinish: false, - - soundPreview: null, - soundPreviewPrev: null, - - prefs: - { - doubleClickThresholdMs: 250, - mouseEdgeScrollThreshold: 60, - mouseEdgeScrollSpeed: 1, - cursorEdgeScrollThreshold: new Rational(4), - cursorEdgeScrollSpeed: 16, - - backgroundColor: "#29242e", - selectionCursorColor: "#0af", - playbackCursorColor: "#f00", - trackSeparatorColor: "#aaa", - submeasureColor: "#0008", - halfSubmeasureColor: "#0002", - meterChangeColor: "#0cf", - keyChangeColor: "#f0c", - } - } - - state = Editor.refreshProjectRange(state) - return Editor.undoPointAdd(state) - } - - - static reduce_set(state, action) - { - state = { ...state, - ...action.state, - } - - return state - } - - - static reduce_resize(state, action) - { - state = { ...state, - w: action.w, - h: action.h, - tracks: [ ...state.tracks ], - } - - let trackY = 0 - for (let tr = 0; tr < state.tracks.length; tr++) - { - if (state.tracks[tr].kind == "notes") - state.tracks[tr] = { ...state.tracks[tr], rect: new Rect(0, trackY, state.w, state.h - trackY) } - else if (state.tracks[tr].kind == "chords") - state.tracks[tr] = { ...state.tracks[tr], rect: new Rect(0, trackY, state.w, 54) } - else - state.tracks[tr] = { ...state.tracks[tr], rect: new Rect(0, trackY, state.w, 44) } - - trackY += state.tracks[tr].rect.h - } - - return state - } - - - static reduce_projectSet(state, action) - { - state = Editor.undoPointAdd(state) - - state = { ...state, - project: action.project, - } - - return state - } - - - static reduce_projectLoad(state, action) - { - state = { ...state, - project: action.project, - } - - state = Editor.selectionClear(state) - state = Editor.reduce_clearUndoStack(state, {}) - state = Editor.reduce_rewind(state, {}) - state = Editor.reduce_playbackSet(state, { playing: false }) - return state - } - - - static reduce_rewind(state, action) - { - if (state.playback.playing) - { - state = Editor.reduce_playbackSet(state, { playing: true, time: state.project.range.start }) - } - else - { - state = Editor.Cursor.setVisible(state, true) - state = Editor.Cursor.place(state, state.project.range.start, null) - state = Editor.scrollTimeIntoView(state, state.project.range.start) - } - - return state - } - - - static reduce_trackAdd(state, action) - { - state = Track.handlerForTrackKind(action.kind).init(state, action) - state = Editor.Cursor.place(state, null, state.tracks.length - 1) - - return Editor.reduce_resize(state, { type: "resize", w: state.w, h: state.h }) - } - - - static reduce_playbackSet(state, action) - { - if (state.mouse.down) - state = Editor.reduce_mouseUp(state, {}) - - const time = action.time || state.playback.time - - state = { ...state, - playback: { ...state.playback, - playing: action.playing, - time, - timeAsFloat: time.asFloat(), - startTime: (action.playing ? time : null), - }, - } - - if (action.playing) - state = Editor.scrollPlaybackIntoView(state, time) - - return state - } - - - static reduce_playbackStep(state, action) - { - const timeAsFloat = action.timeAsFloat === null ? state.playback.timeAsFloat : action.timeAsFloat - const time = Rational.fromFloat(timeAsFloat, 1024) - - state = { ...state, - playback: { ...state.playback, - timeAsFloat, - time, - }, - } - - state = Editor.scrollPlaybackIntoView(state, time) - return state - } - - - static reduce_clearSoundPreview(state, action = {}) - { - let soundPreviewPrev = action.clearPrev ? null : (state.soundPreview || state.soundPreviewPrev) - - if (!state.soundPreview && state.soundPreviewPrev === soundPreviewPrev) - return state - - return { ...state, soundPreview: null, soundPreviewPrev } - } - - - static reduce_insertNote(state, action) - { - state = Editor.handlePendingKeyCommandFinish(state) - - const insertOctave = Math.floor(state.insert.nearPitch / 12) - const possiblePitches = [-1, 0, 1].map(offset => - { - const pitch = (insertOctave + offset) * 12 + (MathUtils.mod(action.chroma, 12)) - const delta = Math.abs(pitch - state.insert.nearPitch) - return { pitch, delta } - }) - - possiblePitches.sort((a, b) => a.delta - b.delta) - const chosenPitch = possiblePitches[0].pitch - - const track = state.tracks.findIndex(t => t.kind === "notes") - - const range = new Range(action.time, action.time.add(state.insert.duration)) - const note = new Project.Note(range, chosenPitch) - const id = state.project.nextId - const project = state.project.upsertNote(note).withRefreshedRange() - - state = { ...state, - project, - insert: { ...state.insert, - nearPitch: chosenPitch, - }, - } - - state = Editor.Cursor.place(state, range.end, track) - state = Editor.Cursor.setVisible(state, false) - state = Editor.scrollTimeIntoView(state, range.end) - state = Editor.soundPreviewSet(state, { kind: "note", pitch: chosenPitch }) - state = Editor.selectionClear(state) - state = Track.selectionAdd(state, track, id) - state = Track.selectionRemoveConflictingBehind(state, track) - state = Editor.undoPointAdd(state) - return state - } - - - static reduce_insertChord(state, action) - { - state = Editor.handlePendingKeyCommandFinish(state) - - const track = state.tracks.findIndex(t => t.kind === "chords") - - const range = new Range(action.time, action.time.add(state.insert.duration)) - const chord = new Project.Chord(range, action.chord) - const id = state.project.nextId - const project = state.project.upsertChord(chord).withRefreshedRange() - - state = { ...state, project } - state = Editor.Cursor.place(state, range.end, track) - state = Editor.Cursor.setVisible(state, false) - state = Editor.scrollTimeIntoView(state, range.end) - state = Editor.soundPreviewSet(state, { kind: "chord", chord: action.chord }) - state = Editor.selectionClear(state) - state = Track.selectionAdd(state, track, id) - state = Track.selectionRemoveConflictingBehind(state, track) - state = Editor.undoPointAdd(state) - return state - } - - - static reduce_insertKeyChange(state, action) - { - state = Editor.handlePendingKeyCommandFinish(state) - - const track = state.tracks.findIndex(t => t.kind === "markers") - - const keyCh = new Project.KeyChange(action.time, action.key) - const id = state.project.nextId - const project = state.project.upsertKeyChange(keyCh).withRefreshedRange() - - state = { ...state, project } - state = Editor.Cursor.place(state, action.time, track) - state = Editor.Cursor.setVisible(state, false) - state = Editor.scrollTimeIntoView(state, action.time) - state = Editor.selectionClear(state) - state = Track.selectionAdd(state, track, id) - state = Track.selectionRemoveConflictingBehind(state, track) - state = Editor.undoPointAdd(state) - return state - } - - - static reduce_insertMeterChange(state, action) - { - state = Editor.handlePendingKeyCommandFinish(state) - - const track = state.tracks.findIndex(t => t.kind === "markers") - - const meterCh = new Project.MeterChange(action.time, action.meter) - const id = state.project.nextId - const project = state.project.upsertMeterChange(meterCh).withRefreshedRange() - - state = { ...state, project } - state = Editor.Cursor.place(state, action.time, track) - state = Editor.Cursor.setVisible(state, false) - state = Editor.scrollTimeIntoView(state, action.time) - state = Editor.selectionClear(state) - state = Track.selectionAdd(state, track, id) - state = Track.selectionRemoveConflictingBehind(state, track) - state = Editor.undoPointAdd(state) - return state - } - - - static reduce_keyDown(state, action) - { - return { ...state, - keys: { ...state.keys, [action.key]: true }, - } - } - - - static reduce_keyUp(state, action) - { - let keys = { ...state.keys } - delete keys[action.key] - - return { ...state, keys } - } - - - static reduce_keyCommand(state, action) - { - let needsUndoPointAfter = true - - state = Editor.reduce_clearSoundPreview(state, { clearPrev: true }) - - switch (action.key) - { - case "z": - { - if (state.playback.playing) - break - - if (!action.ctrlKey) - break - - if (action.shiftKey) - state = Editor.reduce_redo(state, {}) - else - state = Editor.reduce_undo(state, {}) - - needsUndoPointAfter = false - break - } - case "y": - { - if (state.playback.playing) - break - - if (!action.ctrlKey) - break - - state = Editor.reduce_redo(state, {}) - needsUndoPointAfter = false - break - } - case "c": - { - if (state.playback.playing) - break - - if (!action.ctrlKey) - break - - state = Editor.reduce_copy(state, {}) - break - } - case "x": - { - if (state.playback.playing) - break - - if (!action.ctrlKey) - break - - state = Editor.reduce_cut(state, {}) - break - } - case "v": - { - if (state.playback.playing) - break - - if (!action.ctrlKey) - break - - state = Editor.reduce_paste(state, {}) - break - } - case " ": - { - const time = state.cursor.time1.min(state.cursor.time2) - state = Editor.reduce_playbackSet(state, { playing: !state.playback.playing, time }) - break - } - case "delete": - { - if (state.playback.playing) - break - - state = Editor.selectionDelete(state) - break - } - case "backspace": - { - if (state.playback.playing) - break - - if (!state.cursor.visible) - { - state = Editor.selectionDelete(state) - break - } - - const track1 = Math.min(state.cursor.track1, state.cursor.track2) - const track2 = Math.max(state.cursor.track1, state.cursor.track2) - - if (state.cursor.time1.compare(state.cursor.time2) == 0) - { - const time = state.cursor.time1.min(state.cursor.time2) - const prevAnchor = Editor.previousAnchor(state, time, track1, track2) - - for (let tr = track1; tr <= track2; tr++) - state = Track.deleteRange(state, tr, new Range(prevAnchor, time, false, false)) - - state = Editor.Cursor.place(state, prevAnchor, null) - state = Editor.Cursor.setVisible(state, true) - state = Editor.scrollTimeIntoView(state, prevAnchor) - } - else - { - const time1 = state.cursor.time1.min(state.cursor.time2) - const time2 = state.cursor.time1.max(state.cursor.time2) - - for (let tr = track1; tr <= track2; tr++) - state = Track.deleteRange(state, tr, new Range(time1, time2, false, false)) - - state = Editor.Cursor.place(state, time1, null) - state = Editor.Cursor.setVisible(state, true) - state = Editor.scrollTimeIntoView(state, time1) - } - break - } - case "escape": - { - state = Editor.reduce_rewind(state) - break - } - case "enter": - { - if (state.playback.playing) - break - - state = Editor.Cursor.setVisible(state, true) - - const range = Editor.selectionRange(state) - if (range) - { - let track = 0 - for (let tr = 0; tr < state.tracks.length; tr++) - if (Track.selectionHasAny(state, tr)) - track = tr - - state = Editor.Cursor.place(state, range.end, track) - state = Editor.scrollTimeIntoView(state, range.end) - } - - state = Editor.handlePendingKeyCommandFinish(state) - state = Editor.selectionClear(state) - break - } - case "arrowright": - case "arrowleft": - { - const invert = (action.key === "arrowleft") - - if (state.playback.playing) - { - const timeDelta = state.timeSnap.multiplyByFloat((action.ctrlKey ? 64 : 16) * (invert ? -1 : 1)) - const newTime = state.playback.time.add(timeDelta) - state = Editor.reduce_playbackSet(state, { playing: true, time: newTime }) - } - else if (state.cursor.visible && (!Editor.selectionHasAny(state) || action.shiftKey)) - { - const timeDelta = state.timeSnap.multiplyByFloat((action.ctrlKey ? 16 : 1) * (invert ? -1 : 1)) - - state = Editor.handlePendingKeyCommandFinish(state) - - if (action.shiftKey) - { - const newTime = state.cursor.time2.add(timeDelta) - state = Editor.Cursor.drag(state, newTime, null) - state = Editor.selectAtCursor(state) - state = Editor.scrollTimeIntoView(state, newTime) - } - else - { - const timeMin = state.cursor.time1.min(state.cursor.time2) - const timeMax = state.cursor.time1.max(state.cursor.time2) - - const newTime = (invert ? timeMin : timeMax).add(timeDelta) - state = Editor.Cursor.place(state, newTime, null) - state = Editor.scrollTimeIntoView(state, newTime) - } - } - else - { - const commandData = - { - timeDelta: state.timeSnap.multiplyByFloat((action.ctrlKey ? 16 : 1) * (invert ? -1 : 1)), - } - - state = Editor.executeKeyCommand(state, "TimeShift", commandData) - - const range = Editor.selectionRange(state) - const newTime = (invert ? range.start : range.end) - state = Editor.Cursor.setVisible(state, false) - state = Editor.Cursor.place(state, newTime, null) - state = Editor.scrollTimeIntoView(state, newTime) - - state = { ...state, pendingKeyCommandFinish: true } - needsUndoPointAfter = false - } - - break - } - case "arrowup": - case "arrowdown": - { - if (state.playback.playing) - break - - const invert = (action.key === "arrowdown") - if (state.cursor.visible && (!Editor.selectionHasAny(state) || action.shiftKey)) - { - const trackDelta = (invert ? 1 : -1) - - state = Editor.handlePendingKeyCommandFinish(state) - - if (action.shiftKey) - { - const newTrack = state.cursor.track2 + trackDelta - state = Editor.Cursor.drag(state, null, newTrack) - state = Editor.selectAtCursor(state) - } - else - { - const trackMin = Math.min(state.cursor.track1, state.cursor.track2) - const trackMax = Math.max(state.cursor.track1, state.cursor.track2) - - const newTrack = (invert ? trackMax : trackMin) + trackDelta - state = Editor.Cursor.place(state, null, newTrack) - } - } - else - { - const commandData = - { - diatonic: true, - degreeDelta: (action.ctrlKey ? 7 : 1) * (invert ? -1 : 1), - } - - state = Editor.Cursor.setVisible(state, false) - state = Editor.executeKeyCommand(state, "PitchShift", commandData) - state = { ...state, pendingKeyCommandFinish: true } - needsUndoPointAfter = false - } - - break - } - case ".": - case ">": - case ",": - case "<": - { - if (state.playback.playing) - break - - const invert = (action.key === "," || action.key === "<") - const commandData = - { - diatonic: false, - pitchDelta: (action.ctrlKey ? 12 : 1) * (invert ? -1 : 1), - } - - state = Editor.Cursor.setVisible(state, false) - state = Editor.executeKeyCommand(state, "PitchShift", commandData) - state = { ...state, pendingKeyCommandFinish: true } - needsUndoPointAfter = false - break - } - case "1": - case "2": - case "3": - case "4": - case "5": - case "6": - case "7": - { - if (state.playback.playing) - break - - const degree = (action.key.charCodeAt(0) - "1".charCodeAt(0)) - const time = state.cursor.time1.min(state.cursor.time2) - const keyCh = state.project.keyChanges.findActiveAt(time) - const key = keyCh ? keyCh.key : Editor.defaultKey() - - if (state.tracks[state.cursor.track1].kind === "chords") - { - const root = key.midiForDegree(degree) - - let pitches = [0] - pitches.push(key.midiForDegree(degree + 2) - root) - pitches.push(key.midiForDegree(degree + 4) - root) - - const kind = Theory.Chord.kindFromPitches(pitches) - const chord = new Theory.Chord(root, 0, kind, 0, []) - state = Editor.reduce_insertChord(state, { time, chord }) - } - else - { - const chroma = key.midiForDegree(degree) - state = Editor.reduce_insertNote(state, { time, chroma }) - } - } - default: - return state - } - - if (action.ev) - action.ev.preventDefault() - - state = Editor.refreshProjectRange(state) - - if (needsUndoPointAfter) - { - state = { ...state, pendingKeyCommandFinish: false } - state = Editor.undoPointAdd(state) - } - - return state - } - - - static reduce_copy(state, action) - { - if (!Editor.selectionHasAny(state)) - return state - - state = Editor.clipboardClear(state) - state = Editor.selectionAddToClipboard(state) - state = Editor.undoPointAdd(state) - return state - } - - - static reduce_cut(state, action) - { - if (!Editor.selectionHasAny(state)) - return state - - state = Editor.clipboardClear(state) - state = Editor.selectionAddToClipboard(state) - state = Editor.selectionDelete(state) - state = Editor.undoPointAdd(state) - return state - } - - - static reduce_paste(state, action) - { - state = Editor.clipboardPaste(state) - state = Editor.undoPointAdd(state) - return state - } - - - static reduce_mouseMove(state, action) - { - state = Editor.reduce_clearSoundPreview(state) - - state = { ...state, - mouse: { ...state.mouse, - x: action.x, - y: action.y, - xPrev: state.mouse.x, - yPrev: state.mouse.y, - hover: null, - draw: null, - time: Editor.timeAtX(state, action.x), - track: Editor.trackAtY(state, action.y), - } - } - - if (!state.mouse.down) - { - for (let tr = 0; tr < state.tracks.length; tr++) - { - if (state.tracks[tr].rect.contains(state.mouse)) - { - const input = { mouse: { ...state.mouse } } - input.mouse.x -= state.tracks[tr].rect.x - input.mouse.y -= state.tracks[tr].rect.y - - state = Track.updateHover(state, tr, input) - if (state.tracks[tr].hover || state.tracks[tr].draw) - { - state = { ...state, - mouse: { ...state.mouse, - hover: state.tracks[tr].hover, - draw: state.tracks[tr].draw, - }, - } - } - } - else - state = Track.update(state, tr, { hover: null, draw: null }) - } - } - else - { - state = { ...state, - mouse: { ...state.mouse, - drag: { - xDelta: state.mouse.x - state.mouse.dragOrig.x, - yDelta: state.mouse.y - state.mouse.dragOrig.y, - timeDelta: state.mouse.time.subtract(state.mouse.dragOrig.time), - }, - }, - } - - const handleMouseEdgeScroll = (state) => - { - let timeScroll = state.timeScroll - - if (state.mouse.x > state.w - state.prefs.mouseEdgeScrollThreshold) - timeScroll += state.timeSnap.asFloat() * state.prefs.mouseEdgeScrollSpeed - - else if (state.mouse.x < state.prefs.mouseEdgeScrollThreshold) - timeScroll -= state.timeSnap.asFloat() * state.prefs.mouseEdgeScrollSpeed - - return { ...state, timeScroll } - } - - if (state.mouse.action == Editor.actionPan) - { - state = { ...state, - timeScroll: state.mouse.dragOrig.timeScroll - state.mouse.drag.xDelta / state.timeScale, - } - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.pan(state, tr) - } - else if (state.mouse.action == Editor.actionSelectCursor) - { - state = Editor.Cursor.drag(state, state.mouse.time, state.mouse.track) - state = Editor.selectAtCursor(state) - state = handleMouseEdgeScroll(state) - } - else if (state.mouse.action == Editor.actionSelectRect) - { - state = { ...state, - rectSelection: { ...state.rectSelection, - time2: state.mouse.time, - y2: state.mouse.y - state.tracks[state.rectSelection.track].rect.y, - }, - } - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionClear(state, tr) - - state = Track.selectionAddAtRect(state, state.rectSelection.track) - state = handleMouseEdgeScroll(state) - } - else if (state.mouse.action == Editor.actionDraw) - { - for (let tr = 0; tr < state.tracks.length; tr++) - { - const input = { mouse: { ...state.mouse } } - input.mouse.x -= state.tracks[tr].rect.x - input.mouse.y -= state.tracks[tr].rect.y - - state = Track.drawMove(state, tr, input) - } - - state = handleMouseEdgeScroll(state) - } - else - { - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.drag(state, tr) - - state = handleMouseEdgeScroll(state) - } - } - - return state - } - - - static reduce_mouseDown(state, action) - { - if (state.mouse.down) - return state - - const timeSinceLastDown = new Date().getTime() - state.mouse.lastDownDate.getTime() - - state = Editor.reduce_clearSoundPreview(state, { clearPrev: true }) - state = Editor.handlePendingKeyCommandFinish(state) - - state = { ...state, - mouse: { ...state.mouse, - down: true, - action: 0, - lastDownDate: new Date(), - dragOrig: { - x: state.mouse.x, - y: state.mouse.y, - time: state.mouse.time, - timeScroll: state.timeScroll, - track: state.mouse.track, - }, - }, - } - - if (action.rightButton || state.keys[Editor.keyPan]) - { - state = { ...state, - mouse: { ...state.mouse, - action: Editor.actionPan, - }, - } - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.dragStart(state, tr) - } - else if (state.keys[Editor.keySelectRect]) - { - state = Editor.Cursor.setVisible(state, false) - - state = { ...state, - mouse: { ...state.mouse, - action: Editor.actionSelectRect, - }, - rectSelection: { - track: state.mouse.track, - time1: state.mouse.time, - time2: state.mouse.time, - y1: state.mouse.y - state.tracks[state.mouse.track].rect.y, - y2: state.mouse.y - state.tracks[state.mouse.track].rect.y, - }, - } - } - else if (!state.playback.playing) - { - if (state.mouse.draw) - { - state = Editor.selectionClear(state) - state = Editor.Cursor.setVisible(state, false) - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.drawStart(state, tr) - - state = { ...state, - mouse: { ...state.mouse, - action: Editor.actionDraw, - }, - } - } - else - { - if (!state.mouse.hover) - { - if (timeSinceLastDown < state.prefs.doubleClickThresholdMs) - { - const time = Editor.previousAnchor(state, state.mouse.time, state.mouse.track, state.mouse.track) - state = Editor.Cursor.place(state, time, state.mouse.track) - state = Editor.scrollTimeIntoView(state, time) - } - else - { - state = Editor.Cursor.place(state, state.mouse.time, state.mouse.track) - state = { ...state, - mouse: { ...state.mouse, - action: Editor.actionSelectCursor, - }, - } - } - - state = Editor.Cursor.setVisible(state, true) - } - else - { - state = Editor.Cursor.setVisible(state, false) - - if (state.keys[Editor.keySelectMultiple]) - { - for (let tr = 0; tr < state.tracks.length; tr++) - { - state = Track.hoveredPlaySoundPreview(state, tr) - state = Track.hoveredToggleSelection(state, tr) - } - } - else - { - let isHoveringSelected = false - for (let tr = 0; tr < state.tracks.length; tr++) - isHoveringSelected |= Track.hoveredIsSelected(state, tr) - - if (!isHoveringSelected) - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionClear(state, tr) - - for (let tr = 0; tr < state.tracks.length; tr++) - { - state = Track.hoveredPlaySoundPreview(state, tr) - state = Track.hoveredSelect(state, tr) - } - } - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.dragStart(state, tr) - - state = { ...state, - mouse: { ...state.mouse, - action: state.mouse.hover && state.mouse.hover.action, - dragOrig: { ...state.mouse.dragOrig, - range: Editor.selectionRange(state), - }, - }, - } - } - } - } - - return state - } - - - static reduce_mouseUp(state, action) - { - if (!state.mouse.down) - return state - - state = Editor.reduce_clearSoundPreview(state) - - if (state.mouse.action == Editor.actionDraw) - { - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.drawEnd(state, tr) - } - - state = { ...state, - mouse: { ...state.mouse, down: false, action: 0, dragOrig: null, drag: null }, - rectSelection: null, - } - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionRemoveConflictingBehind(state, tr) - - state = Editor.refreshProjectRange(state) - state = Editor.undoPointAdd(state) - - return state - } - - - static reduce_mouseWheel(state, action) - { - if (Math.abs(action.deltaX) > 0) - { - let timeScroll = state.timeScroll + 0.01 / (state.timeScale / 100) * action.deltaX - let lastWheelDate = new Date() - - return { ...state, timeScroll, mouse: { ...state.mouse, lastWheelDate } } - } - else if (new Date().getTime() - state.mouse.lastWheelDate.getTime() > 250) - { - const snap = new Rational(1, 1024) - const prevMouseTime = Editor.timeAtX(state, state.mouse.x, snap) - - let timeScale = state.timeScale * (action.deltaY > 0 ? 0.8 : 1.25) - timeScale = Math.max(4, Math.min(2048, timeScale)) - state = { ...state, timeScale } - - const newMouseTime = Editor.timeAtX(state, state.mouse.x, snap) - - const timeScroll = state.timeScroll - newMouseTime.subtract(prevMouseTime).asFloat() - - const timeSnapAdjustThresholdUpper = 24 - const timeSnapAdjustThresholdLower = 8 - let timeSnap = state.timeSnapBase - - if (timeSnap.asFloat() * timeScale > timeSnapAdjustThresholdUpper) - while (timeSnap.asFloat() * timeScale > timeSnapAdjustThresholdUpper) - timeSnap = timeSnap.divide(new Rational(2)) - - else if (timeSnap.asFloat() * timeScale < timeSnapAdjustThresholdLower) - while (timeSnap.asFloat() * timeScale < timeSnapAdjustThresholdLower) - timeSnap = timeSnap.divide(new Rational(1, 2)) - - return { ...state, timeScroll, timeSnap } - } - - return state - } - - - static reduce_clearUndoStack(state, action) - { - state = { ...state, - undoData: { - stack: [], - pointer: -1, - }, - } - - return Editor.undoPointAdd(state) - } - - - static reduce_undo(state, action) - { - if (state.undoData.pointer <= 0) - return state - - state = Editor.handlePendingKeyCommandFinish(state) - - const undoData = { ...state.undoData, - pointer: state.undoData.pointer - 1, - } - - state = { - ...state, - ...undoData.stack[undoData.pointer].state, - undoData, - } - - return Editor.reduce_resize(state, { w: state.w, h: state.h }) - } - - - static reduce_redo(state, action) - { - if (state.undoData.pointer >= state.undoData.stack.length - 1) - return state - - state = Editor.handlePendingKeyCommandFinish(state) - - const undoData = { ...state.undoData, - pointer: state.undoData.pointer + 1, - } - - state = { - ...state, - ...undoData.stack[undoData.pointer].state, - undoData, - } - - return Editor.reduce_resize(state, { w: state.w, h: state.h }) - } - - - static handlePendingKeyCommandFinish(state) - { - if (!state.pendingKeyCommandFinish) - return state - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionRemoveConflictingBehind(state, tr) - - state = { ...state, pendingKeyCommandFinish: false } - state = Editor.undoPointAdd(state) - return state - } - - - static undoPointAdd(state) - { - let stackCutIndex = state.undoData.pointer + 1 - - if (state.undoData.stack.length > 0 && - state.project === state.undoData.stack[stackCutIndex - 1].state.project) - { - //if (state.undoData.pointer != state.undoData.stack.length - 1) - return state - - //stackCutIndex = state.undoData.pointer - } - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionRemoveConflictingBehind(state, tr) - - const newUndoPoint = - { - state: { - project: state.project, - cursor: state.cursor, - tracks: state.tracks, - timeScale: state.timeScale, - timeScroll: state.timeScroll, - pendingKeyCommandFinish: state.pendingKeyCommandFinish, - }, - } - - const newStack = - [ - ...state.undoData.stack.slice(0, stackCutIndex), - newUndoPoint, - ] - - //console.log("undoPointAdd", newStack) - - return { ...state, - undoData: { ...state.undoData, - stack: newStack, - pointer: newStack.length - 1, - }, - } - } - - - static canUndo(state) - { - return (state.undoData.pointer > 0) - } - - - static canRedo(state) - { - return (state.undoData.pointer < state.undoData.stack.length - 1) - } - - - static refreshProjectRange(state) - { - const project = state.project.withRefreshedRange() - if (project === state.project) - return state - - return { ...state, project } - } - - - static xAtTime(state, time) - { - return (time.asFloat() - state.timeScroll) * state.timeScale - } - - - static timeAtX(state, x, timeSnap = null) - { - timeSnap = timeSnap || state.timeSnap - const time = x / state.timeScale + state.timeScroll - return Rational.fromFloat(time, timeSnap.denominator) - } - - - static timeRangeAtX(state, x1, x2, timeSnap = null) - { - timeSnap = timeSnap || state.timeSnap - return new Range(Editor.timeAtX(state, x1, timeSnap).subtract(timeSnap), Editor.timeAtX(state, x2, timeSnap).add(timeSnap)) - } - - - static trackAtY(state, y) - { - for (let tr = 0; tr < state.tracks.length; tr++) - if (y < state.tracks[tr].rect.y2) - return tr - - return state.tracks.length - 1 - } - - - static visibleTimeRange(state) - { - return new Range(Editor.timeAtX(state, 0).subtract(state.timeSnap), Editor.timeAtX(state, state.w).add(state.timeSnap)) - } - - - static defaultKey() - { - return Theory.Key.parse("C Major") - } - - - static defaultMeter() - { - return new Theory.Meter(4, 4) - } - - - static insertionTime(state) - { - return state.cursor.time1 - } - - - static insertionTrack(state) - { - return state.cursor.track1 - } - - - static scrollTimeIntoView(state, time) - { - const visibleTimeRange = Editor.visibleTimeRange(state) - - let timeScroll = state.timeScroll - - if (time.compare(visibleTimeRange.end.subtract(state.timeSnap.multiply(state.prefs.cursorEdgeScrollThreshold))) > 0) - timeScroll = time.subtract(visibleTimeRange.duration).subtract(state.timeSnap).asFloat() + state.timeSnap.asFloat() * state.prefs.cursorEdgeScrollSpeed - - else if (time.compare(visibleTimeRange.start.add(state.timeSnap.multiply(state.prefs.cursorEdgeScrollThreshold))) < 0) - timeScroll = time.asFloat() - state.timeSnap.asFloat() * state.prefs.cursorEdgeScrollSpeed - - return { ...state, timeScroll } - } - - - static scrollPlaybackIntoView(state, time) - { - const margin = state.timeSnap.multiplyByFloat(16) - const visibleTimeRange = Editor.visibleTimeRange(state) - - let timeScroll = state.timeScroll - - if (time.compare(visibleTimeRange.end.subtract(margin)) > 0) - timeScroll = time.subtract(margin).asFloat() - - else if (time.compare(visibleTimeRange.start.add(margin)) < 0) - timeScroll = time.subtract(margin).asFloat() - - return { ...state, timeScroll } - } - - - static selectAtCursor(state) - { - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionClear(state, tr) - - const trackMin = Math.min(state.cursor.track1, state.cursor.track2) - const trackMax = Math.max(state.cursor.track1, state.cursor.track2) - - if (state.cursor.time1.compare(state.cursor.time2) != 0) - for (let tr = trackMin; tr <= trackMax; tr++) - state = Track.selectionAddAtCursor(state, tr) - - return state - } - - - static selectionHasAny(state) - { - for (let tr = 0; tr < state.tracks.length; tr++) - if (Track.selectionHasAny(state, tr)) - return true - - return false - } - - - static selectionClear(state) - { - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionClear(state, tr) - - return state - } - - - static selectionRange(state) - { - let range = null - - for (let tr = 0; tr < state.tracks.length; tr++) - range = Range.merge(range, Track.selectionRange(state, tr)) - - return range - } - - - static selectionDelete(state) - { - if (!Editor.selectionHasAny(state)) - return state - - const range = Editor.selectionRange(state) - - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionDelete(state, tr) - - state = Editor.Cursor.place(state, range.start, null) - state = Editor.Cursor.setVisible(state, true) - state = Editor.scrollTimeIntoView(state, range.start) - - return state - } - - - static selectionAddToClipboard(state) - { - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track.selectionAddToClipboard(state, tr) - - return state - } - - - static clipboardClear(state) - { - return { ...state, - clipboard: { - elems: new Immutable.Map(), - range: null, - }, - } - } - - - static clipboardAdd(state, elem) - { - if (state.clipboard.elems.has(elem.id)) - return state - - return { ...state, - clipboard: { ...state.clipboard, - elems: state.clipboard.elems.set(elem.id, elem), - range: Range.merge(state.clipboard.range, elem.range || Range.fromPoint(elem.time)), - }, - } - } - - - static clipboardPaste(state, elem) - { - state = Editor.selectionClear(state) - - if (!state.clipboard.range) - return state - - const trackMin = Math.min(state.cursor.track1, state.cursor.track2) - const trackMax = Math.max(state.cursor.track1, state.cursor.track2) - - const pasteData = - { - time: state.cursor.time1.min(state.cursor.time2), - } - - const projectBefore = state.project - - for (let tr = trackMin; tr <= trackMax; tr++) - state = Track.clipboardPaste(state, tr, pasteData) - - if (state.project === projectBefore) - return state - - const endTime = pasteData.time.add(state.clipboard.range.duration) - state = Editor.Cursor.setVisible(state, false) - state = Editor.Cursor.place(state, endTime, null) - state = Editor.scrollTimeIntoView(state, endTime) - state = Editor.refreshProjectRange(state) - - return state - } - - - static soundPreviewSet(state, soundPreview) - { - if (!soundPreview) - return state - - if (state.soundPreviewPrev && - state.soundPreviewPrev.kind == soundPreview.kind) - { - if (soundPreview.kind == "note" && - state.soundPreviewPrev.pitch == soundPreview.pitch) - return state - } - - return { ...state, soundPreview } - } - - - static executeKeyCommand(state, command, args) - { - for (let tr = 0; tr < state.tracks.length; tr++) - state = Track["keyCommand" + command](state, tr, args) - - return state - } - - - static previousAnchor(state, time, track1, track2) - { - let prevAnchor = null - - const trackMin = Math.min(track1, track2) - const trackMax = Math.max(track1, track2) - - for (let tr = trackMin; tr <= trackMax; tr++) - prevAnchor = Rational.max(prevAnchor, Track.previousAnchor(state, tr, time)) - - if (!prevAnchor) - return state.project.range.start - - return prevAnchor - } - - - static render(state, ctx) - { - ctx.save() - - ctx.fillStyle = state.prefs.backgroundColor - ctx.fillRect(0, 0, state.w, state.h) - - Editor.renderBackgroundMeasures(state, ctx) - Editor.renderCursorHighlight(state, ctx) - - for (let tr = 0; tr < state.tracks.length; tr++) - { - const track = state.tracks[tr] - - ctx.save() - ctx.translate(track.rect.x, track.rect.y) - - ctx.strokeStyle = state.prefs.trackSeparatorColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - - ctx.beginPath() - ctx.moveTo(0, 0) - ctx.lineTo(state.w, 0) - ctx.stroke() - - ctx.beginPath() - ctx.rect(0, 0, track.rect.w, track.rect.h) - ctx.clip() - - Editor.renderRectSelectionHighlight(state, ctx, tr) - Track.render(state, tr, ctx) - Editor.renderRectSelectionContour(state, ctx, tr) - - ctx.restore() - } - - if (state.cursor.visible) - { - const timeMin = state.cursor.time1.min(state.cursor.time2) - const timeMax = state.cursor.time1.max(state.cursor.time2) - Editor.renderCursorBeam(state, ctx, timeMin, false) - Editor.renderCursorBeam(state, ctx, timeMax, true) - } - - Editor.renderPlaybackBeam(state, ctx, state.playback.time) - - ctx.restore() - } - - - static renderBackgroundMeasures(state, ctx) - { - const visibleTimeRange = Editor.visibleTimeRange(state) - - ctx.fillStyle = "#1b191c" - - const songXMin = Editor.xAtTime(state, state.project.range.start) - const songXMax = Editor.xAtTime(state, state.project.range.end) - - if (songXMin > 0) - ctx.fillRect(0, 0, songXMin, state.h) - - if (songXMax < state.w) - ctx.fillRect(songXMax, 0, state.w - songXMax, state.h) - - for (let [meterCh1, meterCh2] of state.project.meterChanges.iterActiveAtRangePairwise(visibleTimeRange)) - { - if (!meterCh1 && !meterCh2) - continue - - let timeMin = (meterCh1 ? meterCh1.time : null) - let timeMax = (meterCh2 ? meterCh2.time : visibleTimeRange.end) - - let measureAlternate = true - - if (!meterCh1) - { - meterCh1 = meterCh2 - timeMin = meterCh2.time - while (timeMin.compare(visibleTimeRange.start) > 0) - { - timeMin = timeMin.subtract(meterCh2.meter.fullCycleDuration) - - if (meterCh2.meter.alternatingMeasureCount % 2 != 0) - measureAlternate = !measureAlternate - } - } - - const meterCh1X = Editor.xAtTime(state, timeMin) - const meterCh2X = Editor.xAtTime(state, timeMax) - - ctx.strokeStyle = state.prefs.meterChangeColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - - ctx.beginPath() - ctx.moveTo(meterCh1X, 0) - ctx.lineTo(meterCh1X, state.h) - ctx.stroke() - - for (const [measureN, measureD, time1, time2] of meterCh1.meter.iterMeasuresPairwise(timeMin)) - { - measureAlternate = !measureAlternate - - if (time2.compare(visibleTimeRange.start) < 0) - continue - - if (time1.compare(timeMax) > 0 || time1.compare(visibleTimeRange.end) > 0) - break - - const measureX1 = Editor.xAtTime(state, time1) - const measureX2 = Editor.xAtTime(state, time2) - - if (measureAlternate) - { - const x1 = Math.max(songXMin, Math.min(songXMax, Math.min(meterCh2X, measureX1))) - const x2 = Math.max(songXMin, Math.min(songXMax, Math.min(meterCh2X, measureX2))) - - ctx.fillStyle = "#cdf" - ctx.globalAlpha = 0.1 - ctx.fillRect(x1, 0, x2 - x1, state.h) - ctx.globalAlpha = 1 - } - - const halfSubmeasureSize = Editor.xAtTime(state, new Rational(1, measureD * 2)) - Editor.xAtTime(state, new Rational(0)) - if (halfSubmeasureSize > 16) - { - let halfSubmeasureTime = time1.add(new Rational(-1, measureD * 2)) - for (let sub = 1; sub <= measureN; sub++) - { - halfSubmeasureTime = halfSubmeasureTime.add(new Rational(2, measureD * 2)) - - const halfSubmeasureX = Editor.xAtTime(state, halfSubmeasureTime) - if (halfSubmeasureX >= meterCh1X && halfSubmeasureX <= meterCh2X) - { - ctx.strokeStyle = state.prefs.halfSubmeasureColor - ctx.beginPath() - ctx.moveTo(halfSubmeasureX, 0) - ctx.lineTo(halfSubmeasureX, state.h) - ctx.stroke() - } - } - } - - const submeasureSize = Editor.xAtTime(state, new Rational(1, measureD)) - Editor.xAtTime(state, new Rational(0)) - if (submeasureSize > 8) - { - let submeasureTime = time1 - for (let sub = 1; sub <= measureN; sub++) - { - submeasureTime = submeasureTime.add(new Rational(1, measureD)) - - const submeasureX = Editor.xAtTime(state, submeasureTime) - if (submeasureX >= meterCh1X && submeasureX <= meterCh2X) - { - ctx.strokeStyle = state.prefs.submeasureColor - ctx.beginPath() - ctx.moveTo(submeasureX, 0) - ctx.lineTo(submeasureX, state.h) - ctx.stroke() - } - } - } - } - } - - for (const keyCh of state.project.keyChanges.iterAtRange(visibleTimeRange)) - { - const keyChX = Editor.xAtTime(state, keyCh.time) - - ctx.strokeStyle = state.prefs.keyChangeColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - - ctx.beginPath() - ctx.moveTo(keyChX, 0) - ctx.lineTo(keyChX, state.h) - ctx.stroke() - } - } - - - static renderPlaybackBeam(state, ctx, time) - { - if (!state.playback.playing) - return - - const trackMin = 0 - const trackMax = state.tracks.length - 1 - - if (trackMin < 0 || trackMax < 0) - return - - ctx.save() - - const x = Editor.xAtTime(state, time) - - ctx.strokeStyle = state.prefs.playbackCursorColor - ctx.lineCap = "round" - ctx.lineWidth = 2 - - const trackMinRect = state.tracks[trackMin].rect - const trackMaxRect = state.tracks[trackMax].rect - - ctx.beginPath() - ctx.moveTo(trackMinRect.x1 + x, trackMinRect.y1) - ctx.lineTo(trackMinRect.x1 + x, trackMinRect.y1) - ctx.lineTo(trackMaxRect.x1 + x, trackMaxRect.y2) - ctx.lineTo(trackMaxRect.x1 + x, trackMaxRect.y2) - ctx.stroke() - - ctx.restore() - } - - - static renderCursorBeam(state, ctx, time, tipOffsetSide) - { - if (state.playback.playing) - return - - if (state.rectSelection) - return - - const trackMin = Math.min(state.cursor.track1, state.cursor.track2) - const trackMax = Math.max(state.cursor.track1, state.cursor.track2) - - if (trackMin < 0 || trackMax < 0) - return - - ctx.save() - - const x = Editor.xAtTime(state, time) - - ctx.strokeStyle = state.prefs.selectionCursorColor - ctx.lineCap = "round" - ctx.lineWidth = 2 - - const headSize = 7 * (tipOffsetSide ? -1 : 1) - - const trackMinRect = state.tracks[trackMin].rect - const trackMaxRect = state.tracks[trackMax].rect - - ctx.beginPath() - ctx.moveTo(trackMinRect.x1 + x + headSize, trackMinRect.y1) - ctx.lineTo(trackMinRect.x1 + x, trackMinRect.y1) - ctx.lineTo(trackMaxRect.x1 + x, trackMaxRect.y2) - ctx.lineTo(trackMaxRect.x1 + x + headSize, trackMaxRect.y2) - ctx.stroke() - - ctx.restore() - } - - - static renderCursorHighlight(state, ctx) - { - if (state.playback.playing) - return - - if (state.rectSelection) - return - - if (!state.cursor.visible) - return - - const timeMin = state.cursor.time1.min(state.cursor.time2) - const timeMax = state.cursor.time1.max(state.cursor.time2) - const trackMin = Math.min(state.cursor.track1, state.cursor.track2) - const trackMax = Math.max(state.cursor.track1, state.cursor.track2) - const trackMinRect = state.tracks[trackMin].rect - const trackMaxRect = state.tracks[trackMax].rect - - ctx.save() - - const x1 = Editor.xAtTime(state, timeMin) - const x2 = Editor.xAtTime(state, timeMax) - - ctx.fillStyle = state.prefs.selectionCursorColor - ctx.globalAlpha = 0.3 - ctx.fillRect(x1, trackMinRect.y1, x2 - x1, trackMaxRect.y2 - trackMinRect.y1) - - ctx.restore() - } - - - static renderRectSelectionContour(state, ctx, trackIndex) - { - if (state.playback.playing) - return - - if (!state.rectSelection) - return - - if (trackIndex != state.rectSelection.track) - return - - const timeMin = state.rectSelection.time1.min(state.rectSelection.time2) - const timeMax = state.rectSelection.time1.max(state.rectSelection.time2) - const y1 = Math.min(state.rectSelection.y1, state.rectSelection.y2) - const y2 = Math.max(state.rectSelection.y1, state.rectSelection.y2) + 1 - - ctx.save() - - const x1 = Editor.xAtTime(state, timeMin) - const x2 = Editor.xAtTime(state, timeMax) - - ctx.strokeStyle = state.prefs.selectionCursorColor - ctx.lineCap = "square" - ctx.lineWidth = 2 - ctx.strokeRect(x1, y1, x2 - x1, y2 - y1) - - ctx.restore() - } - - - static renderRectSelectionHighlight(state, ctx, trackIndex) - { - if (state.playback.playing) - return - - if (!state.rectSelection) - return - - if (trackIndex != state.rectSelection.track) - return - - const timeMin = state.rectSelection.time1.min(state.rectSelection.time2) - const timeMax = state.rectSelection.time1.max(state.rectSelection.time2) - const y1 = Math.min(state.rectSelection.y1, state.rectSelection.y2) - const y2 = Math.max(state.rectSelection.y1, state.rectSelection.y2) + 1 - - ctx.save() - - const x1 = Editor.xAtTime(state, timeMin) - const x2 = Editor.xAtTime(state, timeMax) - - ctx.fillStyle = state.prefs.selectionCursorColor - ctx.globalAlpha = 0.3 - ctx.fillRect(x1, y1, x2 - x1, y2 - y1) - - ctx.restore() - } - - - static Cursor = class EditorCursor - { - static setVisible(state, visible) - { - return { ...state, - cursor: { ...state.cursor, - visible, - }, - } - } - - - static place(state, time, trackIndex) - { - if (trackIndex !== null) - trackIndex = Math.max(0, Math.min(state.tracks.length - 1, trackIndex)) - - return { ...state, - cursor: { ...state.cursor, - time1: time === null ? state.cursor.time1 : time, - time2: time === null ? state.cursor.time2 : time, - track1: trackIndex === null ? state.cursor.track1 : trackIndex, - track2: trackIndex === null ? state.cursor.track2 : trackIndex, - }, - } - } - - - static drag(state, time, trackIndex) - { - if (trackIndex !== null) - trackIndex = Math.max(0, Math.min(state.tracks.length - 1, trackIndex)) - - return { ...state, - cursor: { ...state.cursor, - time2: time === null ? state.cursor.time2 : time, - track2: trackIndex === null ? state.cursor.track2 : trackIndex, - }, - } - } - } -} \ No newline at end of file diff --git a/src_old/editor/track.js b/src_old/editor/track.js deleted file mode 100644 index 225d9fd..0000000 --- a/src_old/editor/track.js +++ /dev/null @@ -1,310 +0,0 @@ -import { default as Immutable } from "immutable" -import Editor from "./editor.js" -import TrackMarkers from "./trackMarkers.js" -import TrackChords from "./trackChords.js" -import TrackNotes from "./trackNotes.js" -import Rational from "../util/rational.js" -import Range from "../util/range.js" -import Rect from "../util/rect.js" - - -export default class Track -{ - static init(state, action) - { - return { - rect: new Rect(0, 0, 0, 0), - yScroll: 0, - hover: null, - draw: null, - selection: new Immutable.Set(), - dragData: null, - } - } - - - static handlerForTrackKind(kind) - { - switch (kind) - { - case "markers": return TrackMarkers - case "chords": return TrackChords - case "notes": return TrackNotes - default: throw "invalid track kind" - } - } - - - static dispatchDerived(fnName, state, trackIndex, args) - { - const handler = Track.handlerForTrackKind(state.tracks[trackIndex].kind) - const fn = handler[fnName] - if (!fn) - return null - - return fn(state, trackIndex, args) - } - - - static update(state, trackIndex, newData) - { - const track = - { - ...state.tracks[trackIndex], - ...newData - } - - return { - ...state, - tracks: [ ...state.tracks.slice(0, trackIndex), track, ...state.tracks.slice(trackIndex + 1) ], - } - } - - - static hoveredIsSelected(state, trackIndex, args) - { - if (!state.tracks[trackIndex].hover) - return false - - return state.tracks[trackIndex].selection.has(state.tracks[trackIndex].hover.id) - } - - - static hoveredSelect(state, trackIndex, args) - { - if (!state.tracks[trackIndex].hover) - return state - - const id = state.tracks[trackIndex].hover.id - - state = Track.cursorSetAtElem(state, trackIndex, state.project.findById(id)) - return Track.selectionAdd(state, trackIndex, id) - } - - - static hoveredToggleSelection(state, trackIndex, args) - { - if (!state.tracks[trackIndex].hover) - return state - - const id = state.tracks[trackIndex].hover.id - - state = Track.cursorSetAtElem(state, trackIndex, state.project.findById(id)) - - if (state.tracks[trackIndex].selection.has(id)) - return Track.selectionRemove(state, trackIndex, id) - else - return Track.selectionAdd(state, trackIndex, id) - } - - - static hoveredPlaySoundPreview(state, trackIndex, args) - { - return Track.dispatchDerived("hoveredPlaySoundPreview", state, trackIndex, args) || state - } - - - static cursorSetAtElem(state, trackIndex, elem) - { - if (!elem) - return state - - if (elem.time) - return Editor.Cursor.place(state, elem.time, trackIndex) - - if (elem.range) - return Editor.Cursor.place(state, elem.range.start, trackIndex) - - return state - } - - - static selectionClear(state, trackIndex, args) - { - return Track.update(state, trackIndex, { selection: new Immutable.Set() }) - } - - - static selectionAdd(state, trackIndex, id) - { - return Track.update(state, trackIndex, { selection: state.tracks[trackIndex].selection.add(id) }) - } - - - static selectionRemove(state, trackIndex, id) - { - return Track.update(state, trackIndex, { selection: state.tracks[trackIndex].selection.delete(id) }) - } - - - static selectionRange(state, trackIndex) - { - let range = null - - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - if (elem.range) - range = Range.merge(range, elem.range) - else - range = Range.merge(range, Range.fromPoint(elem.time)) - } - - return range - } - - - static selectionHasAny(state, trackIndex, args) - { - const res = Track.dispatchDerived("selectionHasAny", state, trackIndex, args) - if (res !== null) - return res - - for (const id of state.tracks[trackIndex].selection) - if (state.project.findById(id)) - return true - - return false - } - - - static selectionDelete(state, trackIndex, args) - { - const res = Track.dispatchDerived("selectionDelete", state, trackIndex, args) - if (res !== null) - return res - - for (const id of state.tracks[trackIndex].selection) - state = { ...state, project: state.project.removeById(id) } - - return state - } - - - static selectionAddAtCursor(state, trackIndex, args) - { - return Track.dispatchDerived("selectionAddAtCursor", state, trackIndex, args) || state - } - - - static selectionAddAtRect(state, trackIndex, args) - { - return Track.dispatchDerived("selectionAddAtRect", state, trackIndex, args) || state - } - - - static selectionAddToClipboard(state, trackIndex, args) - { - const res = Track.dispatchDerived("selectionAddToClipboard", state, trackIndex, args) - if (res !== null) - return res - - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - state = Editor.clipboardAdd(state, elem) - } - - return state - } - - - static selectionRemoveConflictingBehind(state, trackIndex, args) - { - return Track.dispatchDerived("selectionRemoveConflictingBehind", state, trackIndex, args) || state - } - - - static clipboardPaste(state, trackIndex, args) - { - return Track.dispatchDerived("clipboardPaste", state, trackIndex, args) || state - } - - - static updateHover(state, trackIndex, args) - { - return Track.dispatchDerived("updateHover", state, trackIndex, args) || state - } - - - static previousAnchor(state, trackIndex, time) - { - return Track.dispatchDerived("previousAnchor", state, trackIndex, time) || null - } - - - static deleteRange(state, trackIndex, range) - { - return Track.dispatchDerived("deleteRange", state, trackIndex, range) || state - } - - - static pan(state, trackIndex, args) - { - return Track.dispatchDerived("pan", state, trackIndex, args) || state - } - - - static dragStart(state, trackIndex, args) - { - let elems = new Immutable.Map() - for (const id of state.tracks[trackIndex].selection) - elems = elems.set(id, state.project.findById(id)) - - let dragData = - { - yScroll: state.tracks[trackIndex].yScroll, - elems, - } - - return Track.update(state, trackIndex, { dragData }) - } - - - static drag(state, trackIndex, args) - { - return Track.dispatchDerived("drag", state, trackIndex, args) || state - } - - - static drawStart(state, trackIndex, args) - { - return Track.dispatchDerived("drawStart", state, trackIndex, args) || state - } - - - static drawMove(state, trackIndex, args) - { - return Track.dispatchDerived("drawMove", state, trackIndex, args) || state - } - - - static drawEnd(state, trackIndex, args) - { - return Track.dispatchDerived("drawEnd", state, trackIndex, args) || state - } - - - static keyCommandTimeShift(state, trackIndex, args) - { - return Track.dispatchDerived("keyCommandTimeShift", state, trackIndex, args) || state - } - - - static keyCommandPitchShift(state, trackIndex, args) - { - return Track.dispatchDerived("keyCommandPitchShift", state, trackIndex, args) || state - } - - - static render(state, trackIndex, args) - { - return Track.dispatchDerived("render", state, trackIndex, args) || state - } -} \ No newline at end of file diff --git a/src_old/editor/trackChords.js b/src_old/editor/trackChords.js deleted file mode 100644 index 075bb6f..0000000 --- a/src_old/editor/trackChords.js +++ /dev/null @@ -1,456 +0,0 @@ -import Project from "../project/project.js" -import Editor from "./editor.js" -import Track from "./track.js" -import Rational from "../util/rational.js" -import Range from "../util/range.js" -import Rect from "../util/rect.js" -import Theory from "../theory.ts" -import CanvasUtils from "../util/canvas.js" - - -export default class TrackChords -{ - static init(state, trackIndex, action) - { - const newTrack = - { - ...Track.init(state, action), - kind: "chords", - } - - return { ...state, - tracks: [ ...state.tracks, newTrack ], - } - } - - - static updateHover(state, trackIndex, input) - { - let hover = null - let draw = null - - if (state.keys[Editor.keyDraw]) - { - const keyCh = state.project.keyChanges.findActiveAt(input.mouse.time) - const key = keyCh ? keyCh.key : Editor.defaultKey() - draw = - { - kind: "chord", - time1: input.mouse.time, - time2: input.mouse.time.add(state.timeSnap.multiply(new Rational(4))), - chord: new Theory.Chord(key.chromaForDegree(0), 0, 0, 0, []) - } - } - else - { - const margin = 10 - const checkRange = Editor.timeRangeAtX(state, input.mouse.x - margin, input.mouse.x + margin) - - let hoverPrimary = null - let hoverSecondary = null - - for (const chord of state.project.chords.iterAtRange(checkRange)) - { - const margin = 2 - - const x1 = Editor.xAtTime(state, chord.range.start) - const x2 = Editor.xAtTime(state, chord.range.end) - const rect = new Rect(x1 - margin, 0, x2 - x1 + margin * 2, state.tracks[trackIndex].rect.h) - - const dragMarginOut = Math.abs(Math.min(0, rect.w - 16)) - const stretchMarginOut = 16 - const stretchMarginIn = Math.max(0, Math.min(10, rect.w / 4)) - const rectDrag = new Rect(rect.x - dragMarginOut, rect.y, rect.w + dragMarginOut * 2, rect.h) - const rectStretchStart = new Rect(rect.x - stretchMarginOut, rect.y, stretchMarginOut + stretchMarginIn, rect.h) - const rectStretchEnd = new Rect(rect.x2 - stretchMarginIn, rect.y, stretchMarginOut + stretchMarginIn, rect.h) - - const exactHover = rect.contains(input.mouse) - - let action = 0 - if (dragMarginOut > 0 && rectDrag.contains(input.mouse)) - action = Editor.actionDragTime - else if (rectStretchStart.contains(input.mouse)) - action = Editor.actionStretchTimeStart - else if (rectStretchEnd.contains(input.mouse)) - action = Editor.actionStretchTimeEnd - else if (exactHover) - action = Editor.actionDragTime - - const hoverChord = - { - id: chord.id, - range: chord.range, - action, - } - - if (action != 0) - { - if (exactHover) - hoverPrimary = hoverChord - else - hoverSecondary = hoverChord - } - - if (hoverPrimary) - break - } - - hover = hoverPrimary || hoverSecondary - } - - return Track.update(state, trackIndex, { hover, draw }) - } - - - static hoveredPlaySoundPreview(state, trackIndex) - { - const hover = state.tracks[trackIndex].hover - if (!hover) - return state - - const id = hover.id - const chord = state.project.chords.findById(id) - - if (!chord) - return state - - return Editor.soundPreviewSet(state, TrackChords.mergeSoundPreview(null, chord.chord)) - } - - - static selectionAddAtCursor(state, trackIndex) - { - const timeRange = new Range(state.cursor.time1, state.cursor.time2, false, false).sorted() - - for (const chord of state.project.chords.iterAtRange(timeRange)) - state = Track.selectionAdd(state, trackIndex, chord.id) - - return state - } - - - static selectionAddAtRect(state, trackIndex) - { - const timeRange = new Range(state.rectSelection.time1, state.rectSelection.time2, false, false).sorted() - - for (const chord of state.project.chords.iterAtRange(timeRange)) - state = Track.selectionAdd(state, trackIndex, chord.id) - - return state - } - - - static selectionRemoveConflictingBehind(state, trackIndex) - { - const selection = state.tracks[trackIndex].selection - - for (const id of selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - for (const chord of state.project.chords.iterAtRange(elem.range)) - { - if (selection.has(chord.id)) - continue - - state = { ...state, project: state.project.removeById(chord.id) } - - for (const slice of chord.range.iterSlices(elem.range)) - { - const newChord = new Project.Chord(slice, chord.chord) - state = { ...state, project: state.project.upsertChord(newChord) } - } - } - } - - return state - } - - - static clipboardPaste(state, trackIndex, pasteData) - { - for (const [clipboardId, elem] of state.clipboard.elems) - { - if (elem instanceof Project.Chord) - { - const range = elem.range.displace(pasteData.time.subtract(state.clipboard.range.start)) - const chord = new Project.Chord(range, elem.chord) - const id = state.project.nextId - state = { ...state, project: state.project.upsertChord(chord) } - state = Track.selectionAdd(state, trackIndex, id) - } - } - - return state - } - - - static previousAnchor(state, trackIndex, time) - { - return state.project.chords.findPreviousAnchor(time) - } - - - static deleteRange(state, trackIndex, range) - { - for (const chord of state.project.chords.iterAtRange(range)) - { - state = { ...state, project: state.project.removeById(chord.id) } - - for (const slice of chord.range.iterSlices(range)) - { - const newChord = new Project.Chord(slice, chord.chord) - state = { ...state, project: state.project.upsertChord(newChord) } - } - } - - return state - } - - - static drag(state, trackIndex) - { - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.tracks[trackIndex].dragData.elems.get(id) - if (!elem) - continue - - let changes = {} - - if (state.mouse.action & Editor.actionDragTime) - changes.range = elem.range.displace(state.mouse.drag.timeDelta) - - if (state.mouse.action & Editor.actionStretchTimeStart) - { - changes.range = elem.range.stretch(state.mouse.drag.timeDelta, state.mouse.dragOrig.range.end, state.mouse.dragOrig.range.start) - if (elem.range.start.compare(state.mouse.dragOrig.range.start) == 0) - changes.range = new Range(changes.range.start.snap(state.timeSnap), changes.range.end) - - changes.range = changes.range.sorted() - } - - if (state.mouse.action & Editor.actionStretchTimeEnd) - { - changes.range = elem.range.stretch(state.mouse.drag.timeDelta, state.mouse.dragOrig.range.start, state.mouse.dragOrig.range.end) - if (elem.range.end.compare(state.mouse.dragOrig.range.end) == 0) - changes.range = new Range(changes.range.start, changes.range.end.snap(state.timeSnap)) - - changes.range = changes.range.sorted() - } - - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - return state - } - - - static drawMove(state, trackIndex, input) - { - let draw = state.tracks[trackIndex].draw - - if (draw) - { - let time2 = input.mouse.time - if (Math.abs(Editor.xAtTime(state, draw.time1) - Editor.xAtTime(state, time2)) < 5) - time2 = draw.time1.add(state.timeSnap.multiply(new Rational(4))) - - draw = { ...draw, time2 } - } - - return Track.update(state, trackIndex, { draw }) - } - - - static drawEnd(state, trackIndex, input) - { - const draw = state.tracks[trackIndex].draw - if (draw) - { - if (draw.kind == "chord") - { - const chord = new Project.Chord(new Range(draw.time1, draw.time2).sorted(), draw.chord) - const id = state.project.nextId - state = { ...state, project: state.project.upsertChord(chord) } - state = Track.selectionAdd(state, trackIndex, id) - state = Editor.soundPreviewSet(state, TrackChords.mergeSoundPreview(null, draw.chord)) - } - } - - return state - } - - - static keyCommandTimeShift(state, trackIndex, commandData) - { - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - let changes = {} - changes.range = elem.range.displace(commandData.timeDelta) - - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - return state - } - - - static keyCommandPitchShift(state, trackIndex, commandData) - { - let soundPreview = null - - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - let changes = {} - if (commandData.diatonic) - { - const keyCh = state.project.keyChanges.findActiveAt(elem.range.start) - const key = keyCh ? keyCh.key : Editor.defaultKey() - const degree = key.octavedDegreeForMidi(elem.chord.rootMidi) - const newDegree = degree + commandData.degreeDelta - const newRoot = key.midiForDegree(commandData.degreeDelta >= 0 ? Math.floor(newDegree) : Math.ceil(newDegree)) - changes.chord = elem.chord.withChanges({ rootMidi: newRoot }) - } - else - changes.chord = elem.chord.withChanges({ rootMidi: elem.chord.rootMidi + commandData.pitchDelta }) - - soundPreview = TrackChords.mergeSoundPreview(soundPreview, changes.chord) - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - state = Editor.soundPreviewSet(state, soundPreview) - return state - } - - - static mergeSoundPreview(soundPreview, chord) - { - return { kind: "chord", chord } - } - - - static *iterKeyChangesAtRange(state, trackIndex, range) - { - const defaultKey = Editor.defaultKey() - - for (const pair of state.project.keyChanges.iterActiveAtRangePairwise(range)) - { - const keyCh1 = pair[0] || new Project.KeyChange(range.start, defaultKey) - const keyCh2 = pair[1] || new Project.KeyChange(range.end, defaultKey) - - const keyCh1X = Editor.xAtTime(state, keyCh1.time) - const keyCh2X = Editor.xAtTime(state, keyCh2.time) - - yield [keyCh1, keyCh1X, keyCh2X] - } - } - - - static *iterChordsAndKeyChangesAtRange(state, trackIndex, range) - { - const defaultKey = Editor.defaultKey() - - for (const pair of state.project.keyChanges.iterActiveAtRangePairwise(range)) - { - const keyCh1 = pair[0] || new Project.KeyChange(range.start, defaultKey) - const keyCh2 = pair[1] || new Project.KeyChange(range.end, defaultKey) - - const keyCh1X = Editor.xAtTime(state, keyCh1.time) - const keyCh2X = Editor.xAtTime(state, keyCh2.time) - - const time1 = keyCh1.time.max(range.start) - const time2 = keyCh2.time.min(range.end) - - for (const chord of state.project.chords.iterAtRange(new Range(time1, time2))) - yield [chord, keyCh1, keyCh1X, keyCh2X] - } - } - - - static render(state, trackIndex, ctx) - { - const track = state.tracks[trackIndex] - const visibleTimeRange = Editor.visibleTimeRange(state) - - for (const [chord, keyCh, xMin, xMax] of TrackChords.iterChordsAndKeyChangesAtRange(state, trackIndex, visibleTimeRange)) - { - if (!state.playback.playing && track.selection.has(chord.id)) - continue - - const hovering = track.hover && track.hover.id == chord.id - const playing = state.playback.playing && chord.range.overlapsPoint(state.playback.time) - TrackChords.renderChord(state, trackIndex, ctx, chord.range, keyCh.key, chord.chord, xMin, xMax, hovering, false, playing) - } - - if (!state.playback.playing) - { - for (const [chord, keyCh, xMin, xMax] of TrackChords.iterChordsAndKeyChangesAtRange(state, trackIndex, visibleTimeRange)) - { - if (!track.selection.has(chord.id)) - continue - - const hovering = track.hover && track.hover.id == chord.id - TrackChords.renderChord(state, trackIndex, ctx, chord.range, keyCh.key, chord.chord, xMin, xMax, hovering, true, false) - } - } - - const draw = state.tracks[trackIndex].draw - if (draw) - { - ctx.globalAlpha = 0.6 - - const keyCh = state.project.keyChanges.findActiveAt(draw.time1) - const key = keyCh ? keyCh.key : Editor.defaultKey() - TrackChords.renderChord(state, trackIndex, ctx, new Range(draw.time1, draw.time2).sorted(), key, draw.chord, -Infinity, Infinity, false, false) - - ctx.globalAlpha = 1 - } - } - - - static renderChord(state, trackIndex, ctx, range, key, chord, xMin, xMax, hovering, selected, playing) - { - const h = state.tracks[trackIndex].rect.h - const chordX1 = Editor.xAtTime(state, range.start) - const chordX2 = Editor.xAtTime(state, range.end) - - let x1 = Math.max(xMin, Math.min(xMax, chordX1)) - let x2 = Math.max(xMin, Math.min(xMax, chordX2)) - - if (x1 == chordX1) - x1 += 1 - - if (x2 == chordX2) - x2 -= 1 - - CanvasUtils.drawChord(ctx, x1, 0, x2, h, chord, key) - - if (hovering) - { - ctx.globalAlpha = 0.4 - ctx.fillStyle = "#fff" - ctx.fillRect(x1, 0, x2 - x1, h) - ctx.globalAlpha = 1 - } - - if (selected || playing) - { - const margin = 3 - ctx.globalAlpha = 0.6 - ctx.fillStyle = "#fff" - ctx.fillRect(x1, margin, x2 - x1, h - margin * 2) - ctx.globalAlpha = 1 - } - } -} \ No newline at end of file diff --git a/src_old/editor/trackMarkers.js b/src_old/editor/trackMarkers.js deleted file mode 100644 index 5c565d9..0000000 --- a/src_old/editor/trackMarkers.js +++ /dev/null @@ -1,477 +0,0 @@ -import Project from "../project/project.js" -import Editor from "./editor.js" -import Track from "./track.js" -import Rational from "../util/rational.js" -import Range from "../util/range.js" -import Rect from "../util/rect.js" -import Theory from "../theory.ts" - - -const markerWidth = 22 -const keyMarkerY = 0 -const keyMarkerHeight = 22 -const meterMarkerY = 22 -const meterMarkerHeight = 22 - - -export default class TrackMarkers -{ - static init(state, trackIndex, action) - { - const newTrack = - { - ...Track.init(state, action), - kind: "markers", - } - - return { ...state, - tracks: [ ...state.tracks, newTrack ], - } - } - - - static updateHover(state, trackIndex, input) - { - let hover = null - let draw = null - - if (state.keys[Editor.keyDraw]) - { - if (input.mouse.y >= meterMarkerY && input.mouse.y <= meterMarkerY + meterMarkerHeight) - draw = { kind: "meter", time: input.mouse.time } - - if (input.mouse.y >= keyMarkerY && input.mouse.y <= keyMarkerY + keyMarkerHeight) - draw = { kind: "key", time: input.mouse.time } - } - else - { - const checkRange = Editor.timeRangeAtX(state, input.mouse.x - markerWidth, input.mouse.x + markerWidth) - - for (const keyCh of state.project.keyChanges.iterAtRange(checkRange)) - { - const rect = TrackMarkers.knobRectForKeyChange(state, keyCh.time) - if (rect.contains(input.mouse)) - { - hover = - { - id: keyCh.id, - range: Range.fromPoint(keyCh.time), - action: Editor.actionDragTime, - } - } - } - - for (const meterCh of state.project.meterChanges.iterAtRange(checkRange)) - { - const rect = TrackMarkers.knobRectForMeterChange(state, meterCh.time) - if (rect.contains(input.mouse)) - { - hover = - { - id: meterCh.id, - range: Range.fromPoint(meterCh.time), - action: Editor.actionDragTime, - } - } - } - } - - return Track.update(state, trackIndex, { hover, draw }) - } - - - static selectionAddAtCursor(state, trackIndex) - { - const timeRange = new Range(state.cursor.time1, state.cursor.time2, false, false).sorted() - - for (const keyCh of state.project.keyChanges.iterAtRange(timeRange)) - state = Track.selectionAdd(state, trackIndex, keyCh.id) - - for (const meterCh of state.project.meterChanges.iterAtRange(timeRange)) - state = Track.selectionAdd(state, trackIndex, meterCh.id) - - return state - } - - - static selectionAddAtRect(state, trackIndex) - { - const timeRange = new Range(state.rectSelection.time1, state.rectSelection.time2, false, false).sorted() - const y1 = Math.min(state.rectSelection.y1, state.rectSelection.y2) - const y2 = Math.max(state.rectSelection.y1, state.rectSelection.y2) - - if (y2 > keyMarkerY && y1 < keyMarkerY + keyMarkerHeight) - for (const keyCh of state.project.keyChanges.iterAtRange(timeRange)) - state = Track.selectionAdd(state, trackIndex, keyCh.id) - - if (y2 > meterMarkerY && y1 < meterMarkerY + meterMarkerHeight) - for (const meterCh of state.project.meterChanges.iterAtRange(timeRange)) - state = Track.selectionAdd(state, trackIndex, meterCh.id) - - return state - } - - - static selectionRemoveConflictingBehind(state, trackIndex) - { - const selection = state.tracks[trackIndex].selection - - for (const id of selection) - { - const elem = state.project.findById(id) - - if (elem instanceof Project.KeyChange) - { - for (const keyCh of state.project.keyChanges.iterAt(elem.time)) - { - if (selection.has(keyCh.id)) - continue - - state = { ...state, project: state.project.removeById(keyCh.id) } - } - } - - if (elem instanceof Project.MeterChange) - { - for (const meterCh of state.project.meterChanges.iterAt(elem.time)) - { - if (selection.has(meterCh.id)) - continue - - state = { ...state, project: state.project.removeById(meterCh.id) } - } - } - } - - return state - } - - - static clipboardPaste(state, trackIndex, pasteData) - { - for (const [clipboardId, elem] of state.clipboard.elems) - { - if (elem instanceof Project.KeyChange) - { - const time = elem.time.add(pasteData.time.subtract(state.clipboard.range.start)) - const keyCh = new Project.KeyChange(time, elem.key) - const id = state.project.nextId - state = { ...state, project: state.project.upsertKeyChange(keyCh) } - state = Track.selectionAdd(state, trackIndex, id) - } - - if (elem instanceof Project.MeterChange) - { - const time = elem.time.add(pasteData.time.subtract(state.clipboard.range.start)) - const meterCh = new Project.MeterChange(time, elem.meter) - const id = state.project.nextId - state = { ...state, project: state.project.upsertMeterChange(meterCh) } - state = Track.selectionAdd(state, trackIndex, id) - } - } - - return state - } - - - static previousAnchor(state, trackIndex, time) - { - const prevAnchorKey = state.project.keyChanges.findPreviousDeletionAnchor(time) - const prevAnchorMeter = state.project.meterChanges.findPreviousDeletionAnchor(time) - - return Rational.max(prevAnchorKey, prevAnchorMeter) - } - - - static deleteRange(state, trackIndex, range) - { - if (range.start.compare(range.end) == 0) - { - for (const keyCh of state.project.keyChanges.iterAt(range.start)) - state = { ...state, project: state.project.removeById(keyCh.id) } - - for (const meterCh of state.project.meterChanges.iterAt(range.start)) - state = { ...state, project: state.project.removeById(meterCh.id) } - } - else - { - for (const keyCh of state.project.keyChanges.iterAtRange(range)) - state = { ...state, project: state.project.removeById(keyCh.id) } - - for (const meterCh of state.project.meterChanges.iterAtRange(range)) - state = { ...state, project: state.project.removeById(meterCh.id) } - } - - return state - } - - - static drag(state, trackIndex) - { - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.tracks[trackIndex].dragData.elems.get(id) - if (!elem) - continue - - let changes = {} - - if (state.mouse.action & Editor.actionDragTime) - changes.time = elem.time.add(state.mouse.drag.timeDelta).snap(state.timeSnap) - - if (state.mouse.action & Editor.actionStretchTimeStart) - { - changes.time = elem.time.stretch(state.mouse.drag.timeDelta, state.mouse.dragOrig.range.end, state.mouse.dragOrig.range.start) - if (elem.time.compare(state.mouse.dragOrig.range.start) == 0) - changes.time = changes.time.snap(state.timeSnap) - } - - if (state.mouse.action & Editor.actionStretchTimeEnd) - { - changes.time = elem.time.stretch(state.mouse.drag.timeDelta, state.mouse.dragOrig.range.start, state.mouse.dragOrig.range.end) - if (elem.time.compare(state.mouse.dragOrig.range.start) == 0) - changes.time = changes.time.snap(state.timeSnap) - } - - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - return state - } - - - static drawMove(state, trackIndex, input) - { - let draw = state.tracks[trackIndex].draw - - if (draw) - draw = { ...draw, time: input.mouse.time } - - return Track.update(state, trackIndex, { draw }) - } - - - static drawEnd(state, trackIndex, input) - { - const draw = state.tracks[trackIndex].draw - if (draw) - { - const id = state.project.nextId - - if (draw.kind == "key") - state = { ...state, project: state.project.upsertKeyChange(new Project.KeyChange(draw.time, Editor.defaultKey())) } - - else if (draw.kind == "meter") - state = { ...state, project: state.project.upsertMeterChange(new Project.MeterChange(draw.time, Editor.defaultMeter())) } - - state = Track.selectionAdd(state, trackIndex, id) - } - - return state - } - - - static keyCommandTimeShift(state, trackIndex, commandData) - { - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - let changes = {} - changes.time = elem.time.add(commandData.timeDelta) - - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - return state - } - - - static keyCommandPitchShift(state, trackIndex, commandData) - { - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - if (!(elem instanceof Project.KeyChange)) - continue - - let changes = {} - if (commandData.diatonic) - { - const key = elem.key - const newRootMidi = key.midiForDegree(0) + commandData.degreeDelta - changes.key = new Theory.Key(key.nameForMidi(newRootMidi).simplified, key.scale) - /*const key = elem.key - const newRoot = new Theory.PitchName(key.tonic.letter + commandData.degreeDelta, key.tonic.accidental) - changes.key = new Theory.Key(newRoot, key.scale)*/ - } - else - { - const key = elem.key - const newRootMidi = key.midiForDegree(0) + commandData.pitchDelta - changes.key = new Theory.Key(key.nameForMidi(newRootMidi).simplified, key.scale) - } - - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - return state - } - - - static knobRectForMeterChange(state, time) - { - const x = (time.asFloat() - state.timeScroll) * state.timeScale - - return new Rect(x - markerWidth / 2, meterMarkerY, markerWidth, meterMarkerHeight) - } - - - static knobRectForKeyChange(state, time) - { - const x = (time.asFloat() - state.timeScroll) * state.timeScale - - return new Rect(x - markerWidth / 2, keyMarkerY, markerWidth, keyMarkerHeight) - } - - - static render(state, trackIndex, ctx) - { - const visibleTimeRange = Editor.visibleTimeRange(state) - - for (const keyCh of state.project.keyChanges.iterAtRange(visibleTimeRange)) - TrackMarkers.renderKeyChange(state, trackIndex, ctx, keyCh) - - for (const meterCh of state.project.meterChanges.iterAtRange(visibleTimeRange)) - TrackMarkers.renderMeterChange(state, trackIndex, ctx, meterCh) - - if (state.tracks[trackIndex].draw) - { - ctx.globalAlpha = 0.6 - - if (state.tracks[trackIndex].draw.kind == "key") - TrackMarkers.renderKeyChangeKnob(state, trackIndex, ctx, state.tracks[trackIndex].draw.time) - - else if (state.tracks[trackIndex].draw.kind == "meter") - TrackMarkers.renderMeterChangeKnob(state, trackIndex, ctx, state.tracks[trackIndex].draw.time) - - ctx.globalAlpha = 1 - } - } - - - static renderMeterChangeKnob(state, trackIndex, ctx, time) - { - const rect = TrackMarkers.knobRectForMeterChange(state, time) - - ctx.fillStyle = state.prefs.meterChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - } - - - static renderMeterChange(state, trackIndex, ctx, meterCh) - { - const rect = TrackMarkers.knobRectForMeterChange(state, meterCh.time) - - ctx.fillStyle = state.prefs.meterChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.font = "14px Verdana" - ctx.textAlign = "left" - ctx.textBaseline = "middle" - ctx.fillText( - meterCh.meter.numerator.toString() + " / " + meterCh.meter.denominator.toString(), - rect.x + rect.w + 5, - rect.y + rect.h / 2) - - if (state.tracks[trackIndex].selection.has(meterCh.id)) - { - ctx.globalAlpha = 0.75 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2 - 3, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - - const hover = state.tracks[trackIndex].hover - if (hover && hover.id === meterCh.id) - { - ctx.globalAlpha = 0.5 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - } - - - static renderKeyChangeKnob(state, trackIndex, ctx, time) - { - const rect = TrackMarkers.knobRectForKeyChange(state, time) - - ctx.fillStyle = state.prefs.keyChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - } - - - static renderKeyChange(state, trackIndex, ctx, keyCh) - { - const rect = TrackMarkers.knobRectForKeyChange(state, keyCh.time) - - ctx.fillStyle = state.prefs.keyChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.font = "14px Verdana" - ctx.textAlign = "left" - ctx.textBaseline = "middle" - ctx.fillText(keyCh.key.str, rect.x + rect.w + 5, rect.y + rect.h / 2) - - if (state.tracks[trackIndex].selection.has(keyCh.id)) - { - ctx.globalAlpha = 0.75 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2 - 3, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - - const hover = state.tracks[trackIndex].hover - if (hover && hover.id === keyCh.id) - { - ctx.globalAlpha = 0.5 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - } -} \ No newline at end of file diff --git a/src_old/editor/trackNotes.js b/src_old/editor/trackNotes.js deleted file mode 100644 index 8e4472b..0000000 --- a/src_old/editor/trackNotes.js +++ /dev/null @@ -1,591 +0,0 @@ -import Project from "../project/project.js" -import Editor from "./editor.js" -import Track from "./track.js" -import Rational from "../util/rational.js" -import Range from "../util/range.js" -import Rect from "../util/rect.js" -import Theory from "../theory.ts" -import CanvasUtils from "../util/canvas.js" - - -export default class TrackNotes -{ - static init(state, trackIndex, action) - { - const newTrack = - { - ...Track.init(state, action), - kind: "notes", - rowScale: 15, - } - - return { ...state, - tracks: [ ...state.tracks, newTrack ], - } - } - - - static updateHover(state, trackIndex, input) - { - let hover = null - let draw = null - - if (state.keys[Editor.keyDraw]) - { - const keyCh = state.project.keyChanges.findActiveAt(input.mouse.time) - const key = keyCh ? keyCh.key : Editor.defaultKey() - const row = TrackNotes.rowAtY(state, trackIndex, input.mouse.y, key) - const pitch = TrackNotes.pitchForRow(state, trackIndex, row, key) - draw = - { - kind: "note", - time1: input.mouse.time, - time2: input.mouse.time.add(state.timeSnap.multiply(new Rational(4))), - pitch, - } - } - else - { - const margin = 10 - const checkRange = Editor.timeRangeAtX(state, input.mouse.x - margin, input.mouse.x + margin) - - let hoverPrimary = null - let hoverSecondary = null - - for (const [note, keyCh, xMin, xMax] of TrackNotes.iterNotesAndKeyChangesAtRange(state, trackIndex, checkRange)) - { - const margin = 2 - - const row = TrackNotes.rowForPitch(state, trackIndex, note.pitch, keyCh.key) - const rectExact = TrackNotes.rectForNote(state, trackIndex, note.range, row, xMin, xMax) - const rect = new Rect(rectExact.x - margin, rectExact.y, rectExact.w + margin * 2, rectExact.h) - - const dragMarginOut = Math.abs(Math.min(0, rect.w - 16)) - const stretchMarginOut = 16 - const stretchMarginIn = Math.max(0, Math.min(10, rect.w / 4)) - const rectDrag = new Rect(rect.x - dragMarginOut, rect.y, rect.w + dragMarginOut * 2, rect.h) - const rectStretchStart = new Rect(rect.x - stretchMarginOut, rect.y, stretchMarginOut + stretchMarginIn, rect.h) - const rectStretchEnd = new Rect(rect.x2 - stretchMarginIn, rect.y, stretchMarginOut + stretchMarginIn, rect.h) - - const exactHover = rect.contains(input.mouse) - - let action = 0 - if (dragMarginOut > 0 && rectDrag.contains(input.mouse)) - action = Editor.actionDragTime | Editor.actionDragPitchRow - else if (rectStretchStart.contains(input.mouse) && !rectExact.cutStart) - action = Editor.actionStretchTimeStart - else if (rectStretchEnd.contains(input.mouse) && !rectExact.cutEnd) - action = Editor.actionStretchTimeEnd - else if (exactHover) - action = Editor.actionDragTime | Editor.actionDragPitchRow - - const hoverNote = - { - id: note.id, - range: note.range, - action, - } - - if (action != 0) - { - if (exactHover) - hoverPrimary = hoverNote - else - hoverSecondary = hoverNote - } - - if (hoverPrimary) - break - } - - hover = hoverPrimary || hoverSecondary - } - - return Track.update(state, trackIndex, { hover, draw }) - } - - - static hoveredPlaySoundPreview(state, trackIndex) - { - const hover = state.tracks[trackIndex].hover - if (!hover) - return state - - const id = hover.id - const note = state.project.notes.findById(id) - - if (!note) - return state - - return Editor.soundPreviewSet(state, TrackNotes.mergeSoundPreview(null, note.pitch)) - } - - - static selectionAddAtCursor(state, trackIndex) - { - const timeRange = new Range(state.cursor.time1, state.cursor.time2, false, false).sorted() - - for (const note of state.project.notes.iterAtRange(timeRange)) - state = Track.selectionAdd(state, trackIndex, note.id) - - return state - } - - - static selectionAddAtRect(state, trackIndex) - { - const timeRange = new Range(state.rectSelection.time1, state.rectSelection.time2, false, false).sorted() - const y1 = Math.min(state.rectSelection.y1, state.rectSelection.y2) - const y2 = Math.max(state.rectSelection.y1, state.rectSelection.y2) - - for (const [note, keyCh, xMin, xMax] of TrackNotes.iterNotesAndKeyChangesAtRange(state, trackIndex, timeRange)) - { - const row = TrackNotes.rowForPitch(state, trackIndex, note.pitch, keyCh.key) - const rect = TrackNotes.rectForNote(state, trackIndex, note.range, row, xMin, xMax) - if (y1 < rect.y2 && y2 > rect.y1) - state = Track.selectionAdd(state, trackIndex, note.id) - } - - return state - } - - - static selectionRemoveConflictingBehind(state, trackIndex) - { - const selection = state.tracks[trackIndex].selection - - for (const id of selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - for (const note of state.project.notes.iterAtRange(elem.range)) - { - if (selection.has(note.id)) - continue - - if (note.pitch !== elem.pitch) - continue - - state = { ...state, project: state.project.removeById(note.id) } - - for (const slice of note.range.iterSlices(elem.range)) - { - const newNote = new Project.Note(slice, note.pitch) - state = { ...state, project: state.project.upsertNote(newNote) } - } - } - } - - return state - } - - - static clipboardPaste(state, trackIndex, pasteData) - { - for (const [clipboardId, elem] of state.clipboard.elems) - { - if (elem instanceof Project.Note) - { - const range = elem.range.displace(pasteData.time.subtract(state.clipboard.range.start)) - const note = new Project.Note(range, elem.pitch) - const id = state.project.nextId - state = { ...state, project: state.project.upsertNote(note) } - state = Track.selectionAdd(state, trackIndex, id) - } - } - - return state - } - - - static previousAnchor(state, trackIndex, time) - { - return state.project.notes.findPreviousAnchor(time) - } - - - static deleteRange(state, trackIndex, range) - { - for (const note of state.project.notes.iterAtRange(range)) - { - state = { ...state, project: state.project.removeById(note.id) } - - for (const slice of note.range.iterSlices(range)) - { - const newNote = new Project.Note(slice, note.pitch) - state = { ...state, project: state.project.upsertNote(newNote) } - } - } - - return state - } - - - static pan(state, trackIndex) - { - const pitchRowDelta = -(state.mouse.drag.yDelta / state.tracks[trackIndex].rowScale) - - const yScroll = state.tracks[trackIndex].dragData.yScroll + pitchRowDelta - state = Track.update(state, trackIndex, { yScroll }) - - return state - } - - - static drag(state, trackIndex) - { - const pitchRowDelta = -(state.mouse.drag.yDelta / state.tracks[trackIndex].rowScale) - - let soundPreview = null - - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.tracks[trackIndex].dragData.elems.get(id) - if (!elem) - continue - - let changes = {} - - if (state.mouse.action & Editor.actionDragTime) - changes.range = elem.range.displace(state.mouse.drag.timeDelta) - - if (state.mouse.action & Editor.actionStretchTimeStart) - { - changes.range = elem.range.stretch(state.mouse.drag.timeDelta, state.mouse.dragOrig.range.end, state.mouse.dragOrig.range.start) - if (elem.range.start.compare(state.mouse.dragOrig.range.start) == 0) - changes.range = new Range(changes.range.start.snap(state.timeSnap), changes.range.end) - - changes.range = changes.range.sorted() - } - - if (state.mouse.action & Editor.actionStretchTimeEnd) - { - changes.range = elem.range.stretch(state.mouse.drag.timeDelta, state.mouse.dragOrig.range.start, state.mouse.dragOrig.range.end) - if (elem.range.end.compare(state.mouse.dragOrig.range.end) == 0) - changes.range = new Range(changes.range.start, changes.range.end.snap(state.timeSnap)) - - changes.range = changes.range.sorted() - } - - if (state.mouse.action & Editor.actionDragPitchRow) - { - const keyCh = state.project.keyChanges.findActiveAt(elem.range.start) - const key = keyCh ? keyCh.key : Editor.defaultKey() - const degree = key.octavedDegreeForMidi(elem.pitch) - const newPitch = key.midiForDegree(Math.floor(degree + pitchRowDelta)) - changes.pitch = newPitch - soundPreview = TrackNotes.mergeSoundPreview(soundPreview, newPitch) - } - - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - state = Editor.soundPreviewSet(state, soundPreview) - return state - } - - - static drawMove(state, trackIndex, input) - { - let draw = state.tracks[trackIndex].draw - - if (draw) - { - let time2 = input.mouse.time - if (Math.abs(Editor.xAtTime(state, draw.time1) - Editor.xAtTime(state, time2)) < 5) - time2 = draw.time1.add(state.timeSnap.multiply(new Rational(4))) - - draw = { ...draw, time2 } - } - - return Track.update(state, trackIndex, { draw }) - } - - - static drawEnd(state, trackIndex, input) - { - const draw = state.tracks[trackIndex].draw - if (draw) - { - if (draw.kind == "note") - { - const note = new Project.Note(new Range(draw.time1, draw.time2).sorted(), draw.pitch) - const id = state.project.nextId - state = { ...state, project: state.project.upsertNote(note) } - state = Track.selectionAdd(state, trackIndex, id) - state = Editor.soundPreviewSet(state, TrackNotes.mergeSoundPreview(null, draw.pitch)) - } - } - - return state - } - - - static keyCommandTimeShift(state, trackIndex, commandData) - { - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - let changes = {} - changes.range = elem.range.displace(commandData.timeDelta) - - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - return state - } - - - static keyCommandPitchShift(state, trackIndex, commandData) - { - let soundPreview = null - - for (const id of state.tracks[trackIndex].selection) - { - const elem = state.project.findById(id) - if (!elem) - continue - - let changes = {} - if (commandData.diatonic) - { - const keyCh = state.project.keyChanges.findActiveAt(elem.range.start) - const key = keyCh ? keyCh.key : Editor.defaultKey() - const degree = key.octavedDegreeForMidi(elem.pitch) - const newDegree = degree + commandData.degreeDelta - const newPitch = key.midiForDegree(commandData.degreeDelta >= 0 ? Math.floor(newDegree) : Math.ceil(newDegree)) - changes.pitch = newPitch - } - else - changes.pitch = elem.pitch + commandData.pitchDelta - - soundPreview = TrackNotes.mergeSoundPreview(soundPreview, changes.pitch) - state = { ...state, project: state.project.update(elem.withChanges(changes)) } - } - - state = Editor.soundPreviewSet(state, soundPreview) - return state - } - - - static yForRow(state, trackIndex, row) - { - const track = state.tracks[trackIndex] - return track.rect.h / 2 - (row + 1 + track.yScroll) * track.rowScale - } - - - static rowAtY(state, trackIndex, y, key) - { - const track = state.tracks[trackIndex] - return Math.floor((track.rect.h / 2 - y) / track.rowScale - track.yScroll) - } - - - static rowForPitch(state, trackIndex, pitch, key) - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.octavedDegreeForMidi(pitch - 60) + tonicRowOffset - } - - - static pitchForRow(state, trackIndex, row, key) - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.midiForDegree(row - Math.floor(tonicRowOffset)) + 60 - } - - - static mergeSoundPreview(soundPreview, pitch) - { - if (soundPreview && soundPreview.pitch >= pitch) - return soundPreview - - return { kind: "note", pitch } - } - - - static rectForNote(state, trackIndex, range, row, xStart, xEnd) - { - const track = state.tracks[trackIndex] - - const noteOrigX1 = Editor.xAtTime(state, range.start) - const noteOrigX2 = Editor.xAtTime(state, range.end) - - const noteY = TrackNotes.yForRow(state, trackIndex, row) - - let noteX1 = Math.max(noteOrigX1, xStart) - let noteX2 = Math.min(noteOrigX2, xEnd) - - const cutStart = noteOrigX1 < noteX1 - const cutEnd = noteOrigX2 > noteX2 - - if (!cutStart) noteX1 += 1 - if (!cutEnd) noteX2 -= 1 - - const noteW = Math.max(2, noteX2 - noteX1) - - return Object.assign(new Rect(noteX1, noteY, noteW, track.rowScale), { cutStart, cutEnd }) - } - - - static *iterKeyChangesAtRange(state, trackIndex, range) - { - const defaultKey = Editor.defaultKey() - - for (const pair of state.project.keyChanges.iterActiveAtRangePairwise(range)) - { - const keyCh1 = pair[0] || new Project.KeyChange(range.start, defaultKey) - const keyCh2 = pair[1] || new Project.KeyChange(range.end, defaultKey) - - const keyCh1X = Editor.xAtTime(state, keyCh1.time) - const keyCh2X = Editor.xAtTime(state, keyCh2.time) - - yield [keyCh1, keyCh1X, keyCh2X] - } - } - - - static *iterNotesAndKeyChangesAtRange(state, trackIndex, range) - { - const defaultKey = Editor.defaultKey() - - for (const pair of state.project.keyChanges.iterActiveAtRangePairwise(range)) - { - const keyCh1 = pair[0] || new Project.KeyChange(range.start, defaultKey) - const keyCh2 = pair[1] || new Project.KeyChange(range.end, defaultKey) - - const keyCh1X = Editor.xAtTime(state, keyCh1.time) - const keyCh2X = Editor.xAtTime(state, keyCh2.time) - - const time1 = keyCh1.time.max(range.start) - const time2 = keyCh2.time.min(range.end) - - for (const note of state.project.notes.iterAtRange(new Range(time1, time2))) - yield [note, keyCh1, keyCh1X, keyCh2X] - } - } - - - static render(state, trackIndex, ctx) - { - const track = state.tracks[trackIndex] - const visibleTimeRange = Editor.visibleTimeRange(state) - - for (const [keyCh, xMin, xMax] of TrackNotes.iterKeyChangesAtRange(state, trackIndex, visibleTimeRange)) - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(keyCh.key.tonic.chroma) - - const rowAtTop = TrackNotes.rowAtY(state, trackIndex, 0) - const rowAtBottom = TrackNotes.rowAtY(state, trackIndex, track.rect.h) - - const octaveAtTop = Math.ceil(rowAtTop / 7) + 1 - const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1 - - for (let i = octaveAtBottom; i <= octaveAtTop; i++) - { - const y = TrackNotes.yForRow(state, trackIndex, tonicRowOffset + i * 7) + track.rowScale - - ctx.strokeStyle = "#000" - ctx.beginPath() - ctx.moveTo(xMin, y) - ctx.lineTo(xMax, y) - ctx.stroke() - - for (let j = 2; j < 7; j += 2) - { - const ySuboctave = TrackNotes.yForRow(state, trackIndex, tonicRowOffset + i * 7 + j) + track.rowScale - - ctx.globalAlpha = 0.025 - ctx.fillStyle = "#000" - ctx.fillRect(xMin, ySuboctave, xMax - xMin, track.rowScale) - ctx.globalAlpha = 1 - } - - if (i == 0) - { - ctx.globalAlpha = 0.05 - ctx.fillStyle = "#fff" - ctx.fillRect(xMin, y - 7 * track.rowScale, xMax - xMin, 7 * track.rowScale) - ctx.globalAlpha = 1 - } - } - } - - for (const [note, keyCh, xMin, xMax] of TrackNotes.iterNotesAndKeyChangesAtRange(state, trackIndex, visibleTimeRange)) - { - if (!state.playback.playing && track.selection.has(note.id)) - continue - - const row = TrackNotes.rowForPitch(state, trackIndex, note.pitch, keyCh.key) - const mode = keyCh.key.scale.metadata.mode - const fillStyle = CanvasUtils.fillStyleForDegree(ctx, keyCh.key.degreeForMidi(note.pitch) + mode) - const hovering = track.hover && track.hover.id == note.id - const playing = state.playback.playing && note.range.overlapsPoint(state.playback.time) - TrackNotes.renderNote(state, trackIndex, ctx, note.range, row, xMin, xMax, fillStyle, hovering, false, playing) - } - - if (!state.playback.playing) - { - for (const [note, keyCh, xMin, xMax] of TrackNotes.iterNotesAndKeyChangesAtRange(state, trackIndex, visibleTimeRange)) - { - if (!track.selection.has(note.id)) - continue - - const row = TrackNotes.rowForPitch(state, trackIndex, note.pitch, keyCh.key) - const mode = keyCh.key.scale.metadata.mode - const fillStyle = CanvasUtils.fillStyleForDegree(ctx, keyCh.key.degreeForMidi(note.pitch) + mode) - const hovering = track.hover && track.hover.id == note.id - TrackNotes.renderNote(state, trackIndex, ctx, note.range, row, xMin, xMax, fillStyle, hovering, true, false) - } - } - - const draw = state.tracks[trackIndex].draw - if (draw) - { - ctx.globalAlpha = 0.6 - - const keyCh = state.project.keyChanges.findActiveAt(draw.time1) - const key = keyCh ? keyCh.key : Editor.defaultKey() - const row = TrackNotes.rowForPitch(state, trackIndex, draw.pitch, key) - const mode = key.scale.metadata.mode - const fillStyle = CanvasUtils.fillStyleForDegree(ctx, key.degreeForMidi(draw.pitch) + mode) - TrackNotes.renderNote(state, trackIndex, ctx, new Range(draw.time1, draw.time2).sorted(), row, -Infinity, Infinity, fillStyle) - - ctx.globalAlpha = 1 - } - } - - - static renderNote(state, trackIndex, ctx, range, row, xMin, xMax, fillStyle, hovering, selected, playing) - { - const rect = TrackNotes.rectForNote(state, trackIndex, range, row, xMin, xMax) - - ctx.fillStyle = fillStyle - - ctx.beginPath() - ctx.fillRect(rect.x, rect.y, rect.w, rect.h) - - if (hovering) - { - ctx.globalAlpha = 0.4 - ctx.fillStyle = "#fff" - ctx.fillRect(rect.x, rect.y, rect.w, rect.h) - ctx.globalAlpha = 1 - } - - if (selected || playing) - { - const margin = 3 - ctx.globalAlpha = 0.6 - ctx.fillStyle = "#fff" - ctx.fillRect(rect.x, rect.y + margin, rect.w, rect.h - margin * 2) - ctx.globalAlpha = 1 - } - } -} \ No newline at end of file diff --git a/src_old/editor2/EditorContent.tsx b/src_old/editor2/EditorContent.tsx deleted file mode 100644 index a8d0e9e..0000000 --- a/src_old/editor2/EditorContent.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React from "react" -import Editor from "./editor" -import EditorState from "./editorState" -import { AppState, AppReducer, ContentManager } from "../AppState" -import { useAppManager } from "../AppContext" -import Rect from "../util/rect" - - -interface EditorContentProps -{ - contentId: number - rect: Rect -} - - -export function EditorContent(props: EditorContentProps) -{ - const appManager = useAppManager() - const contentCtx = appManager.makeContentManager(props.contentId) - - const refDiv = React.useRef(null) - const refCanvas = React.useRef(null) - const needsResetView = React.useRef(true) - - const transformMousePos = (canvas: HTMLCanvasElement, ev: MouseEvent) => - { - const rect = canvas.getBoundingClientRect() - return { - x: (ev.clientX - rect.left), - y: (ev.clientY - rect.top) - } - } - - const resize = (contentCtx: ContentManager) => - { - if (!refDiv.current) - return - - const rect = refDiv.current!.getBoundingClientRect() - const x = Math.floor(rect.x) - const y = Math.floor(rect.y) - const w = Math.floor(rect.width) - const h = Math.floor(rect.height) - - refCanvas.current!.style.width = w + "px" - refCanvas.current!.style.height = h + "px" - refCanvas.current!.width = w - refCanvas.current!.height = h - - Editor.resize(contentCtx, { x, y, w, h }) - Editor.tracksRefresh(contentCtx) - } - - React.useEffect(() => - { - resize(contentCtx) - contentCtx.dispatch() - - }, [props.rect]) - - React.useEffect(() => - { - if (!refCanvas.current) - return - - const refresh = () => - { - if (!contentCtx.contentState || contentCtx.contentState.tracks.length == 0) - resize(contentCtx) - } - - const preventDefault = (ev: Event) => ev.preventDefault() - - const onMouseMove = (ev: MouseEvent) => - { - refresh() - const pos = transformMousePos(refCanvas.current!, ev) - Editor.reduce_mouseMove(contentCtx, { pos }) - contentCtx.dispatch() - } - - const onMouseDown = (ev: MouseEvent) => - { - //if (window.document.activeElement) - // window.document.activeElement.blur() - - refresh() - ev.preventDefault() - const pos = transformMousePos(refCanvas.current!, ev) - - Editor.reduce_mouseMove(contentCtx, { pos }) - Editor.reduce_mouseDown(contentCtx, { rightButton: ev.button != 0, ctrlKey: ev.ctrlKey }) - contentCtx.dispatch() - } - - const onMouseUp = (ev: MouseEvent) => - { - refresh() - const pos = transformMousePos(refCanvas.current!, ev) - Editor.reduce_mouseMove(contentCtx, { pos }) - Editor.reduce_mouseUp(contentCtx, { }) - Editor.reduce_mouseMove(contentCtx, { pos }) - contentCtx.dispatch() - } - - const onMouseWheel = (ev: MouseWheelEvent) => - { - refresh() - ev.preventDefault() - Editor.reduce_mouseWheel(contentCtx, { deltaX: ev.deltaX, deltaY: ev.deltaY }) - contentCtx.dispatch() - } - - const onKeyDown = (ev: KeyboardEvent) => - { - refresh() - Editor.reduce_keyDown(contentCtx, { key: ev.key.toLowerCase() }) - Editor.reduce_keyCommand(contentCtx, { - ev, - key: ev.key.toLowerCase(), - ctrlKey: ev.ctrlKey, - shiftKey: ev.shiftKey, - }) - contentCtx.dispatch() - } - - const onKeyUp = (ev: KeyboardEvent) => - { - refresh() - Editor.reduce_keyUp(contentCtx, { key: ev.key.toLowerCase() }) - contentCtx.dispatch() - } - - window.addEventListener("mousemove", onMouseMove) - window.addEventListener("mouseup", onMouseUp) - window.addEventListener("keydown", onKeyDown) - window.addEventListener("keyup", onKeyUp) - - refCanvas.current!.addEventListener("mousedown", onMouseDown) - refCanvas.current!.addEventListener("wheel", onMouseWheel) - refCanvas.current!.addEventListener("mouseup", preventDefault) - refCanvas.current!.addEventListener("contextmenu", preventDefault) - - return () => - { - window.removeEventListener("mousemove", onMouseMove) - window.removeEventListener("mouseup", onMouseUp) - window.removeEventListener("keydown", onKeyDown) - window.removeEventListener("keyup", onKeyUp) - - if (!refCanvas.current) - return - - refCanvas.current!.removeEventListener("mousedown", onMouseDown) - refCanvas.current!.removeEventListener("wheel", onMouseWheel) - refCanvas.current!.removeEventListener("mouseup", preventDefault) - refCanvas.current!.removeEventListener("contextmenu", preventDefault) - } - - }, [refCanvas.current, props.contentId]) - - React.useEffect(() => - { - if (!refCanvas.current) - return - - Editor.render(contentCtx, refCanvas.current!.getContext("2d")!) - - const mouseAction = - contentCtx.contentState.mouse.action || - (contentCtx.contentState.mouse.hover && contentCtx.contentState.mouse.hover.action)! - - if (contentCtx.contentState.tracks.some((tr: any) => !!tr.draw) || mouseAction & (Editor.actionDraw)) - refCanvas.current!.style.cursor = "crosshair" - else if (mouseAction & (Editor.actionDragTime)) - refCanvas.current!.style.cursor = (contentCtx.contentState.mouse.down ? "grabbing" : "grab") - else if (mouseAction & (Editor.actionPan)) - refCanvas.current!.style.cursor = "move" - else if (mouseAction & (Editor.actionStretchTimeStart | Editor.actionStretchTimeEnd)) - refCanvas.current!.style.cursor = "col-resize" - else - refCanvas.current!.style.cursor = "text" - - }, [refCanvas.current, contentCtx.appState]) - - React.useEffect(() => - { - if (!contentCtx.contentState || contentCtx.contentState.tracks.length == 0) - { - window.requestAnimationFrame(() => - { - resize(contentCtx) - contentCtx.dispatch() - }) - return - } - - }, [props.contentId]) - - - return ( -
- - - { contentCtx.contentState.tracks.map((track, i) => -
- Track Name -
- )} -
- ) -} \ No newline at end of file diff --git a/src_old/editor2/InspectorContent.tsx b/src_old/editor2/InspectorContent.tsx deleted file mode 100644 index f62d6d4..0000000 --- a/src_old/editor2/InspectorContent.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import React from "react" -import ButtonList from "../toolbox/ButtonList" -import DropdownMenu from "../toolbox/DropdownMenu" -import Editor from "./editor" -import { AppState } from "../AppState" -import Rect from "../util/rect" -import Project from "../project/project2" -import * as Theory from "../theory/theory" -import { useAppManager } from "../AppContext" - - -interface InspectorContentProps -{ - contentId: number - rect: Rect -} - - -interface InspectorState -{ - elemIds: Project.ID[] -} - - -export default function InspectorContent(props: InspectorContentProps) -{ - const appManager = useAppManager() - const contentCtx = appManager.makeContentManager(props.contentId) - - - const elem = contentCtx.appState.project.elems.get(contentCtx.contentState.elemIds[0]) - if (!elem) - return null - - - const keyCh = elem as Project.KeyChange - const key = keyCh.key - - - const chromaticOptions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map(chroma => - { - chroma = Theory.Utils.mod(chroma + key.tonic.chroma, 12) - return { - label: key.nameForChroma(chroma).str, - value: chroma, - bkgColor: Theory.Utils.degreeToColor(key.degreeForChroma(chroma)), - width: "2em", - } - }) - - - const chromaticSelected = [0, 1, 2, 3, 4, 5, 6].map(degree => key.chromaForDegree(degree)) - - - const tonicLetterOptions = [0, 4, 1, 5, 2, 6, 3].map(letter => - { - return { - label: Theory.Utils.letterToStr(letter), - value: letter, - } - }) - - - const tonicAccidentalOptions = [-1, 0, 1].map(acc => - { - return { - label: acc == 0 ? "♮" : Theory.Utils.accidentalToStr(acc), - value: acc, - } - }) - - - const scaleOptions = Theory.Scale.list.map(scale => - { - return { - label: scale.names[0], - value: scale.id, - } - }) - - - const onChangeTonicLetter = (item: any) => - { - const tonic = new Theory.PitchName(item.value, key.tonic.accidental) - const newKey = new Theory.Key(tonic, key.scale) - changeKey(newKey) - } - - - const onChangeTonicAccidental = (item: any) => - { - const tonic = new Theory.PitchName(key.tonic.letter, item.value) - const newKey = new Theory.Key(tonic, key.scale) - changeKey(newKey) - } - - - const onChangeScale = (item: any) => - { - const scale = Theory.Scale.fromId(item.value) - const newKey = new Theory.Key(key.tonic, scale) - changeKey(newKey) - } - - - const changeKey = (newKey: Theory.Key) => - { - const newKeyCh = Project.Element.withChanges(keyCh, { key: newKey }) - const project = Project.upsertTimedElement(appManager.appState.project, newKeyCh) - appManager.mergeAppState({ project }) - appManager.dispatch() - } - - - return
- -
- [Key Change]
- { (elem as Project.KeyChange).key.str } -
- -
-
- Tonic -
- - - -
- Accidental -
- - - -
- Scale -
- - - -
-
- -
- Pitches -
- - {} } - /> - -
- -
-} \ No newline at end of file diff --git a/src_old/editor2/TrackInstrumentContent.tsx b/src_old/editor2/TrackInstrumentContent.tsx deleted file mode 100644 index 55612bd..0000000 --- a/src_old/editor2/TrackInstrumentContent.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import React from "react" -import ButtonList from "../toolbox/ButtonList" -import DropdownMenu from "../toolbox/DropdownMenu" -import Editor from "./editor" -import { AppState } from "../AppState" -import Rect from "../util/rect" -import Project from "../project/project2" -import * as Theory from "../theory/theory" -import { useAppManager } from "../AppContext" -import ListBox from "../toolbox/ListBox" - - -interface TrackInstrumentContentProps -{ - contentId: number - rect: Rect -} - - -interface TrackInstrumentContentState -{ - elemIds: Project.ID[] -} - - -function getMidiIcon(midiBank: number, midiPreset: number): string -{ - if (midiBank == 128) // Percussion - return "🥁" - - if (midiPreset <= 7) // Piano - return "🎹" - else if (midiPreset <= 15) // Chromatic Percussion - return "🔔" - else if (midiPreset <= 23) // Organ - return "💨" - else if (midiPreset <= 31) // Guitar - return "🎸" - else if (midiPreset <= 39) // Bass - return "🎸" - else if (midiPreset <= 47) // Strings - return "🎻" - else if (midiPreset <= 55) // Ensemble - return "🎻" - else if (midiPreset <= 63) // Brass - return "🎺" - else if (midiPreset <= 71) // Reed - return "🎷" - else if (midiPreset <= 79) // Pipe - return "✏️" - else if (midiPreset <= 87) // Synth Lead - return "🕹️" - else if (midiPreset <= 95) // Synth Pad - return "🕹️" - else if (midiPreset <= 103) // Synth FX - return "🕹️" - else if (midiPreset <= 111) // Ethnic - return "🪕" - else if (midiPreset <= 119) // Percussive - return "🥁" - else if (midiPreset <= 127) // Sound FX - return "🔊" - else - return "🎹" -} - - -export default function TrackInstrumentContent(props: TrackInstrumentContentProps) -{ - const appManager = useAppManager() - const contentCtx = appManager.makeContentManager(props.contentId) - - - const elem = contentCtx.appState.project.elems.get(contentCtx.contentState.elemIds[0]) - if (!elem) - return null - - const track = elem as Project.Track - if (track.trackType != Project.TrackType.Notes) - return null - - const trackNotes = track as Project.TrackNotes - const trackInstr = trackNotes.instrument as Project.TrackInstrumentSflib - const sflibMeta = appManager.appState.sflib - const sflibCurrentColl = sflibMeta.collections.find(coll => coll.id == trackInstr.collectionId)! - const sflibCurrentInstr = sflibCurrentColl.instruments.find(instr => instr.id == trackInstr.instrumentId)! - - - const onChange = (collectionId: string, instrumentId: string) => - { - const newTrack = Project.TrackNotes.withChanges(trackNotes, { - instrument: { - ...trackNotes.instrument, - collectionId, - instrumentId, - } - }) - - const newProject = Project.upsertTrack(contentCtx.appState.project, newTrack) - contentCtx.appManager.mergeAppState({ project: newProject }) - contentCtx.appManager.dispatch() - } - - - return
- -
- -
- Collection -
- -
- Instrument -
- - onChange(item.value, sflibMeta.collections.find(coll => coll.id == item.value)!.instruments[0].id) } - items={ sflibMeta.collections.map(coll => - { - return { - value: coll.id, - label: coll.name, - } - })} - /> - - onChange(sflibCurrentColl.id, item.value) } - items={ sflibCurrentColl.instruments.map(instr => - { - return { - value: instr.id, - label: - getMidiIcon(instr.midiBank, instr.midiPreset) + " " + - //instr.midiBank.toString().padStart(3, "0") + "." + - //instr.midiPreset.toString().padStart(3, "0") + " : " + - instr.name, - } - })} - /> - -
- -
-} \ No newline at end of file diff --git a/src_old/editor2/TrackPopup.tsx b/src_old/editor2/TrackPopup.tsx deleted file mode 100644 index 68d4a43..0000000 --- a/src_old/editor2/TrackPopup.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from "react" -import PopupButton from "../popup/PopupButton" -import Rect from "../util/rect" - - -interface TrackPopupProps -{ -} - - -export default function TrackPopup(props: TrackPopupProps) -{ - return <> - - - -} \ No newline at end of file diff --git a/src_old/editor2/editor.ts b/src_old/editor2/editor.ts deleted file mode 100644 index 4c45da9..0000000 --- a/src_old/editor2/editor.ts +++ /dev/null @@ -1,1392 +0,0 @@ -import { ContentManager, AppReducer } from "../AppState" -import EditorState, { EditorMode } from "./editorState" -import Track from "./track" -import TrackState from "./trackState" -import TrackStateManager from "./trackStateManager" -import TrackKeyChanges from "./trackKeyChanges" -import TrackMeterChanges from "./trackMeterChanges" -import Project from "../project/project2" -import Rational from "../util/rational" -import Range from "../util/range" -import Rect from "../util/rect" -import * as Theory from "../theory/theory" -import DockableData from "../dockable/state" -import { stat } from "fs" -import TrackPopup from "./TrackPopup" - - -export default class Editor -{ - static actionPan = 0x01 - static actionSelectCursor = 0x02 - static actionSelectRect = 0x04 - static actionDraw = 0x08 - static actionDragTime = 0x10 - static actionDragPitchRow = 0x20 - static actionStretchTimeStart = 0x40 - static actionStretchTimeEnd = 0x80 - - - static makeNewFull(): EditorState - { - return { - mode: EditorMode.Full, - modeTracks: [], - - x: 0, - y: 0, - w: 0, - h: 0, - - trackHeaderW: 200, - - tracks: [], - trackScroll: 0, - - timeScroll: -0.5, - timeScale: 100, - timeSnap: new Rational(1, 16), - timeSnapBase: new Rational(1, 16), - - cursor: - { - visible: true, - time1: new Rational(0), - time2: new Rational(0), - track1: 0, - track2: 0, - }, - - rectCursor: - { - track: 0, - time1: new Rational(0), - time2: new Rational(0), - y1: 0, - y2: 0, - }, - - keys: {}, - - mouse: - { - down: false, - downDate: new Date(), - - action: 0, - - pos: { x: 0, y: 0 }, - posPrev: { x: 0, y: 0 }, - time: new Rational(0), - track: 0, - trackPos: { x: 0, y: 0 }, - trackYRaw: 0, - row: 0, - - hover: null, - - drag: { - xLocked: true, - yLocked: true, - - posOrigin: { x: 0, y: 0 }, - timeOrigin: new Rational(0), - timeScrollOrigin: 0, - rangeOrigin: new Range(new Rational(), new Rational()), - trackOrigin: 0, - trackScrollOrigin: 0, - trackPosOrigin: { x: 0, y: 0 }, - trackYRawOrigin: 0, - trackYScrollOrigin: 0, - rowOrigin: 0, - projectOrigin: Project.getDefault(), - - posDelta: { x: 0, y: 0 }, - timeDelta: new Rational(0), - trackPosDelta: { x: 0, y: 0 }, - rowDelta: 0, - }, - - wheelDate: new Date(), - }, - } - } - - - static makeNewNoteEditor(trackIds: number[]): EditorState - { - const state = Editor.makeNewFull() - state.mode = EditorMode.NoteEditor - state.modeTracks = trackIds - return state - } - - - static init(state: ContentManager) - { - state.contentState = Editor.makeNewFull() - } - - - static resize(state: ContentManager, action: any) - { - state.mergeContentState({ - x: action.x, - y: action.y, - w: action.w, - h: action.h, - }) - } - - - static tracksRefresh(state: ContentManager) - { - const tracks: TrackState[] = [] - - for (let t = 0; t < state.appState.project.tracks.length; t++) - { - const track = state.appState.project.tracks[t] - if (track.trackType == Project.TrackType.Notes) - { - if (state.contentState.mode == EditorMode.Full) - tracks.push({ - type: "notesPreview", - trackIndex: t, - trackId: track.id, - y: 0, - h: 40, - yScroll: 0, - pinned: false, - }) - else if (state.contentState.modeTracks.some(t => t == track.id)) - tracks.push({ - type: "notes", - trackIndex: t, - trackId: track.id, - y: 0, - h: 0, - yScroll: 0, - pinned: false, - }) - } - else if (track.trackType == Project.TrackType.KeyChanges) - tracks.push({ - type: "keyChanges", - trackIndex: t, - trackId: track.id, - y: 0, - h: TrackKeyChanges.knobHeight, - yScroll: 0, - pinned: false, - }) - else if (track.trackType == Project.TrackType.MeterChanges) - tracks.push({ - type: "meterChanges", - trackIndex: t, - trackId: track.id, - y: 0, - h: TrackMeterChanges.knobHeight, - yScroll: 0, - pinned: false, - }) - } - - let fixedH = 0 - for (let t = 0; t < tracks.length; t++) - { - if (tracks[t].h > 0) - fixedH += tracks[t].h - } - - for (let t = 0; t < tracks.length; t++) - { - if (tracks[t].h == 0) - tracks[t].h = state.contentState.h - fixedH - } - - let y = 0 - for (let t = 0; t < tracks.length; t++) - { - tracks[t].y = y - y += tracks[t].h - } - - state.mergeContentState({ tracks }) - - for (let t = 0; t < state.contentState.tracks.length; t++) - Track.execute("init", state, t) - } - - - static reduce_keyDown(state: ContentManager, action: any) - { - state.mergeContentState({ - keys: { ...state.contentState.keys, [action.key]: true }, - }) - } - - - static reduce_keyUp(state: ContentManager, action: any) - { - let keys = { ...state.contentState.keys } - delete keys[action.key] - - state.mergeContentState({ keys }) - } - - - static reduce_keyCommand(state: ContentManager, action: any) - { - - } - - - static reduce_mouseMove(state: ContentManager, action: any) - { - const track = Editor.trackAtY(state, state.contentState.mouse.pos.y) - const trackDrag = !state.contentState.mouse.down ? track : state.contentState.mouse.drag.trackOrigin - - const trackX = action.pos.x - state.contentState.trackHeaderW - const trackYRaw = state.contentState.mouse.pos.y - Editor.trackY(state, trackDrag) - const trackY = trackYRaw + state.contentState.tracks[trackDrag].yScroll - const trackPos = { x: trackX, y: trackY } - - const row = Track.execute("rowAtY", state, trackDrag, trackY) - - state.mergeContentState({ - mouse: { - ...state.contentState.mouse, - pos: action.pos, - posPrev: state.contentState.mouse.pos, - time: Editor.timeAtX(state, trackX), - track, - trackPos, - trackYRaw, - row, - } - }) - - if (!state.contentState.mouse.down) - { - state.mergeContentState({ - mouse: { - ...state.contentState.mouse, - hover: null, - } - }) - - if (state.contentState.keys[state.appState.prefs.editor.keyDraw]) - { - for (let t = 0; t < state.contentState.tracks.length; t++) - { - if (t == state.contentState.mouse.track) - Track.execute("drawHover", state, t) - else - Track.execute("drawClear", state, t) - } - } - else - { - for (let t = 0; t < state.contentState.tracks.length; t++) - { - Track.execute("drawClear", state, t) - - if (t == state.contentState.mouse.track) - Track.execute("hover", state, t) - } - } - } - else - { - const posDelta = { - x: state.contentState.mouse.pos.x - state.contentState.mouse.drag.posOrigin.x, - y: state.contentState.mouse.pos.y - state.contentState.mouse.drag.posOrigin.y, - } - - const timeDelta = - state.contentState.mouse.time.subtract(state.contentState.mouse.drag.timeOrigin) - - const trackPosDelta = { - x: state.contentState.mouse.trackPos.x - state.contentState.mouse.drag.trackPosOrigin.x, - y: state.contentState.mouse.trackPos.y - state.contentState.mouse.drag.trackPosOrigin.y, - } - - const rowDelta = state.contentState.mouse.row - state.contentState.mouse.drag.rowOrigin - - const xLocked = state.contentState.mouse.drag.xLocked && Math.abs(posDelta.x) < state.appState.prefs.editor.mouseDragXLockedDistance - const yLocked = state.contentState.mouse.drag.yLocked && Math.abs(posDelta.y) < state.appState.prefs.editor.mouseDragYLockedDistance - - state.mergeContentState({ - mouse: { - ...state.contentState.mouse, - drag: { - ...state.contentState.mouse.drag, - xLocked, - yLocked, - posDelta, - timeDelta, - trackPosDelta, - rowDelta, - }, - }, - }) - - if (state.contentState.mouse.action == Editor.actionPan) - { - state.mergeContentState({ - timeScroll: state.contentState.mouse.drag.timeScrollOrigin - state.contentState.mouse.drag.posDelta.x / state.contentState.timeScale, - }) - - if (state.contentState.mouse.drag.posOrigin.x > state.contentState.trackHeaderW && - Track.execute("yScrollEnabled", state, state.contentState.mouse.drag.trackOrigin)) - { - const trackState = new TrackStateManager(state, state.contentState.mouse.drag.trackOrigin) - const yScroll = - state.contentState.mouse.drag.trackYScrollOrigin - - state.contentState.mouse.drag.posDelta.y - - trackState.mergeTrackState({ yScroll }) - } - else - { - const lastTrack = state.contentState.tracks[state.contentState.tracks.length - 1] - const trackScroll = - Math.max(0, - Math.min( - lastTrack.y + lastTrack.h - state.contentState.h, - state.contentState.mouse.drag.trackScrollOrigin - state.contentState.mouse.drag.posDelta.y)) - - state.mergeContentState({ trackScroll }) - } - } - else if (state.contentState.mouse.action == Editor.actionSelectCursor) - { - Editor.cursorDrag(state, state.contentState.mouse.time, state.contentState.mouse.track) - Editor.selectionClear(state) - Editor.selectionAddAtCursor(state) - Editor.handleEdgeScroll(state, false) - } - else if (state.contentState.mouse.action == Editor.actionSelectRect) - { - state.mergeContentState({ - rectCursor: { ...state.contentState.rectCursor, - time2: state.contentState.mouse.time, - y2: state.contentState.mouse.trackPos.y, - }, - }) - - Editor.selectionClear(state) - Editor.selectionAddAtRectCursor(state) - Editor.handleEdgeScroll(state, true) - } - else if (state.contentState.mouse.action == Editor.actionDraw) - { - Track.execute("drawDrag", state, state.contentState.mouse.drag.trackOrigin) - Editor.handleEdgeScroll(state, false) - } - else - { - Editor.drag(state) - Editor.handleEdgeScroll(state, true) - } - } - } - - - static drag(state: ContentManager) - { - let mouseActionBlocked = 0 - if (state.contentState.mouse.drag.xLocked) - mouseActionBlocked |= Editor.actionDragTime | Editor.actionStretchTimeEnd | Editor.actionStretchTimeStart - - if (state.contentState.mouse.drag.yLocked) - mouseActionBlocked |= Editor.actionDragPitchRow - - const mouseAction = state.contentState.mouse.action & ~mouseActionBlocked - const mouseDrag = state.contentState.mouse.drag - - for (const id of state.appState.selection) - { - const elem = mouseDrag.projectOrigin.elems.get(id) - if (!elem) - continue - - let changes: any = {} - - if (elem.type == Project.ElementType.Note) - { - const rangedElem = elem as any as Project.RangedElement - - if (mouseAction & Editor.actionDragTime) - changes.range = rangedElem.range.displace(mouseDrag.timeDelta) - - if (mouseAction & Editor.actionStretchTimeStart) - { - changes.range = rangedElem.range.stretch(mouseDrag.timeDelta, mouseDrag.rangeOrigin.end, mouseDrag.rangeOrigin.start) - if (rangedElem.range.start.compare(mouseDrag.rangeOrigin.start) == 0) - changes.range = new Range(changes.range.start.snap(state.contentState.timeSnap), changes.range.end) - - changes.range = changes.range.sorted() - } - - if (mouseAction & Editor.actionStretchTimeEnd) - { - changes.range = rangedElem.range.stretch(mouseDrag.timeDelta, mouseDrag.rangeOrigin.start, mouseDrag.rangeOrigin.end) - if (rangedElem.range.end.compare(mouseDrag.rangeOrigin.end) == 0) - changes.range = new Range(changes.range.start, changes.range.end.snap(state.contentState.timeSnap)) - - changes.range = changes.range.sorted() - } - - if (mouseAction & Editor.actionDragPitchRow) - { - const note = rangedElem as Project.Note - const key = Editor.keyAt(state, state.contentState.tracks[state.contentState.mouse.drag.trackOrigin].trackId, rangedElem.range.start) - const degree = key.octavedDegreeForMidi(note.pitch) - const newPitch = key.midiForDegree(Math.floor(degree + mouseDrag.rowDelta)) - changes.pitch = newPitch - } - - const newRangedElem = Project.RangedElement.withChanges(rangedElem, changes) - - state.mergeAppState({ - project: Project.upsertRangedElement(state.appState.project, newRangedElem) - }) - } - - else if (elem.type == Project.ElementType.KeyChange || - elem.type == Project.ElementType.MeterChange) - { - const timedElem = elem as any as Project.TimedElement - - if (mouseAction & Editor.actionDragTime) - changes.time = timedElem.time.add(mouseDrag.timeDelta).snap(state.contentState.timeSnap) - - if (mouseAction & Editor.actionStretchTimeStart) - { - changes.time = timedElem.time.stretch(mouseDrag.timeDelta, mouseDrag.rangeOrigin.end, mouseDrag.rangeOrigin.start) - if (timedElem.time.compare(mouseDrag.rangeOrigin.start) == 0) - changes.time = changes.time.snap(state.contentState.timeSnap) - } - - if (mouseAction & Editor.actionStretchTimeEnd) - { - changes.time = timedElem.time.stretch(mouseDrag.timeDelta, mouseDrag.rangeOrigin.start, mouseDrag.rangeOrigin.end) - if (timedElem.time.compare(mouseDrag.rangeOrigin.start) == 0) - changes.time = changes.time.snap(state.contentState.timeSnap) - } - - const newTimedElem = Project.TimedElement.withChanges(timedElem, changes) - - state.mergeAppState({ - project: Project.upsertTimedElement(state.appState.project, newTimedElem) - }) - } - } - } - - - static reduce_mouseDown(state: ContentManager, action: any) - { - if (state.contentState.mouse.down) - return - - const now = new Date() - const timeSinceLastDown = now.getTime() - state.contentState.mouse.downDate.getTime() - const isDoubleClick = timeSinceLastDown < 250 - - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - down: true, - downDate: now, - drag: { ...state.contentState.mouse.drag, - xLocked: true, - yLocked: true, - posOrigin: state.contentState.mouse.pos, - timeOrigin: state.contentState.mouse.time, - timeScrollOrigin: state.contentState.timeScroll, - trackScrollOrigin: state.contentState.trackScroll, - trackOrigin: state.contentState.mouse.track, - trackPosOrigin: state.contentState.mouse.trackPos, - trackYRawOrigin: state.contentState.mouse.trackYRaw, - trackYScrollOrigin: state.contentState.tracks[state.contentState.mouse.track].yScroll, - rowOrigin: state.contentState.mouse.row, - projectOrigin: state.appState.project, - }, - action: 0, - } - }) - - Editor.popupClear(state) - - if (action.rightButton || state.contentState.keys[state.appState.prefs.editor.keyPan]) - { - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - action: Editor.actionPan - } - }) - } - else if (state.contentState.keys[state.appState.prefs.editor.keySelectRect]) - { - Editor.cursorSetVisible(state, false) - - state.mergeContentState({ - rectCursor: { - track: state.contentState.mouse.track, - time1: state.contentState.mouse.time, - time2: state.contentState.mouse.time, - y1: state.contentState.mouse.trackPos.y, - y2: state.contentState.mouse.trackPos.y, - }, - mouse: { ...state.contentState.mouse, - action: Editor.actionSelectRect, - } - }) - } - else if (state.contentState.keys[state.appState.prefs.editor.keyDraw]) - { - Editor.cursorSetVisible(state, false) - Editor.selectionClear(state) - Track.execute("drawStart", state, state.contentState.mouse.track) - - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - action: Editor.actionDraw, - } - }) - } - else - { - const selectMultiple = state.contentState.keys[state.appState.prefs.editor.keySelectMultiple] - - if (isDoubleClick && state.contentState.mode == EditorMode.Full) - { - let noteEditorState = Editor.makeNewNoteEditor([state.contentState.tracks[state.contentState.mouse.track].trackId]) - noteEditorState.timeScale = state.contentState.timeScale - noteEditorState.timeScroll = state.contentState.timeScroll - - state.appState = AppReducer.createOrUpdateTab( - state.appState, state.contentId, - "editorNotes", noteEditorState) - - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - down: false, - } - }) - } - else if (state.contentState.mouse.hover) - { - const alreadySelected = state.appState.selection.has(state.contentState.mouse.hover.id) - - if (!selectMultiple && !alreadySelected) - Editor.selectionClear(state) - - if (!alreadySelected || !selectMultiple) - Editor.selectionAdd(state, state.contentState.mouse.hover.id) - else - Editor.selectionRemove(state, state.contentState.mouse.hover.id) - - Editor.cursorSetVisible(state, false) - - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - drag: { ...state.contentState.mouse.drag, - rangeOrigin: Editor.selectionRange(state)!, - }, - action: state.contentState.mouse.hover.action, - } - }) - } - else - { - if (!selectMultiple) - Editor.selectionClear(state) - - Editor.cursorPlace(state, state.contentState.mouse.time, state.contentState.mouse.track) - Editor.cursorSetVisible(state, true) - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - action: Editor.actionSelectCursor, - } - }) - state.mergeAppState({ - playback: { ...state.appState.playback, - timeStart: state.contentState.mouse.time, - } - }) - } - } - } - - - static reduce_mouseUp(state: ContentManager, action: any) - { - if (!state.contentState.mouse.down) - return state - - if (state.contentState.mouse.action == Editor.actionDraw) - { - Track.execute("drawEnd", state, state.contentState.mouse.track) - } - else if (state.contentState.mouse.action == Editor.actionPan && - state.contentState.mouse.drag.xLocked && - state.contentState.mouse.drag.yLocked) - { - if (state.contentState.mouse.pos.x < state.contentState.trackHeaderW) - { - Editor.popup(state, state.contentState.mouse.track, - "trackInstrument", - new Rect( - state.contentState.mouse.pos.x, - state.contentState.mouse.pos.y, - 350, 500), - { elemIds: [state.contentState.tracks[state.contentState.mouse.track].trackId] }) - - /*state.appState = AppReducer.createPopup( - state.appState, - new Rect( - state.contentState.x + state.contentState.mouse.pos.x, - state.contentState.y + state.contentState.mouse.pos.y, - 0, 0), - TrackPopup, {})*/ - } - else if (state.contentState.mouse.hover) - { - Editor.selectionClear(state) - Editor.selectionAdd(state, state.contentState.mouse.hover.id) - Track.execute("popup", state, state.contentState.mouse.track) - } - } - - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - down: false, - action: 0, - } - }) - } - - - static reduce_mouseWheel(state: ContentManager, action: any) - { - if (Math.abs(action.deltaX) > 0) - { - let timeScroll = state.contentState.timeScroll + 0.01 / (state.contentState.timeScale / 100) * action.deltaX - let wheelDate = new Date() - - state.mergeContentState({ - timeScroll, - mouse: { ...state.contentState.mouse, - wheelDate - } - }) - } - else if (new Date().getTime() - state.contentState.mouse.wheelDate.getTime() > 250) - { - const snap = new Rational(1, 1024) - const prevMouseTime = Editor.timeAtX(state, state.contentState.mouse.pos.x - state.contentState.trackHeaderW, snap) - - let timeScale = state.contentState.timeScale * (action.deltaY > 0 ? 0.8 : 1.25) - timeScale = Math.max(4, Math.min(2048, timeScale)) - state.mergeContentState({ timeScale }) - - const newMouseTime = Editor.timeAtX(state, state.contentState.mouse.pos.x - state.contentState.trackHeaderW, snap) - - const timeScroll = state.contentState.timeScroll - newMouseTime.subtract(prevMouseTime).asFloat() - - const timeSnapAdjustThresholdUpper = 24 - const timeSnapAdjustThresholdLower = 8 - let timeSnap = state.contentState.timeSnapBase - - if (timeSnap.asFloat() * timeScale > timeSnapAdjustThresholdUpper) - while (timeSnap.asFloat() * timeScale > timeSnapAdjustThresholdUpper) - timeSnap = timeSnap.divide(new Rational(2)) - - else if (timeSnap.asFloat() * timeScale < timeSnapAdjustThresholdLower) - while (timeSnap.asFloat() * timeScale < timeSnapAdjustThresholdLower) - timeSnap = timeSnap.divide(new Rational(1, 2)) - - state.mergeContentState({ timeScroll, timeSnap }) - } - } - - - static handleEdgeScroll(state: ContentManager, handleYScroll: boolean) - { - const threshold = state.appState.prefs.editor.mouseEdgeScrollThreshold - const speed = state.appState.prefs.editor.mouseEdgeScrollSpeed - - const mouseX = state.contentState.mouse.pos.x - state.contentState.trackHeaderW - - let timeScroll = state.contentState.timeScroll - - if (mouseX > state.contentState.w - state.contentState.trackHeaderW - threshold) - timeScroll += state.contentState.timeSnap.asFloat() * speed - - else if (mouseX < threshold) - timeScroll -= state.contentState.timeSnap.asFloat() * speed - - state.mergeContentState({ timeScroll }) - - if (handleYScroll && - Track.execute("yScrollEnabled", state, state.contentState.mouse.drag.trackOrigin)) - { - const threshold = state.appState.prefs.editor.mouseEdgeScrollThreshold - const speed = state.appState.prefs.editor.mouseEdgeScrollSpeed * 2 - - const mouseY = state.contentState.mouse.trackYRaw - - const trackState = new TrackStateManager(state, state.contentState.mouse.drag.trackOrigin) - - if (mouseY > trackState.trackState.h - threshold) - trackState.mergeTrackState({ yScroll: trackState.trackState.yScroll + speed }) - - else if (mouseY < threshold) - trackState.mergeTrackState({ yScroll: trackState.trackState.yScroll - speed }) - } - } - - - static popup(state: ContentManager, trackIndex: number, type: string, rect: Rect, popupState: any) - { - const x = state.contentState.x + state.contentState.trackHeaderW - const y = state.contentState.y + Editor.trackY(state, trackIndex) - - state.appState = AppReducer.createFloating(state.appState, type, popupState, rect.displace(x, y)) - } - - - static popupClear(state: ContentManager) - { - state.appState = AppReducer.removeFloating(state.appState, "inspector") - } - - - static cursorSetVisible(state: ContentManager, visible: boolean) - { - state.mergeContentState({ - cursor: { - ...state.contentState.cursor, - visible, - } - }) - } - - - static cursorPlace(state: ContentManager, time: Rational | null, trackIndex: number | null) - { - if (trackIndex !== null) - trackIndex = Math.max(0, Math.min(state.contentState.tracks.length - 1, trackIndex)) - - const cursor = state.contentState.cursor - - state.mergeContentState({ - cursor: { ...cursor, - time1: time === null ? cursor.time1 : time, - time2: time === null ? cursor.time2 : time, - track1: trackIndex === null ? cursor.track1 : trackIndex, - track2: trackIndex === null ? cursor.track2 : trackIndex, - }, - }) - } - - - static cursorDrag(state: ContentManager, time: Rational | null, trackIndex: number | null) - { - if (trackIndex !== null) - trackIndex = Math.max(0, Math.min(state.contentState.tracks.length - 1, trackIndex)) - - const cursor = state.contentState.cursor - - state.mergeContentState({ - cursor: { ...cursor, - time2: time === null ? cursor.time2 : time, - track2: trackIndex === null ? cursor.track2 : trackIndex, - }, - }) - } - - - static selectionAdd(state: ContentManager, id: number) - { - state.mergeAppState({ - selection: state.appState.selection.add(id), - }) - } - - - static selectionAddAtCursor(state: ContentManager) - { - const trackMin = Math.min(state.contentState.cursor.track1, state.contentState.cursor.track2) - const trackMax = Math.max(state.contentState.cursor.track1, state.contentState.cursor.track2) - - const time1 = state.contentState.cursor.time1 - const time2 = state.contentState.cursor.time2 - if (time1.compare(time2) != 0) - { - let selection = state.appState.selection - - const range = new Range(time1, time2, false, false).sorted() - - for (let t = trackMin; t <= trackMax; t++) - { - const elems = Track.execute("elemsAt", state, t, { range }) - - for (const elem of elems) - selection = selection.add(elem) - } - - state.mergeAppState({ selection }) - } - } - - - static selectionAddAtRectCursor(state: ContentManager) - { - const track = state.contentState.rectCursor.track - - const time1 = state.contentState.rectCursor.time1 - const time2 = state.contentState.rectCursor.time2 - if (time1.compare(time2) != 0) - { - let selection = state.appState.selection - - const range = new Range(time1, time2, false, false).sorted() - const y1 = Math.min(state.contentState.rectCursor.y1, state.contentState.rectCursor.y2) - const y2 = Math.max(state.contentState.rectCursor.y1, state.contentState.rectCursor.y2) - const elems = Track.execute("elemsAt", state, track, { range, y1, y2 }) - - for (const elem of elems) - selection = selection.add(elem) - - state.mergeAppState({ selection }) - } - } - - - static selectionRemove(state: ContentManager, id: number) - { - state.mergeAppState({ - selection: state.appState.selection.remove(id), - }) - } - - - static selectionClear(state: ContentManager) - { - state.mergeAppState({ - selection: state.appState.selection.clear(), - }) - } - - - static selectionRange(state: ContentManager): Range | null - { - let range: Range | null = null - - for (const id of state.appState.selection) - { - const elem = state.appState.project.elems.get(id) as any - if (!elem) - continue - - if (elem.range) - { - const rangedElem = elem as Project.RangedElement - range = Range.merge(range, rangedElem.range) - } - - else if (elem.time) - { - const timedElem = elem as Project.TimedElement - range = Range.merge(range, Range.fromPoint(timedElem.time)) - } - } - - return range - } - - - static xAtTime(state: ContentManager, time: Rational): number - { - return (time.asFloat() - state.contentState.timeScroll) * state.contentState.timeScale - } - - - static timeAtX(state: ContentManager, x: number, timeSnap?: Rational): Rational - { - timeSnap = timeSnap || state.contentState.timeSnap - const time = x / state.contentState.timeScale + state.contentState.timeScroll - return Rational.fromFloat(time, timeSnap.denominator) - } - - - static timeRangeAtX(state: ContentManager, x1: number, x2: number, timeSnap?: Rational) - { - timeSnap = timeSnap || state.contentState.timeSnap - return new Range( - Editor.timeAtX(state, x1, timeSnap).subtract(timeSnap), - Editor.timeAtX(state, x2, timeSnap).add(timeSnap)) - } - - - static trackY(state: ContentManager, trackIndex: number): number - { - return state.contentState.tracks[trackIndex].y - state.contentState.trackScroll - } - - - static trackAtY(state: ContentManager, y: number): number - { - y += state.contentState.trackScroll - - if (y < 0) - return 0 - - for (let t = 0; t < state.contentState.tracks.length; t++) - { - const track = state.contentState.tracks[t] - - if (y >= track.y && y <= track.y + track.h) - return t - } - - return state.contentState.tracks.length - 1 - } - - - static rectForTrack(state: ContentManager, trackIndex: number): Rect | null - { - let y = 0 - for (let t = 0; t < state.contentState.tracks.length; t++) - { - const h = state.contentState.tracks[t].h - - if (t == trackIndex) - { - return new Rect( - state.contentState.trackHeaderW, - y, - state.contentState.w - state.contentState.trackHeaderW, - h) - } - - y += h - } - - return null - } - - - static visibleTimeRange(state: ContentManager): Range - { - return new Range( - Editor.timeAtX(state, 0).subtract(state.contentState.timeSnap), - Editor.timeAtX(state, state.contentState.w).add(state.contentState.timeSnap)) - } - - - static keyAt(state: ContentManager, trackId: Project.ID, time: Rational): Theory.Key - { - const keyChangeTrackId = Project.keyChangeTrackForTrack(state.appState.project, trackId) - const keyChangeTrackTimedElems = state.appState.project.timedLists.get(keyChangeTrackId) - if (!keyChangeTrackTimedElems) - return Editor.defaultKey() - - const keyCh = keyChangeTrackTimedElems.findActiveAt(time) - if (keyCh) - return (keyCh as Project.KeyChange).key - - const firstKeyCh = keyChangeTrackTimedElems.findFirst() - if (firstKeyCh) - return (firstKeyCh as Project.KeyChange).key - - return Editor.defaultKey() - } - - - static meterAt(state: ContentManager, trackId: Project.ID, time: Rational): Theory.Meter - { - const meterChangeTrackId = Project.meterChangeTrackForTrack(state.appState.project, trackId) - const meterChangeTrackTimedElems = state.appState.project.timedLists.get(meterChangeTrackId) - if (!meterChangeTrackTimedElems) - return Editor.defaultMeter() - - const meterCh = meterChangeTrackTimedElems.findActiveAt(time) - if (meterCh) - return (meterCh as Project.MeterChange).meter - - const firstMeterCh = meterChangeTrackTimedElems.findFirst() - if (firstMeterCh) - return (firstMeterCh as Project.MeterChange).meter - - return Editor.defaultMeter() - } - - - static defaultKey(): Theory.Key - { - return Theory.Key.parse("C Major") - } - - - static defaultMeter(): Theory.Meter - { - return new Theory.Meter(4, 4) - } - - - static render(state: ContentManager, ctx: CanvasRenderingContext2D) - { - ctx.save() - - ctx.fillStyle = state.appState.prefs.editor.bkgColor - ctx.fillRect(0, 0, state.contentState.w, state.contentState.h) - - ctx.save() - ctx.translate(state.contentState.trackHeaderW, 0) - - ctx.beginPath() - ctx.rect( - 0, - 0, - state.contentState.w - state.contentState.trackHeaderW, - state.contentState.h) - ctx.clip() - - Editor.renderCursorHighlight(state, ctx) - Editor.renderBackgroundMeasures(state, ctx) - - ctx.restore() - - let y = -state.contentState.trackScroll - for (let t = 0; t < state.contentState.tracks.length; t++) - { - ctx.save() - ctx.translate(state.contentState.trackHeaderW, y) - - ctx.beginPath() - ctx.rect( - 0, - 1, - state.contentState.w - state.contentState.trackHeaderW, - state.contentState.tracks[t].h - 1) - ctx.clip() - - ctx.translate(0, -state.contentState.tracks[t].yScroll) - - Editor.renderRectCursorHighlight(state, ctx, t) - Track.execute("render", state, t, ctx) - Editor.renderRectCursorContour(state, ctx, t) - - ctx.restore() - - y += state.contentState.tracks[t].h - - ctx.strokeStyle = state.appState.prefs.editor.trackHBorderColor - ctx.beginPath() - ctx.moveTo(0, y + 0.5) - ctx.lineTo(state.contentState.w, y + 0.5) - ctx.stroke() - } - - ctx.save() - ctx.translate(state.contentState.trackHeaderW, 0) - - ctx.beginPath() - ctx.rect( - 0, - 0, - state.contentState.w - state.contentState.trackHeaderW, - state.contentState.h) - ctx.clip() - - if (state.contentState.cursor.visible) - { - const timeMin = state.contentState.cursor.time1.min(state.contentState.cursor.time2)! - const timeMax = state.contentState.cursor.time1.max(state.contentState.cursor.time2)! - Editor.renderCursorBeam(state, ctx, timeMin, false) - Editor.renderCursorBeam(state, ctx, timeMax, true) - } - - if (state.appState.playback.playing) - Editor.renderPlaybackBeam(state, ctx, state.appState.playback.time) - - ctx.restore() - - ctx.strokeStyle = state.appState.prefs.editor.trackVBorderColor - ctx.beginPath() - ctx.moveTo(state.contentState.trackHeaderW + 0.5, 0) - ctx.lineTo(state.contentState.trackHeaderW + 0.5, state.contentState.h) - ctx.stroke() - - ctx.restore() - } - - - static renderBackgroundMeasures(state: ContentManager, ctx: CanvasRenderingContext2D) - { - const visibleRange = Editor.visibleTimeRange(state) - - /*ctx.fillStyle = "#1b191c" - - const songXMin = Editor.xAtTime(state, state.project.range.start) - const songXMax = Editor.xAtTime(state, state.project.range.end) - - if (songXMin > 0) - ctx.fillRect(0, 0, songXMin, state.h) - - if (songXMax < state.w) - ctx.fillRect(songXMax, 0, state.w - songXMax, state.h)*/ - - const meterChangeTrackId = Project.meterChangeTrackForTrack(state.appState.project, 0) - const meterChangeList = state.appState.project.timedLists.get(meterChangeTrackId)! - - for (let [meterCh1Raw, meterCh2Raw] of meterChangeList.iterActiveAtRangePairwise(visibleRange)) - { - let timeMin = (meterCh1Raw ? meterCh1Raw.time : null) - let timeMax = (meterCh2Raw ? meterCh2Raw.time : visibleRange.end) - - let measureAlternate = true - - let meterCh1 = meterCh1Raw as (Project.MeterChange | null) - let meterCh2 = meterCh2Raw as (Project.MeterChange | null) - - if (!meterCh1) - { - if (!meterCh2) - continue - - meterCh1 = meterCh2 - timeMin = meterCh2.time - while (timeMin.compare(visibleRange.start) > 0) - { - timeMin = timeMin.subtract(meterCh2.meter.fullCycleDuration) - - if (meterCh2.meter.alternatingMeasureCount % 2 != 0) - measureAlternate = !measureAlternate - } - } - - const meterCh1X = 0.5 + Math.floor(Editor.xAtTime(state, timeMin!)) - const meterCh2X = 0.5 + Math.floor(Editor.xAtTime(state, timeMax)) - - ctx.strokeStyle = state.appState.prefs.editor.meterChangeColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - - for (const [measureN, measureD, time1, time2] of meterCh1.meter.iterMeasuresPairwise(timeMin)) - { - measureAlternate = !measureAlternate - - if (time2.compare(visibleRange.start) < 0) - continue - - if (time1.compare(timeMax) > 0 || time1.compare(visibleRange.end) > 0) - break - - const measureX1 = 0.5 + Math.floor(Editor.xAtTime(state, time1)) - const measureX2 = 0.5 + Math.floor(Editor.xAtTime(state, time2)) - - if (measureAlternate) - { - const x1 = Math.min(meterCh2X, measureX1) - const x2 = Math.min(meterCh2X, measureX2) - - ctx.fillStyle = state.appState.prefs.editor.measureAlternateBkgColor - ctx.fillRect(x1, 0, x2 - x1, state.contentState.h) - } - - if (time1.compare(meterCh1.time) == 0) - ctx.strokeStyle = state.appState.prefs.editor.meterChangeColor - else - ctx.strokeStyle = state.appState.prefs.editor.measureColor - - ctx.beginPath() - ctx.moveTo(measureX1, 0) - ctx.lineTo(measureX1, state.contentState.h) - ctx.stroke() - - const halfSubmeasureSize = Editor.xAtTime(state, new Rational(1, measureD * 2)) - Editor.xAtTime(state, new Rational(0)) - if (halfSubmeasureSize > 16) - { - let halfSubmeasureTime = time1.add(new Rational(-1, measureD * 2)) - for (let sub = 1; sub <= measureN; sub++) - { - halfSubmeasureTime = halfSubmeasureTime.add(new Rational(2, measureD * 2)) - - const halfSubmeasureX = 0.5 + Math.floor(Editor.xAtTime(state, halfSubmeasureTime)) - if (halfSubmeasureX >= meterCh1X && halfSubmeasureX <= meterCh2X) - { - ctx.strokeStyle = state.appState.prefs.editor.halfSubmeasureColor - ctx.beginPath() - ctx.moveTo(halfSubmeasureX, 0) - ctx.lineTo(halfSubmeasureX, state.contentState.h) - ctx.stroke() - } - } - } - - const submeasureSize = Editor.xAtTime(state, new Rational(1, measureD)) - Editor.xAtTime(state, new Rational(0)) - if (submeasureSize > 8) - { - let submeasureTime = time1 - for (let sub = 1; sub <= measureN; sub++) - { - submeasureTime = submeasureTime.add(new Rational(1, measureD)) - - const submeasureX = 0.5 + Math.floor(Editor.xAtTime(state, submeasureTime)) - if (submeasureX >= meterCh1X && submeasureX <= meterCh2X) - { - ctx.strokeStyle = state.appState.prefs.editor.submeasureColor - ctx.beginPath() - ctx.moveTo(submeasureX, 0) - ctx.lineTo(submeasureX, state.contentState.h) - ctx.stroke() - } - } - } - } - } - - const keyChangeTrackId = Project.keyChangeTrackForTrack(state.appState.project, 0) - const keyChangeList = state.appState.project.timedLists.get(keyChangeTrackId)! - - for (const keyCh of keyChangeList.iterAtRange(visibleRange)) - { - const keyChX = 0.5 + Math.floor(Editor.xAtTime(state, keyCh.time)) - - ctx.strokeStyle = state.appState.prefs.editor.keyChangeColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - - ctx.beginPath() - ctx.moveTo(keyChX, 0) - ctx.lineTo(keyChX, state.contentState.h) - ctx.stroke() - } - } - - - static renderPlaybackBeam(state: ContentManager, ctx: CanvasRenderingContext2D, time: Rational) - { - const trackMin = 0 - const trackMax = state.contentState.tracks.length - 1 - - const x = 0.5 + Math.floor(Editor.xAtTime(state, time)) - - ctx.strokeStyle = state.appState.prefs.editor.playbackCursorColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - - const y1 = 0.5 + Math.floor(Editor.trackY(state, trackMin)) - const y2 = 0.5 + Math.floor(Editor.trackY(state, trackMax) + state.contentState.tracks[trackMax].h) - - ctx.beginPath() - ctx.lineTo(x, y1) - ctx.lineTo(x, y2) - ctx.stroke() - } - - - static renderCursorHighlight(state: ContentManager, ctx: CanvasRenderingContext2D) - { - if (!state.contentState.cursor.visible) - return - - const timeMin = state.contentState.cursor.time1.min(state.contentState.cursor.time2)! - const timeMax = state.contentState.cursor.time1.max(state.contentState.cursor.time2)! - const trackMin = Math.min(state.contentState.cursor.track1, state.contentState.cursor.track2) - const trackMax = Math.max(state.contentState.cursor.track1, state.contentState.cursor.track2) - - if (trackMin < 0 || trackMax < 0 || - trackMin >= state.contentState.tracks.length || - trackMax >= state.contentState.tracks.length) - return - - const y1 = 0.5 + Math.floor(Editor.trackY(state, trackMin)) - const y2 = 0.5 + Math.floor(Editor.trackY(state, trackMax) + state.contentState.tracks[trackMax].h) - - const x1 = Editor.xAtTime(state, timeMin) - const x2 = Editor.xAtTime(state, timeMax) - - ctx.fillStyle = state.appState.prefs.editor.selectionBkgColor - ctx.fillRect(x1, y1, x2 - x1, y2 - y1) - } - - - static renderCursorBeam(state: ContentManager, ctx: CanvasRenderingContext2D, time: Rational, tipOffsetSide: boolean) - { - const trackMin = Math.min(state.contentState.cursor.track1, state.contentState.cursor.track2) - const trackMax = Math.max(state.contentState.cursor.track1, state.contentState.cursor.track2) - - if (trackMin < 0 || trackMax < 0 || - trackMin >= state.contentState.tracks.length || - trackMax >= state.contentState.tracks.length) - return - - const x = 0.5 + Math.floor(Editor.xAtTime(state, time)) - - ctx.strokeStyle = state.appState.prefs.editor.selectionCursorColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - - const headSize = 7 * (tipOffsetSide ? -1 : 1) - - const y1 = 0.5 + Math.floor(Editor.trackY(state, trackMin)) - const y2 = 0.5 + Math.floor(Editor.trackY(state, trackMax) + state.contentState.tracks[trackMax].h) - - ctx.beginPath() - ctx.moveTo(x + headSize, y1) - ctx.lineTo(x, y1) - ctx.lineTo(x, y2) - ctx.lineTo(x + headSize, y2) - ctx.stroke() - } - - - static renderRectCursorHighlight(state: ContentManager, ctx: CanvasRenderingContext2D, trackIndex: number) - { - if (state.contentState.mouse.action != Editor.actionSelectRect) - return - - if (trackIndex != state.contentState.rectCursor.track) - return - - const timeMin = state.contentState.rectCursor.time1.min(state.contentState.rectCursor.time2)! - const timeMax = state.contentState.rectCursor.time1.max(state.contentState.rectCursor.time2)! - const y1 = 0.5 + Math.floor(Math.min(state.contentState.rectCursor.y1, state.contentState.rectCursor.y2)) - const y2 = 0.5 + Math.floor(Math.max(state.contentState.rectCursor.y1, state.contentState.rectCursor.y2)) + 1 - - const x1 = 0.5 + Math.floor(Editor.xAtTime(state, timeMin)) - const x2 = 0.5 + Math.floor(Editor.xAtTime(state, timeMax)) - - ctx.fillStyle = state.appState.prefs.editor.selectionBkgColor - ctx.fillRect(x1, y1, x2 - x1, y2 - y1) - } - - - static renderRectCursorContour(state: ContentManager, ctx: CanvasRenderingContext2D, trackIndex: number) - { - if (state.contentState.mouse.action != Editor.actionSelectRect) - return - - if (trackIndex != state.contentState.rectCursor.track) - return - - const timeMin = state.contentState.rectCursor.time1.min(state.contentState.rectCursor.time2)! - const timeMax = state.contentState.rectCursor.time1.max(state.contentState.rectCursor.time2)! - const y1 = 0.5 + Math.floor(Math.min(state.contentState.rectCursor.y1, state.contentState.rectCursor.y2)) - const y2 = 0.5 + Math.floor(Math.max(state.contentState.rectCursor.y1, state.contentState.rectCursor.y2)) + 1 - - const x1 = 0.5 + Math.floor(Editor.xAtTime(state, timeMin)) - const x2 = 0.5 + Math.floor(Editor.xAtTime(state, timeMax)) - - ctx.strokeStyle = state.appState.prefs.editor.selectionCursorColor - ctx.lineCap = "square" - ctx.lineWidth = 1 - ctx.strokeRect(x1, y1, x2 - x1, y2 - y1) - } -} \ No newline at end of file diff --git a/src_old/editor2/editorState.ts b/src_old/editor2/editorState.ts deleted file mode 100644 index a59e5f0..0000000 --- a/src_old/editor2/editorState.ts +++ /dev/null @@ -1,101 +0,0 @@ -import TrackState from "./trackState" -import Project from "../project/project2" -import Rational from "../util/rational" -import Range from "../util/range" - - -export enum EditorMode -{ - Full, - NoteEditor, -} - - -export default interface EditorState -{ - mode: EditorMode - modeTracks: number[] - - x: number - y: number - w: number - h: number - - trackHeaderW: number - - tracks: TrackState[] - trackScroll: number - - timeScroll: number - timeScale: number - timeSnap: Rational - timeSnapBase: Rational - - cursor: - { - visible: boolean - time1: Rational - time2: Rational - track1: number - track2: number - } - - rectCursor: - { - track: number - time1: Rational - time2: Rational - y1: number - y2: number - } - - keys: { [key: string]: boolean } - - mouse: - { - down: boolean - downDate: Date - - action: number - - pos: { x: number, y: number } - posPrev: { x: number, y: number } - time: Rational - track: number, - trackPos: { x: number, y: number } - trackYRaw: number, - row: number, - - hover: null | - { - id: number, - range: Range, - action: number, - } - - drag: - { - xLocked: boolean - yLocked: boolean - - posOrigin: { x: number, y: number } - timeOrigin: Rational - timeScrollOrigin: number - trackScrollOrigin: number - rangeOrigin: Range - trackOrigin: number - trackPosOrigin: { x: number, y: number } - trackYRawOrigin: number - trackYScrollOrigin: number - rowOrigin: number - projectOrigin: Project - - posDelta: { x: number, y: number } - timeDelta: Rational - trackPosDelta: { x: number, y: number } - rowDelta: number - } - - wheelDate: Date - } -} \ No newline at end of file diff --git a/src_old/editor2/track.ts b/src_old/editor2/track.ts deleted file mode 100644 index 1d5d8b9..0000000 --- a/src_old/editor2/track.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { ContentManager } from "../AppState" -import EditorState from "./editorState" -import TrackStateManager from "./trackStateManager" -import TrackNotes from "./trackNotes" -import TrackNotesPreview from "./trackNotesPreview" -import TrackKeyChanges from "./trackKeyChanges" -import TrackMeterChanges from "./trackMeterChanges" -import Project from "../project/project2" - - -export default class Track -{ - static init(state: TrackStateManager) - { - state.mergeTrackState({ - yScroll: 0, - }) - } - - - static handlerForTrackType(type: string): any - { - switch (type) - { - case "notes": return TrackNotes - case "notesPreview": return TrackNotesPreview - case "keyChanges": return TrackKeyChanges - case "meterChanges": return TrackMeterChanges - default: throw "invalid track kind" - } - } - - - static yScrollEnabled(state: TrackStateManager): boolean - { - return false - } - - - static rowAtY(state: TrackStateManager, y: number): number - { - return 0 - } - - - static elemsAt(state: TrackStateManager, region: any): Project.ID[] - { - return [] - } - - - static execute(fnName: string, state: ContentManager, trackIndex: number, ...args: any[]): any - { - const trackStateManager = new TrackStateManager(state, trackIndex) - - const handlerDerived = Track.handlerForTrackType(trackStateManager.trackState.type) - const fnDerived = handlerDerived[fnName] - if (fnDerived) - return fnDerived(trackStateManager, ...args) - - const fn = (Track as any)[fnName] - if (fn) - return fn(trackStateManager, ...args) - - return null - } -} \ No newline at end of file diff --git a/src_old/editor2/trackKeyChanges.ts b/src_old/editor2/trackKeyChanges.ts deleted file mode 100644 index 5f7d679..0000000 --- a/src_old/editor2/trackKeyChanges.ts +++ /dev/null @@ -1,249 +0,0 @@ -import Editor from "./editor" -import Track from "./track" -import TrackStateManager from "./trackStateManager" -import TrackKeyChangesState from "./trackKeyChangesState" -import Rect from "../util/rect" -import Range from "../util/range" -import Project from "../project/project2" -import Rational from "../util/rational" -import * as Theory from "../theory/theory" - - -export default class TrackKeyChanges -{ - static knobWidth = 16 - static knobHeight = 22 - - - static init(state: TrackStateManager) - { - Track.init(state) - state.mergeTrackState({ - type: "keyChanges", - }) - } - - - static hover(state: TrackStateManager) - { - const pos = state.contentState.mouse.trackPos - - const checkRange = Editor.timeRangeAtX( - state.contentStateManager, - pos.x - TrackKeyChanges.knobWidth, - pos.x + TrackKeyChanges.knobWidth) - - let hover = null - - for (const keyCh of TrackKeyChanges.iterAtRange(state, checkRange)) - { - const rect = TrackKeyChanges.knobRectForKeyChange(state, keyCh.time) - if (rect.contains(pos)) - { - hover = - { - id: keyCh.id, - range: Range.fromPoint(keyCh.time), - action: Editor.actionDragTime, - } - } - } - - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - hover, - } - }) - } - - - static drawClear(state: TrackStateManager) - { - state.mergeTrackState({ draw: null }) - } - - - static drawHover(state: TrackStateManager) - { - const time = state.contentState.mouse.time - - state.mergeTrackState({ draw: { time } }) - } - - - static drawDrag(state: TrackStateManager) - { - const draw = state.trackState.draw - if (draw) - { - const time = state.contentState.mouse.time - state.mergeTrackState({ draw: { time } }) - } - } - - - static drawEnd(state: TrackStateManager) - { - const draw = state.trackState.draw - if (draw) - { - const keyCh = new Project.KeyChange( - state.trackState.trackId, - draw.time, - Editor.defaultKey()) - - const id = state.appState.project.nextId - state.mergeAppState({ - project: Project.upsertTimedElement(state.appState.project, keyCh), - selection: state.appState.selection.add(id), - }) - } - } - - - static popup(state: TrackStateManager) - { - const elemId = state.contentState.mouse.hover!.id - const elem = state.appState.project.elems.get(elemId) as Project.KeyChange - - const knob = TrackKeyChanges.knobRectForKeyChange(state, elem.time) - - Editor.popup(state.contentStateManager, state.trackIndex, - "inspector", - new Rect(knob.x2 + 10, knob.y2 + 10, 450, 250), - { elemIds: [elemId] }) - } - - - static elemsAt(state: TrackStateManager, region: any): Project.ID[] - { - const elems = [] - - for (const keyCh of TrackKeyChanges.iterAtRange(state, region.range)) - elems.push(keyCh.id) - - return elems - } - - - static *iterAtRange(state: TrackStateManager, range: Range): Generator - { - const trackElems = state.appState.project.timedLists.get(state.trackState.trackId) - if (!trackElems) - return - - for (const keyCh of trackElems.iterAtRange(range)) - yield keyCh as Project.KeyChange - } - - - static knobRectForKeyChange(state: TrackStateManager, time: Rational) - { - return new Rect( - Editor.xAtTime(state.contentStateManager, time) - TrackKeyChanges.knobWidth / 2, - 0, - TrackKeyChanges.knobWidth, - TrackKeyChanges.knobHeight) - } - - - static render(state: TrackStateManager, ctx: CanvasRenderingContext2D) - { - const visibleRange = Editor.visibleTimeRange(state.contentStateManager) - - const firstKey = Editor.keyAt(state.contentStateManager, state.trackState.trackId, visibleRange.start) - let shouldDrawFirstKey = true - - for (const keyCh of TrackKeyChanges.iterAtRange(state, visibleRange)) - { - if (shouldDrawFirstKey) - { - const x = Editor.xAtTime(state.contentStateManager, keyCh.time) - if (x > 80) - TrackKeyChanges.renderKeyChangeLabel(state, ctx, firstKey) - } - - TrackKeyChanges.renderKeyChange(state, ctx, keyCh) - shouldDrawFirstKey = false - } - - if (shouldDrawFirstKey) - TrackKeyChanges.renderKeyChangeLabel(state, ctx, firstKey) - - const draw = state.trackState.draw - if (draw) - { - ctx.globalAlpha = 0.6 - TrackKeyChanges.renderKeyChangeKnob(state, ctx, draw.time) - ctx.globalAlpha = 1 - } - } - - - static renderKeyChangeKnob(state: TrackStateManager, ctx: CanvasRenderingContext2D, time: Rational) - { - const rect = TrackKeyChanges.knobRectForKeyChange(state, time) - - ctx.fillStyle = state.appState.prefs.editor.keyChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - } - - - static renderKeyChangeLabel(state: TrackStateManager, ctx: CanvasRenderingContext2D, key: Theory.Key) - { - const rect = TrackKeyChanges.knobRectForKeyChange(state, new Rational(0)) - const x = 5 - - ctx.fillStyle = state.appState.prefs.editor.keyChangeColor - - ctx.font = "14px Verdana" - ctx.textAlign = "left" - ctx.textBaseline = "middle" - ctx.fillText(key.str, x, rect.y + rect.h / 2) - } - - - static renderKeyChange(state: TrackStateManager, ctx: CanvasRenderingContext2D, keyCh: Project.KeyChange) - { - const rect = TrackKeyChanges.knobRectForKeyChange(state, keyCh.time) - - ctx.fillStyle = state.appState.prefs.editor.keyChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.font = "14px Verdana" - ctx.textAlign = "left" - ctx.textBaseline = "middle" - ctx.fillText(keyCh.key.str, rect.x + rect.w + 5, rect.y + rect.h / 2) - - if (state.appState.selection.has(keyCh.id)) - { - ctx.globalAlpha = 0.75 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2 - 3, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - - const hover = state.contentState.mouse.hover - if (hover && hover.id === keyCh.id) - { - ctx.globalAlpha = 0.5 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - } -} \ No newline at end of file diff --git a/src_old/editor2/trackKeyChangesState.ts b/src_old/editor2/trackKeyChangesState.ts deleted file mode 100644 index 09cd949..0000000 --- a/src_old/editor2/trackKeyChangesState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import TrackState from "./trackState" -import Rational from "../util/rational" - - -export default interface TrackKeyChangesState extends TrackState -{ - draw: null | - { - time: Rational - } -} \ No newline at end of file diff --git a/src_old/editor2/trackMeterChanges.ts b/src_old/editor2/trackMeterChanges.ts deleted file mode 100644 index 4db3ec3..0000000 --- a/src_old/editor2/trackMeterChanges.ts +++ /dev/null @@ -1,236 +0,0 @@ -import Editor from "./editor" -import Track from "./track" -import TrackStateManager from "./trackStateManager" -import TrackMeterChangesState from "./trackMeterChangesState" -import Rect from "../util/rect" -import Range from "../util/range" -import Project from "../project/project2" -import Rational from "../util/rational" -import * as Theory from "../theory/theory" - - -export default class TrackMeterChanges -{ - static knobWidth = 16 - static knobHeight = 22 - - - static init(state: TrackStateManager) - { - Track.init(state) - state.mergeTrackState({ - type: "meterChanges", - }) - } - - - static hover(state: TrackStateManager) - { - const pos = state.contentState.mouse.trackPos - - const checkRange = Editor.timeRangeAtX( - state.contentStateManager, - pos.x - TrackMeterChanges.knobWidth, - pos.x + TrackMeterChanges.knobWidth) - - let hover = null - - for (const keyCh of TrackMeterChanges.iterAtRange(state, checkRange)) - { - const rect = TrackMeterChanges.knobRectForMeterChange(state, keyCh.time) - if (rect.contains(pos)) - { - hover = - { - id: keyCh.id, - range: Range.fromPoint(keyCh.time), - action: Editor.actionDragTime, - } - } - } - - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - hover, - } - }) - } - - - static drawClear(state: TrackStateManager) - { - state.mergeTrackState({ draw: null }) - } - - - static drawHover(state: TrackStateManager) - { - const time = state.contentState.mouse.time - - state.mergeTrackState({ draw: { time } }) - } - - - static drawDrag(state: TrackStateManager) - { - const draw = state.trackState.draw - if (draw) - { - const time = state.contentState.mouse.time - state.mergeTrackState({ draw: { time } }) - } - } - - - static drawEnd(state: TrackStateManager) - { - const draw = state.trackState.draw - if (draw) - { - const meterCh = new Project.MeterChange( - state.trackState.trackId, - draw.time, - Editor.defaultMeter()) - - const id = state.appState.project.nextId - state.mergeAppState({ - project: Project.upsertTimedElement(state.appState.project, meterCh), - selection: state.appState.selection.add(id), - }) - } - } - - - static elemsAt(state: TrackStateManager, region: any): Project.ID[] - { - const elems = [] - - for (const meterCh of TrackMeterChanges.iterAtRange(state, region.range)) - elems.push(meterCh.id) - - return elems - } - - - static *iterAtRange(state: TrackStateManager, range: Range): Generator - { - const trackElems = state.appState.project.timedLists.get(state.trackState.trackId) - if (!trackElems) - return - - for (const keyCh of trackElems.iterAtRange(range)) - yield keyCh as Project.MeterChange - } - - - static knobRectForMeterChange(state: TrackStateManager, time: Rational) - { - return new Rect( - Editor.xAtTime(state.contentStateManager, time) - TrackMeterChanges.knobWidth / 2, - 0, - TrackMeterChanges.knobWidth, - TrackMeterChanges.knobHeight) - } - - - static render(state: TrackStateManager, ctx: CanvasRenderingContext2D) - { - const visibleRange = Editor.visibleTimeRange(state.contentStateManager) - - const firstMeter = Editor.meterAt(state.contentStateManager, state.trackState.trackId, visibleRange.start) - let shouldDrawFirstKey = true - - for (const meterCh of TrackMeterChanges.iterAtRange(state, visibleRange)) - { - if (shouldDrawFirstKey) - { - const x = Editor.xAtTime(state.contentStateManager, meterCh.time) - if (x > 80) - TrackMeterChanges.renderMeterChangeLabel(state, ctx, firstMeter) - } - - TrackMeterChanges.renderMeterChange(state, ctx, meterCh) - shouldDrawFirstKey = false - } - - if (shouldDrawFirstKey) - TrackMeterChanges.renderMeterChangeLabel(state, ctx, firstMeter) - - - const draw = state.trackState.draw - if (draw) - { - ctx.globalAlpha = 0.6 - TrackMeterChanges.renderMeterChangeKnob(state, ctx, draw.time) - ctx.globalAlpha = 1 - } - } - - - static renderMeterChangeKnob(state: TrackStateManager, ctx: CanvasRenderingContext2D, time: Rational) - { - const rect = TrackMeterChanges.knobRectForMeterChange(state, time) - - ctx.fillStyle = state.appState.prefs.editor.meterChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - } - - - static renderMeterChangeLabel(state: TrackStateManager, ctx: CanvasRenderingContext2D, meter: Theory.Meter) - { - const rect = TrackMeterChanges.knobRectForMeterChange(state, new Rational(0)) - const x = 5 - - ctx.fillStyle = state.appState.prefs.editor.meterChangeColor - - ctx.font = "14px Verdana" - ctx.textAlign = "left" - ctx.textBaseline = "middle" - ctx.fillText(meter.numerator + " / " + meter.denominator, x, rect.y + rect.h / 2) - } - - - static renderMeterChange(state: TrackStateManager, ctx: CanvasRenderingContext2D, meterCh: Project.MeterChange) - { - const rect = TrackMeterChanges.knobRectForMeterChange(state, meterCh.time) - - ctx.fillStyle = state.appState.prefs.editor.meterChangeColor - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.font = "14px Verdana" - ctx.textAlign = "left" - ctx.textBaseline = "middle" - ctx.fillText(meterCh.meter.numerator + " / " + meterCh.meter.denominator, rect.x + rect.w + 5, rect.y + rect.h / 2) - - if (state.appState.selection.has(meterCh.id)) - { - ctx.globalAlpha = 0.75 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2 - 3, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - - const hover = state.contentState.mouse.hover - if (hover && hover.id === meterCh.id) - { - ctx.globalAlpha = 0.5 - ctx.fillStyle = "#fff" - - ctx.beginPath() - ctx.arc(rect.x + rect.w / 2, rect.y + rect.h / 2, rect.w / 2, 0, Math.PI * 2) - ctx.fill() - - ctx.globalAlpha = 1 - } - } -} \ No newline at end of file diff --git a/src_old/editor2/trackMeterChangesState.ts b/src_old/editor2/trackMeterChangesState.ts deleted file mode 100644 index 3b2d4e0..0000000 --- a/src_old/editor2/trackMeterChangesState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import TrackState from "./trackState" -import Rational from "../util/rational" - - -export default interface TrackMeterChangesState extends TrackState -{ - draw: null | - { - time: Rational - } -} \ No newline at end of file diff --git a/src_old/editor2/trackNotes.ts b/src_old/editor2/trackNotes.ts deleted file mode 100644 index e2a9698..0000000 --- a/src_old/editor2/trackNotes.ts +++ /dev/null @@ -1,391 +0,0 @@ -import Editor from "./editor" -import Track from "./track" -import TrackStateManager from "./trackStateManager" -import TrackNotesState from "./trackNotesState" -import Rect from "../util/rect" -import Range from "../util/range" -import Project from "../project/project2" -import Rational from "../util/rational" -import CanvasUtils from "../util/canvasUtils" -import * as Theory from "../theory/theory" - - -type StateManager = TrackStateManager - - -export default class TrackNotes -{ - static init(state: StateManager) - { - Track.init(state) - state.mergeTrackState({ - type: "notes", - rowScale: 10, - }) - } - - - static yScrollEnabled(state: StateManager): boolean - { - return true - } - - - static hover(state: StateManager) - { - const pos = state.contentState.mouse.trackPos - - const margin = 10 - const checkRange = Editor.timeRangeAtX(state.contentStateManager, pos.x - margin, pos.x + margin) - - let hoverPrimary = null - let hoverSecondary = null - - for (const [note, keyCh, xMin, xMax] of TrackNotes.iterNotesAndKeyChangesAtRange(state, checkRange)) - { - const margin = 2 - - const row = TrackNotes.rowForPitch(state, note.pitch, keyCh.key) - const rectExact = TrackNotes.rectForNote(state, note.range, row, xMin, xMax) - const rect = new Rect( - rectExact.x - margin, - rectExact.y, - rectExact.w + margin * 2, - rectExact.h) - - const dragMarginOut = Math.abs(Math.min(0, rect.w - 16)) - const stretchMarginOut = 16 - const stretchMarginIn = Math.max(0, Math.min(10, rect.w / 4)) - const rectDrag = new Rect(rect.x - dragMarginOut, rect.y, rect.w + dragMarginOut * 2, rect.h) - const rectStretchStart = new Rect(rect.x - stretchMarginOut, rect.y, stretchMarginOut + stretchMarginIn, rect.h) - const rectStretchEnd = new Rect(rect.x2 - stretchMarginIn, rect.y, stretchMarginOut + stretchMarginIn, rect.h) - - const exactHover = rect.contains(pos) - - let action = 0 - if (dragMarginOut > 0 && rectDrag.contains(pos)) - action = Editor.actionDragTime | Editor.actionDragPitchRow - else if (rectStretchStart.contains(pos) && !rectExact.cutStart) - action = Editor.actionStretchTimeStart - else if (rectStretchEnd.contains(pos) && !rectExact.cutEnd) - action = Editor.actionStretchTimeEnd - else if (exactHover) - action = Editor.actionDragTime | Editor.actionDragPitchRow - - const hoverNote = - { - id: note.id, - range: note.range, - action, - } - - if (action != 0) - { - if (exactHover) - hoverPrimary = hoverNote - else - hoverSecondary = hoverNote - } - - if (hoverPrimary) - break - } - - const hover = hoverPrimary || hoverSecondary - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - hover, - } - }) - } - - - static drawClear(state: StateManager) - { - state.mergeTrackState({ draw: null }) - } - - - static drawHover(state: StateManager) - { - const time = state.contentState.mouse.time - const key = Editor.keyAt(state.contentStateManager, state.trackState.trackId, time) - const row = TrackNotes.rowAtY(state, state.contentState.mouse.trackPos.y) - const pitch = TrackNotes.pitchForRow(state, row, key) - - state.mergeTrackState({ - draw: - { - time1: time, - time2: time.add(state.contentState.timeSnap.multiply(new Rational(4))), - pitch, - } - }) - } - - - static drawDrag(state: StateManager) - { - const draw = state.trackState.draw - if (draw) - { - let time2 = state.contentState.mouse.time - - const time1X = Editor.xAtTime(state.contentStateManager, draw.time1) - const time2X = Editor.xAtTime(state.contentStateManager, time2) - if (Math.abs(time1X - time2X) < 5) - time2 = draw.time1.add(state.contentState.timeSnap.multiply(new Rational(4))) - - state.mergeTrackState({ - draw: { ...draw, - time2, - } - }) - } - } - - - static drawEnd(state: StateManager) - { - const draw = state.trackState.draw - if (draw) - { - const note = new Project.Note( - state.trackState.trackId, - new Range(draw.time1, draw.time2).sorted(), - draw.pitch) - - const id = state.appState.project.nextId - state.mergeAppState({ - project: Project.upsertRangedElement(state.appState.project, note), - selection: state.appState.selection.add(id), - }) - } - } - - - static elemsAt(state: StateManager, region: any): Project.ID[] - { - const elems = [] - - if (region.y1 === undefined) - { - for (const note of TrackNotes.iterNotesAtRange(state, region.range)) - elems.push(note.id) - } - else - { - for (const [note, keyCh, xMin, xMax] of TrackNotes.iterNotesAndKeyChangesAtRange(state, region.range)) - { - const row = TrackNotes.rowForPitch(state, note.pitch, keyCh.key) - const rect = TrackNotes.rectForNote(state, note.range, row, xMin, xMax) - - if (rect.y1 < region.y2 && rect.y2 > region.y1) - elems.push(note.id) - } - } - - return elems - } - - - static *iterNotesAtRange(state: StateManager, range: Range): Generator - { - const trackElems = state.appState.project.rangedLists.get(state.trackState.trackId) - if (!trackElems) - return - - for (const note of trackElems.iterAtRange(range)) - yield note as Project.Note - } - - - static *iterKeyChangePairsAtRange(state: StateManager, range: Range): Generator<[Project.KeyChange, Project.KeyChange, number, number], void, void> - { - const keyChangeTrackId = Project.keyChangeTrackForTrack(state.appState.project, state.trackState.trackId) - const keyChangeTrackTimedElems = state.appState.project.timedLists.get(keyChangeTrackId) - if (!keyChangeTrackTimedElems) - return - - const firstKeyCh = keyChangeTrackTimedElems.findFirst() as (Project.KeyChange | null) - const defaultKey = firstKeyCh ? firstKeyCh.key : Editor.defaultKey() - - for (const pair of keyChangeTrackTimedElems.iterActiveAtRangePairwise(range)) - { - const keyCh1 = pair[0] || new Project.KeyChange(-1, range.start, defaultKey) - const keyCh2 = pair[1] || new Project.KeyChange(-1, range.end, defaultKey) - - const keyCh1X = Editor.xAtTime(state.contentStateManager, keyCh1.time) - const keyCh2X = Editor.xAtTime(state.contentStateManager, keyCh2.time) - - yield [keyCh1 as Project.KeyChange, keyCh2 as Project.KeyChange, keyCh1X, keyCh2X] - } - } - - - static *iterNotesAndKeyChangesAtRange(state: StateManager, range: Range): Generator<[Project.Note, Project.KeyChange, number, number], void, void> - { - for (const [keyCh1, keyCh2, keyCh1X, keyCh2X] of TrackNotes.iterKeyChangePairsAtRange(state, range)) - { - const time1 = keyCh1.time.max(range.start)! - const time2 = keyCh2.time.min(range.end)! - - for (const note of TrackNotes.iterNotesAtRange(state, new Range(time1, time2))) - yield [note, keyCh1, keyCh1X, keyCh2X] - } - } - - - static yForRow(state: StateManager, row: number): number - { - return state.trackState.h / 2 - (row + 1) * state.trackState.rowScale - } - - - static rowAtY(state: StateManager, y: number): number - { - return -Math.floor((y - state.trackState.h / 2) / state.trackState.rowScale) - 1 - } - - - static rowForPitch(state: StateManager, pitch: number, key: Theory.Key): number - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.octavedDegreeForMidi(pitch - 60) + tonicRowOffset - } - - - static pitchForRow(state: StateManager, row: number, key: Theory.Key): number - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.midiForDegree(row - Math.floor(tonicRowOffset)) + 60 - } - - - static rectForNote(state: StateManager, range: Range, row: number, xStart: number, xEnd: number) - { - const noteOrigX1 = Editor.xAtTime(state.contentStateManager, range.start) - const noteOrigX2 = Editor.xAtTime(state.contentStateManager, range.end) - - const noteY = Math.floor(TrackNotes.yForRow(state, row)) - - let noteX1 = Math.max(noteOrigX1, xStart) - let noteX2 = Math.min(noteOrigX2, xEnd) - - const cutStart = noteOrigX1 < noteX1 - const cutEnd = noteOrigX2 > noteX2 - - //if (!cutStart) noteX1 += 1 - if (!cutEnd) noteX2 -= 1 - - noteX1 = Math.floor(noteX1) - noteX2 = Math.floor(noteX2) - - const noteW = Math.max(2, noteX2 - noteX1) - - return Object.assign( - new Rect(noteX1, noteY, noteW, state.trackState.rowScale), - { cutStart, cutEnd }) - } - - - static render(state: StateManager, ctx: CanvasRenderingContext2D) - { - const visibleRange = Editor.visibleTimeRange(state.contentStateManager) - - const rowAtTop = TrackNotes.rowAtY(state, state.trackState.yScroll) - const rowAtBottom = TrackNotes.rowAtY(state, state.trackState.yScroll + state.trackState.h) - - const octaveAtTop = Math.ceil(rowAtTop / 7) + 1 - const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1 - - for (const [keyCh1, keyCh2, xMin, xMax] of TrackNotes.iterKeyChangePairsAtRange(state, visibleRange)) - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(keyCh1.key.tonic.chroma) - - for (let i = octaveAtBottom; i <= octaveAtTop; i++) - { - const y = 0.5 + Math.floor(TrackNotes.yForRow(state, tonicRowOffset + i * 7) + state.trackState.rowScale) - - ctx.strokeStyle = state.appState.prefs.editor.octaveDividerColor - ctx.beginPath() - ctx.moveTo(xMin, y) - ctx.lineTo(xMax, y) - ctx.stroke() - - for (let j = 1; j < 7; j += 1) - { - const ySuboctave = 0.5 + Math.floor(TrackNotes.yForRow(state, tonicRowOffset + i * 7 + j) + state.trackState.rowScale) - - ctx.strokeStyle = state.appState.prefs.editor.noteRowAlternateBkgColor - ctx.beginPath() - ctx.moveTo(xMin, ySuboctave) - ctx.lineTo(xMax, ySuboctave) - ctx.stroke() - } - - /*if (i == 0) - { - ctx.globalAlpha = 0.05 - ctx.fillStyle = "#fff" - ctx.fillRect(xMin, y - 7 * state.trackState.rowScale, xMax - xMin, 7 * state.trackState.rowScale) - ctx.globalAlpha = 1 - }*/ - } - } - - for (const [note, keyCh, xMin, xMax] of TrackNotes.iterNotesAndKeyChangesAtRange(state, visibleRange)) - { - const key = keyCh.key - const row = TrackNotes.rowForPitch(state, note.pitch, key) - const mode = key.scale.metadata!.mode - const fillStyle = CanvasUtils.fillStyleForDegree(ctx, key.degreeForMidi(note.pitch) + mode) - const hovering = !!state.contentState.mouse.hover && state.contentState.mouse.hover.id == note.id - const selected = state.appState.selection.contains(note.id) - const playing = state.appState.playback.playing && note.range.overlapsPoint(state.appState.playback.time) - TrackNotes.renderNote(state, ctx, note.range, row, xMin, xMax, fillStyle, hovering, selected, playing) - } - - const draw = state.trackState.draw - if (draw) - { - ctx.globalAlpha = 0.6 - - const key = Editor.keyAt(state.contentStateManager, state.trackState.trackId, draw.time1) - const row = TrackNotes.rowForPitch(state, draw.pitch, key) - const mode = key.scale.metadata!.mode - const fillStyle = CanvasUtils.fillStyleForDegree(ctx, key.degreeForMidi(draw.pitch) + mode) - TrackNotes.renderNote(state, ctx, new Range(draw.time1, draw.time2).sorted(), row, -Infinity, Infinity, fillStyle) - - ctx.globalAlpha = 1 - } - } - - - static renderNote(state: StateManager, ctx: CanvasRenderingContext2D, range: Range, row: number, xMin: number, xMax: number, fillStyle: any, hovering?: boolean, selected?: boolean, playing?: boolean) - { - const rect = TrackNotes.rectForNote(state, range, row, xMin, xMax) - - ctx.fillStyle = fillStyle - - ctx.beginPath() - ctx.fillRect(rect.x, rect.y, rect.w, rect.h) - - if (hovering) - { - ctx.globalAlpha = 0.4 - ctx.fillStyle = "#fff" - ctx.fillRect(rect.x, rect.y, rect.w, rect.h) - ctx.globalAlpha = 1 - } - - if (selected || playing) - { - const margin = 3 - ctx.globalAlpha = 0.6 - ctx.fillStyle = "#fff" - ctx.fillRect(rect.x, rect.y + margin, rect.w, rect.h - margin * 2) - ctx.globalAlpha = 1 - } - } -} \ No newline at end of file diff --git a/src_old/editor2/trackNotesPreview.ts b/src_old/editor2/trackNotesPreview.ts deleted file mode 100644 index a656402..0000000 --- a/src_old/editor2/trackNotesPreview.ts +++ /dev/null @@ -1,207 +0,0 @@ -import Editor from "./editor" -import Track from "./track" -import TrackStateManager from "./trackStateManager" -import TrackNotesPreviewState from "./TrackNotesPreviewState" -import Rect from "../util/rect" -import Range from "../util/range" -import Project from "../project/project2" -import Rational from "../util/rational" -import CanvasUtils from "../util/canvasUtils" -import * as Theory from "../theory/theory" - - -type StateManager = TrackStateManager - - -export default class TrackNotesPreview -{ - static init(state: StateManager) - { - Track.init(state) - state.mergeTrackState({ - type: "notesPreview", - rowScale: 2, - }) - } - - - static hover(state: StateManager) - { - state.mergeContentState({ - mouse: { ...state.contentState.mouse, - hover: null, - } - }) - } - - - static elemsAt(state: StateManager, region: any): Project.ID[] - { - const elems = [] - - if (region.y1 === undefined) - { - for (const note of TrackNotesPreview.iterNotesAtRange(state, region.range)) - elems.push(note.id) - } - else - { - for (const [note, keyCh, xMin, xMax] of TrackNotesPreview.iterNotesAndKeyChangesAtRange(state, region.range)) - { - const row = TrackNotesPreview.rowForPitch(state, note.pitch, keyCh.key) - const rect = TrackNotesPreview.rectForNote(state, note.range, row, xMin, xMax) - - if (rect.y1 < region.y2 && rect.y2 > region.y1) - elems.push(note.id) - } - } - - return elems - } - - - static *iterNotesAtRange(state: StateManager, range: Range): Generator - { - const trackElems = state.appState.project.rangedLists.get(state.trackState.trackId) - if (!trackElems) - return - - for (const note of trackElems.iterAtRange(range)) - yield note as Project.Note - } - - - static *iterKeyChangePairsAtRange(state: StateManager, range: Range): Generator<[Project.KeyChange, Project.KeyChange, number, number], void, void> - { - const keyChangeTrackId = Project.keyChangeTrackForTrack(state.appState.project, state.trackState.trackId) - const keyChangeTrackTimedElems = state.appState.project.timedLists.get(keyChangeTrackId) - if (!keyChangeTrackTimedElems) - return - - const firstKeyCh = keyChangeTrackTimedElems.findFirst() as (Project.KeyChange | null) - const defaultKey = firstKeyCh ? firstKeyCh.key : Editor.defaultKey() - - for (const pair of keyChangeTrackTimedElems.iterActiveAtRangePairwise(range)) - { - const keyCh1 = pair[0] || new Project.KeyChange(-1, range.start, defaultKey) - const keyCh2 = pair[1] || new Project.KeyChange(-1, range.end, defaultKey) - - const keyCh1X = Editor.xAtTime(state.contentStateManager, keyCh1.time) - const keyCh2X = Editor.xAtTime(state.contentStateManager, keyCh2.time) - - yield [keyCh1 as Project.KeyChange, keyCh2 as Project.KeyChange, keyCh1X, keyCh2X] - } - } - - - static *iterNotesAndKeyChangesAtRange(state: StateManager, range: Range): Generator<[Project.Note, Project.KeyChange, number, number], void, void> - { - for (const [keyCh1, keyCh2, keyCh1X, keyCh2X] of TrackNotesPreview.iterKeyChangePairsAtRange(state, range)) - { - const time1 = keyCh1.time.max(range.start)! - const time2 = keyCh2.time.min(range.end)! - - for (const note of TrackNotesPreview.iterNotesAtRange(state, new Range(time1, time2))) - yield [note, keyCh1, keyCh1X, keyCh2X] - } - } - - - static yForRow(state: StateManager, row: number): number - { - return state.trackState.h / 2 - (row + 1) * state.trackState.rowScale - } - - - static rowAtY(state: StateManager, y: number): number - { - return -Math.floor((y - state.trackState.h / 2) / state.trackState.rowScale) - 1 - } - - - static rowForPitch(state: StateManager, pitch: number, key: Theory.Key): number - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.octavedDegreeForMidi(pitch - 60) + tonicRowOffset - } - - - static pitchForRow(state: StateManager, row: number, key: Theory.Key): number - { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.midiForDegree(row - Math.floor(tonicRowOffset)) + 60 - } - - - static rectForNote(state: StateManager, range: Range, row: number, xStart: number, xEnd: number) - { - const noteOrigX1 = Editor.xAtTime(state.contentStateManager, range.start) - const noteOrigX2 = Editor.xAtTime(state.contentStateManager, range.end) - - const noteY = Math.floor(TrackNotesPreview.yForRow(state, row)) - - let noteX1 = Math.max(noteOrigX1, xStart) - let noteX2 = Math.min(noteOrigX2, xEnd) - - const cutStart = noteOrigX1 < noteX1 - const cutEnd = noteOrigX2 > noteX2 - - //if (!cutStart) noteX1 += 1 - if (!cutEnd) noteX2 -= 1 - - noteX1 = Math.floor(noteX1) - noteX2 = Math.floor(noteX2) - - const noteW = Math.max(2, noteX2 - noteX1) - - return Object.assign( - new Rect(noteX1, noteY, noteW, state.trackState.rowScale), - { cutStart, cutEnd }) - } - - - static render(state: StateManager, ctx: CanvasRenderingContext2D) - { - const visibleRange = Editor.visibleTimeRange(state.contentStateManager) - - for (const [note, keyCh, xMin, xMax] of TrackNotesPreview.iterNotesAndKeyChangesAtRange(state, visibleRange)) - { - const key = keyCh.key - const row = TrackNotesPreview.rowForPitch(state, note.pitch, key) - const mode = key.scale.metadata!.mode - const fillStyle = CanvasUtils.fillStyleForDegree(ctx, key.degreeForMidi(note.pitch) + mode) - const hovering = !!state.contentState.mouse.hover && state.contentState.mouse.hover.id == note.id - const selected = state.appState.selection.contains(note.id) - const playing = state.appState.playback.playing && note.range.overlapsPoint(state.appState.playback.time) - TrackNotesPreview.renderNote(state, ctx, note.range, row, xMin, xMax, fillStyle, hovering, selected, playing) - } - } - - - static renderNote(state: StateManager, ctx: CanvasRenderingContext2D, range: Range, row: number, xMin: number, xMax: number, fillStyle: any, hovering?: boolean, selected?: boolean, playing?: boolean) - { - const rect = TrackNotesPreview.rectForNote(state, range, row, xMin, xMax) - - ctx.fillStyle = fillStyle - - ctx.beginPath() - ctx.fillRect(rect.x, rect.y, rect.w, rect.h) - - if (hovering) - { - ctx.globalAlpha = 0.4 - ctx.fillStyle = "#fff" - ctx.fillRect(rect.x, rect.y, rect.w, rect.h) - ctx.globalAlpha = 1 - } - - if (selected || playing) - { - const margin = 3 - ctx.globalAlpha = 0.6 - ctx.fillStyle = "#fff" - ctx.fillRect(rect.x, rect.y + margin, rect.w, rect.h - margin * 2) - ctx.globalAlpha = 1 - } - } -} \ No newline at end of file diff --git a/src_old/editor2/trackNotesPreviewState.ts b/src_old/editor2/trackNotesPreviewState.ts deleted file mode 100644 index 92d1b8b..0000000 --- a/src_old/editor2/trackNotesPreviewState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import TrackState from "./trackState" -import Rational from "../util/rational" - - -export default interface TrackNotesPreviewState extends TrackState -{ - rowScale: number -} \ No newline at end of file diff --git a/src_old/editor2/trackNotesState.ts b/src_old/editor2/trackNotesState.ts deleted file mode 100644 index 936cc5e..0000000 --- a/src_old/editor2/trackNotesState.ts +++ /dev/null @@ -1,15 +0,0 @@ -import TrackState from "./trackState" -import Rational from "../util/rational" - - -export default interface TrackNotesState extends TrackState -{ - rowScale: number - - draw: null | - { - time1: Rational - time2: Rational - pitch: number - } -} \ No newline at end of file diff --git a/src_old/editor2/trackState.ts b/src_old/editor2/trackState.ts deleted file mode 100644 index f17792d..0000000 --- a/src_old/editor2/trackState.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default interface TrackState -{ - type: string, - trackIndex: number, - trackId: number, - - y: number, - h: number, - yScroll: number, - - pinned: boolean, -} \ No newline at end of file diff --git a/src_old/editor2/trackStateManager.ts b/src_old/editor2/trackStateManager.ts deleted file mode 100644 index 2d80a50..0000000 --- a/src_old/editor2/trackStateManager.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { AppState, ContentManager, AppReducer } from "../AppState" -import EditorState from "./editorState" -import TrackState from "./trackState" - - -export default class TrackStateManager -{ - contentStateManager: ContentManager - trackIndex: number - - - constructor(contentStateManager: ContentManager, trackIndex: number) - { - this.contentStateManager = contentStateManager - this.trackIndex = trackIndex - } - - - get appState(): AppState - { - return this.contentStateManager.appState - } - - - mergeAppState(newState: Partial) - { - this.contentStateManager.appState = AppReducer.merge(this.contentStateManager.appState, newState) - } - - - get contentState(): EditorState - { - return this.contentStateManager.contentState - } - - - set contentState(newState: EditorState) - { - this.contentStateManager.contentState = newState - } - - - mergeContentState(newState: Partial) - { - this.contentStateManager.mergeContentState(newState) - } - - - get trackState(): T - { - return this.contentStateManager.contentState.tracks[this.trackIndex] as any as T - } - - - set trackState(newState: T) - { - this.contentStateManager.mergeContentState({ - tracks: [ - ...this.contentStateManager.contentState.tracks.slice(0, this.trackIndex), - newState as any as TrackState, - ...this.contentStateManager.contentState.tracks.slice(this.trackIndex + 1), - ] - }) - } - - - mergeTrackState(newState: Partial) - { - this.trackState = { - ...this.trackState, - ...newState, - } - } -} \ No newline at end of file diff --git a/src/main.js b/src_old/main.js similarity index 100% rename from src/main.js rename to src_old/main.js diff --git a/src/menubar/Item.tsx b/src_old/menubar/Item.tsx similarity index 100% rename from src/menubar/Item.tsx rename to src_old/menubar/Item.tsx diff --git a/src/menubar/Root.tsx b/src_old/menubar/Root.tsx similarity index 100% rename from src/menubar/Root.tsx rename to src_old/menubar/Root.tsx diff --git a/src/menubar/index.ts b/src_old/menubar/index.ts similarity index 100% rename from src/menubar/index.ts rename to src_old/menubar/index.ts diff --git a/src_old/playback/PlaybackController.ts b/src_old/playback/PlaybackController.ts deleted file mode 100644 index cb0bd64..0000000 --- a/src_old/playback/PlaybackController.ts +++ /dev/null @@ -1,90 +0,0 @@ -import React from "react" -import { AppManager } from "../AppState" -import { Synth } from "./synth" -import SynthFeed from "./synthFeed" -import Rational from "../util/rational" - - -let synth: Synth | null = null - - -export function usePlaybackController(appManager: AppManager) -{ - const playData = React.useRef({ - playing: false, - timestamp: -1, - }) - - function processFrame(timestamp: number) - { - if (!appManager.appState.playback.playing && playData.current.playing) - { - requestAnimationFrame(() => - { - playData.current.playing = false - - if (synth) - synth.stopAll() - - appManager.mergeAppState({ - playback: { ...appManager.appState.playback, - playing: false, - } - }) - appManager.dispatch() - }) - return - } - - const prevTimestamp = playData.current.timestamp - const deltaTime = (prevTimestamp < 0 ? 0 : timestamp - prevTimestamp) - playData.current.timestamp = timestamp - - if (deltaTime > 0 && deltaTime < 250) - { - const measuresPerSecond = (appManager.appState.project.baseBpm / 4 / 60) - - synth!.process(deltaTime / 1000) - const timeAsFloat = appManager.appState.playback.timeAsFloat + deltaTime / 1000 * measuresPerSecond - appManager.mergeAppState({ - playback: { ...appManager.appState.playback, - timeAsFloat, - time: Rational.fromFloat(timeAsFloat, 64), - } - }) - appManager.dispatch() - } - - requestAnimationFrame(processFrame) - } - - if (appManager.appState.playback.playing && !playData.current.playing) - { - playData.current.playing = true - playData.current.timestamp = -1 - - requestAnimationFrame(() => - { - if (!synth) - synth = new Synth() - - synth.reset() - SynthFeed.feed(appManager.appState.project, synth, appManager.appState.playback.timeStart) - synth.play() - - appManager.mergeAppState({ - playback: { ...appManager.appState.playback, - time: appManager.appState.playback.timeStart, - timeAsFloat: appManager.appState.playback.timeStart.asFloat(), - } - }) - appManager.dispatch() - - requestAnimationFrame(async () => - { - await synth!.prepare(appManager.appState.sflib, appManager.appState.project) - requestAnimationFrame(processFrame) - }) - }) - } -} \ No newline at end of file diff --git a/src/playback/_global.ts b/src_old/playback/_global.ts similarity index 100% rename from src/playback/_global.ts rename to src_old/playback/_global.ts diff --git a/src/playback/index.ts b/src_old/playback/index.ts similarity index 100% rename from src/playback/index.ts rename to src_old/playback/index.ts diff --git a/src/playback/instrument.ts b/src_old/playback/instrument.ts similarity index 100% rename from src/playback/instrument.ts rename to src_old/playback/instrument.ts diff --git a/src/playback/instrumentBasic.ts b/src_old/playback/instrumentBasic.ts similarity index 100% rename from src/playback/instrumentBasic.ts rename to src_old/playback/instrumentBasic.ts diff --git a/src_old/playback/instrumentSflib.ts b/src_old/playback/instrumentSflib.ts index 57d59f3..758f64a 100644 --- a/src_old/playback/instrumentSflib.ts +++ b/src_old/playback/instrumentSflib.ts @@ -1,60 +1,256 @@ -import { Synth } from "./synth" -import Project from "../project/project2" -import { SflibInstrument, SflibMeta } from "./library" -import { sflibGetInstrument } from "./libraryCache" +import * as Playback from "./index" +import * as Project from "../project" +import * as MathUtils from "../util/mathUtils" -export class InstrumentSflib +const notesToDelete = new Set() + + +interface Note { - synth: Synth - trackId: number - audioWorklet?: AudioWorkletNode + request: Playback.NoteRequest + zone: Playback.SflibInstrumentZone + timePassedMs: number + endTimeMs: number + nodeSrc: AudioBufferSourceNode + nodeEnvelope: GainNode + nodeVolume: GainNode +} - constructor(synth: Synth, trackId: number) +export class InstrumentSflib extends Playback.Instrument +{ + collectionId: string + instrumentId: string + sflibInstrument: Playback.SflibInstrument | null + notes: Note[] + + + constructor( + synth: Playback.SynthManager, + outputNode: AudioNode, + collectionId: string, + instrumentId: string) { - this.synth = synth - this.trackId = trackId + super(synth, outputNode) + this.collectionId = collectionId + this.instrumentId = instrumentId + this.sflibInstrument = null + this.notes = [] } - async prepare(sflibMeta: SflibMeta, trackInstrument: Project.TrackInstrumentSflib) + async prepare() { - const instrument = await sflibGetInstrument(sflibMeta, trackInstrument.collectionId, trackInstrument.instrumentId) - if (!instrument) - throw "missing sflib instrument" - - this.audioWorklet = new AudioWorkletNode(this.synth.audioCtx, "SflibAudioProcessor") - this.audioWorklet.connect(this.synth.audioCtxOutput) - this.audioWorklet.port.postMessage({ - type: "setInstrument", - outputSampleRate: this.synth.audioCtx.sampleRate, - instrument - }) - } + this.sflibInstrument = await Playback.sflibGetInstrument( + this.collectionId, this.instrumentId, this.synth.audioCtx) - - destroy() - { - this.audioWorklet!.disconnect() - this.audioWorklet = undefined + if (!this.sflibInstrument) + { + console.error("could not load sflib " + this.collectionId + "/" + this.instrumentId) + return + } } - noteOn(midiPitch: number) - { - this.audioWorklet!.port.postMessage({ type: "noteOn", midiPitch }) - } - - - noteOff(midiPitch: number) - { - this.audioWorklet!.port.postMessage({ type: "noteOff", midiPitch }) + async destroy() + { + + } + + + isFinished() + { + return !this.sflibInstrument || this.notes.length == 0 + } + + + playNote(request: Playback.NoteRequest) + { + if (!this.sflibInstrument) + return + + //if (this.notes.has(request.noteId)) + // return + + const midiPitch = request.midiPitchSeq[0].value + + let zone = this.sflibInstrument.zones.find(z => + midiPitch >= z.midiPitchMin && + midiPitch <= z.midiPitchMax) + + if (!zone) + { + let nearestMidiPitchDistance = Infinity + + for (const z of this.sflibInstrument.zones) + { + const distance = Math.min( + Math.abs(z.midiPitchMin - midiPitch), + Math.abs(z.midiPitchMax - midiPitch)) + + if (distance < nearestMidiPitchDistance) + { + nearestMidiPitchDistance = distance + zone = z + } + } + } + + if (!zone) + return + + const freq = MathUtils.midiToHertz(midiPitch) + + const audioBuffer = this.sflibInstrument.audioBuffers[zone.sampleIndex] + + + const sourceNode = this.synth.audioCtx.createBufferSource() + sourceNode.playbackRate.value = freq / MathUtils.midiToHertz(zone.midiPitchBase) + sourceNode.buffer = audioBuffer + sourceNode.loop = (zone.loopMode == "loop") + sourceNode.loopStart = zone.loopStartIndex / audioBuffer.sampleRate + sourceNode.loopEnd = zone.loopEndIndex / audioBuffer.sampleRate + + + const time = 0.05 + Math.max(0, request.startMs / 1000) + const delayTime = time + zone.volEnvDelaySec + const attackTime = delayTime + (zone.volEnvAttackSec || 0.005) + const holdTime = attackTime + zone.volEnvHoldSec + const decayTime = holdTime + zone.volEnvDecaySec + const sustainLevel = zone.volEnvSustain || 0.0001 + const releaseTime = time + request.durationMs / 1000 + const endTime = releaseTime + Math.max(zone.volEnvReleaseSec, 0.05) + + /* + + Envelope parameters: + + | 100% level + | ______ + | /| |\ + | / | | \ sustainLevel + | / | | \____________ + | / | | | |\ + | / | | | | \ + | / | | | | \ + --+------------------------------------------- + ^ ^ ^ ^ ^ ^ ^ endTime + | | | | | + releaseTime + | | | | + decayTime + | | | + holdTime + | | + attackTime + | + delayTime + + time + + */ + + const releaseTimeCap = releaseTime - 0.001 + const cappedDelayTime = Math.min(delayTime, releaseTimeCap) + const cappedAttackTime = Math.min(attackTime, releaseTimeCap) + const cappedHoldTime = Math.min(holdTime, releaseTimeCap) + + const releaseF = (releaseTime - cappedHoldTime) / (decayTime - cappedHoldTime) + const releaseLevel = releaseF >= 1 ? sustainLevel : Math.pow(sustainLevel, releaseF) + + const envelopeNode = this.synth.audioCtx.createGain() + envelopeNode.gain.value = 0 + envelopeNode.gain.setValueAtTime(0.0001, cappedDelayTime) + envelopeNode.gain.exponentialRampToValueAtTime(1, cappedAttackTime) + envelopeNode.gain.setValueAtTime(1, cappedHoldTime) + + if (decayTime < releaseTime) + { + envelopeNode.gain.exponentialRampToValueAtTime(sustainLevel, decayTime) + envelopeNode.gain.setValueAtTime(sustainLevel, releaseTime) + envelopeNode.gain.exponentialRampToValueAtTime(0.0001, endTime) + } + else + { + envelopeNode.gain.exponentialRampToValueAtTime(releaseLevel, releaseTime) + envelopeNode.gain.setValueAtTime(releaseLevel, releaseTime) + envelopeNode.gain.exponentialRampToValueAtTime(0.0001, endTime) + } + + /*console.log("playNote", this.synth.audioCtx.currentTime, request) + console.log("envelope", + "del", (delayTime - time).toFixed(3), + "atk", (attackTime - time).toFixed(3), + "hld", (holdTime - time).toFixed(3), + "dec", (decayTime - time).toFixed(3), + "::", + sustainLevel.toFixed(3), + releaseLevel.toFixed(3), + "::", + "rel", (releaseTimeCap - time).toFixed(3), + "end", (endTime - time).toFixed(3))*/ + + const volumeNode = this.synth.audioCtx.createGain() + volumeNode.gain.value = MathUtils.dbToLinearGain(request.volumeSeq[0].value) + + + sourceNode.connect(envelopeNode) + envelopeNode.connect(volumeNode) + volumeNode.connect(this.outputNode) + + sourceNode.start(time) + + const note: Note = + { + request, + zone, + timePassedMs: -(time - this.synth.audioCtx.currentTime) * 1000, + endTimeMs: (endTime - time) * 1000, + nodeSrc: sourceNode, + nodeEnvelope: envelopeNode, + nodeVolume: volumeNode, + } + + this.notes.push(note) } - stop() + stopNote(note: Note) + { + note.nodeSrc.stop() + note.nodeSrc.disconnect() + } + + + stopAll() { - this.audioWorklet!.port.postMessage({ type: "stopAll" }) + for (const note of this.notes) + this.stopNote(note) + + this.notes = [] + } + + + process(deltaTimeMs: number) + { + notesToDelete.clear() + + for (const note of this.notes) + { + note.timePassedMs += deltaTimeMs + + if (note.timePassedMs > note.endTimeMs) + { + this.stopNote(note) + notesToDelete.add(note) + } + else if (note.zone.loopMode != "loop") + { + const sample = this.sflibInstrument!.audioBuffers[note.zone.sampleIndex] + if (note.timePassedMs > sample.length / sample.sampleRate * 1000) + { + this.stopNote(note) + notesToDelete.add(note) + } + } + } + + this.notes = this.notes.filter(n => !notesToDelete.has(n)) + notesToDelete.clear() } } \ No newline at end of file diff --git a/src_old/playback/library.ts b/src_old/playback/library.ts deleted file mode 100644 index b66f65e..0000000 --- a/src_old/playback/library.ts +++ /dev/null @@ -1,91 +0,0 @@ -import React from "react" -import { AppManager } from "../AppState" - - -export const sflibUrl = "/library/" - - -export interface SflibMeta -{ - ready: boolean - collections: SflibCollectionMeta[] -} - - -export interface SflibCollectionMeta -{ - id: string - name: string - instruments: SflibInstrumentMeta[] -} - - -export interface SflibInstrumentMeta -{ - id: string - filename: string - filesize: number - name: string - midiBank: number - midiPreset: number -} - - -export interface SflibInstrument -{ - id: string - name: string - midiPreset: number - midiBank: number - zones: SflibInstrumentZone[] - samples: string[] -} - - -export interface SflibInstrumentZone -{ - sampleIndex: number - sampleRate: number - startLoop: number - endLoop: number - loopMode: string - - minPitch: number - maxPitch: number - basePitch: number - minVel: number - maxVel: number - - delayVolEnv?: number - attackVolEnv?: number - holdVolEnv?: number - decayVolEnv?: number - sustainVolEnv?: number - releaseVolEnv?: number - exclusiveClass?: number -} - - -async function loadSflibMeta(): Promise -{ - const data = await fetch(sflibUrl + "library.json") - const meta: SflibMeta = await data.json() - meta.ready = true - console.log("loaded sflib meta", meta) - return meta -} - - -export function useSoundfontLibrary(appManager: AppManager) -{ - React.useEffect(() => - { - window.requestAnimationFrame(async () => - { - const sflib = await loadSflibMeta() - appManager.mergeAppState({ sflib }) - appManager.dispatch() - }) - - }, []) -} \ No newline at end of file diff --git a/src_old/playback/libraryCache.ts b/src_old/playback/libraryCache.ts deleted file mode 100644 index 661bc65..0000000 --- a/src_old/playback/libraryCache.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { sflibUrl, SflibMeta, SflibInstrument } from "./library" -import zlib from "zlib" - - -const sflibCache = new Map() - - -export async function sflibGetInstrument(meta: SflibMeta, collectionId: string, instrumentId: string): Promise -{ - const id = collectionId + "/" + instrumentId - const cached = sflibCache.get(id) - if (cached) - return cached - - const collMeta = meta.collections.find(c => c.id == collectionId) - if (!collMeta) - return null - - const instrMeta = collMeta.instruments.find(i => i.id == instrumentId) - if (!instrMeta) - return null - - const instrFilename = instrMeta.filename - - const data = await fetch(sflibUrl + collectionId + "/" + instrFilename) - const dataCompressed = await data.arrayBuffer() - console.log(dataCompressed) - const instr: SflibInstrument = JSON.parse(zlib.inflateSync(Buffer.from(dataCompressed)).toString("utf8")) - - console.log("loaded sflib instrument", instr) - - sflibCache.set(id, instr) - return instr -} \ No newline at end of file diff --git a/src/playback/projectFeed.ts b/src_old/playback/projectFeed.ts similarity index 100% rename from src/playback/projectFeed.ts rename to src_old/playback/projectFeed.ts diff --git a/src/playback/sflib.ts b/src_old/playback/sflib.ts similarity index 100% rename from src/playback/sflib.ts rename to src_old/playback/sflib.ts diff --git a/src_old/playback/sflibWorklet.ts b/src_old/playback/sflibWorklet.ts deleted file mode 100644 index 8a11180..0000000 --- a/src_old/playback/sflibWorklet.ts +++ /dev/null @@ -1,267 +0,0 @@ -import { SflibInstrument, SflibInstrumentZone } from "./library" - - -interface AudioWorkletProcessor -{ - readonly port: MessagePort - process(inputs: Float32Array[][], outputs: Float32Array[][], parameters: Record): boolean -} - -declare var AudioWorkletProcessor: -{ - prototype: AudioWorkletProcessor - new (options?: AudioWorkletNodeOptions): AudioWorkletProcessor -} - -declare function registerProcessor( - name: string, - processorCtor: (new (options?: AudioWorkletNodeOptions) => AudioWorkletProcessor) & { parameterDescriptors?: AudioParamDescriptor[] } -): void - - -function lerp(a: number, b: number, t: number): number -{ - return a + (b - a) * t -} - - -function sampleEnvelopeStart(envelope: SflibInstrumentZone, time: number): number -{ - const delay = envelope.delayVolEnv || 0 - if (time < delay) - return 0 - - time -= delay - const attack = envelope.attackVolEnv || 0 - if (time < attack) - return time / attack - - time -= attack - const hold = envelope.holdVolEnv || 0 - if (time < hold) - return 1 - - time -= hold - const decay = envelope.decayVolEnv || 0 - const sustain = envelope.sustainVolEnv || 1 - if (time < decay) - return lerp(1, sustain, time / decay) - - return sustain -} - - -function sampleEnvelope(envelope: SflibInstrumentZone, time: number, isOff: boolean, offTime: number): number -{ - const envelopeStart = sampleEnvelopeStart(envelope, time) - - if (!isOff) - { - return envelopeStart - } - else - { - time -= offTime - const release = envelope.releaseVolEnv || 0 - if (time < release) - return lerp(envelopeStart, 0, time / release) - - return 0 - } -} - - -interface Instrument extends SflibInstrument -{ - sampleBuffers: number[][] -} - - -interface PlayingNote -{ - on: boolean - offTime: number - time: number - sampleHead: number - midiPitch: number - zone: SflibInstrumentZone -} - - -class SflibAudioProcessor extends AudioWorkletProcessor -{ - outputSampleRate: number - instrument: Instrument | null - notes: PlayingNote[] - - - constructor(options?: AudioWorkletNodeOptions) - { - super(options) - - this.outputSampleRate = 1 - this.instrument = null - this.notes = [] - - this.port.onmessage = (e) => - { - //console.log(e.data) - - if (e.data.type == "setInstrument") - { - this.outputSampleRate = e.data.outputSampleRate - - this.instrument = e.data.instrument - this.instrument!.sampleBuffers = [] - - for (const sampleRaw of this.instrument!.samples) - { - //console.log(sampleRaw) - const buffer = Buffer.from(sampleRaw, "base64") - //console.log(buffer) - - const array = new Array(buffer.length / 2) - for (let i = 0; i < buffer.length / 2; i++) - { - const b0 = buffer[i * 2] - const b1 = buffer[i * 2 + 1] - let uint16 = (b0 << 8) | b1 - if ((uint16 & 0x8000) != 0) - uint16 = -(0x10000 - uint16) - - array[i] = uint16 / 0x8000 - } - - //console.log(array) - this.instrument!.sampleBuffers.push(array) - } - } - - else if (e.data.type == "noteOn") - { - for (const oldNote of this.notes) - { - if (oldNote.on && oldNote.midiPitch == e.data.midiPitch) - { - oldNote.on = false - oldNote.offTime = oldNote.time - } - } - - const zone = this.instrument!.zones.find( - z => e.data.midiPitch >= z.minPitch && e.data.midiPitch <= z.maxPitch) - - if (zone) - { - const note: PlayingNote = - { - on: true, - offTime: 0, - time: 0, - sampleHead: 0, - midiPitch: e.data.midiPitch, - zone, - } - - this.notes.push(note) - } - } - - else if (e.data.type == "noteOff") - { - for (const note of this.notes) - { - if (note.on && note.midiPitch == e.data.midiPitch) - { - note.on = false - note.offTime = note.time - } - } - } - - else if (e.data.type == "stopAll") - { - for (const note of this.notes) - { - if (note.on) - { - note.on = false - note.offTime = note.time - } - } - } - - //delete this.instrument.samples - } - } - - - process(inputs: Float32Array[][], outputs: Float32Array[][], parameters: Record): boolean - { - for (let n = this.notes.length - 1; n >= 0; n--) - { - const note = this.notes[n] - const output = outputs[0] - const zone = note.zone - const sampleData = this.instrument!.sampleBuffers[zone.sampleIndex] - const rateConversion = zone.sampleRate / this.outputSampleRate - const pitchConversion = midiToHertz(note.midiPitch) / midiToHertz(zone.basePitch) - - const getSampleAt = (index: number): number => - { - const indexBefore = Math.floor(index) - const indexAfter = Math.ceil(index) - - const indexFraction = (index - indexBefore) - - const sampleBefore = sampleData[indexBefore % sampleData.length] - const sampleAfter = sampleData[indexAfter % sampleData.length] - - const sampleInterp = sampleBefore + (sampleAfter - sampleBefore) * indexFraction - //console.log(index, indexFraction, sampleBefore, sampleAfter, sampleInterp) - - return sampleInterp - } - - for (let i = 0; i < output[0].length; i++) - { - const envelope = sampleEnvelope(zone, note.time, !note.on, note.offTime) - const sample = Math.pow(envelope, 4) * getSampleAt(note.sampleHead * rateConversion * pitchConversion) - - for (let c = 0; c < output.length; c++) - { - output[c][i] += sample * 0.25 - } - - note.time += 1 / this.outputSampleRate - - if (zone.loopMode == "noLoop") - { - if (note.sampleHead * rateConversion * pitchConversion < sampleData.length - 1) - note.sampleHead += 1 - } - else - { - note.sampleHead += 1 - if (note.sampleHead * rateConversion * pitchConversion >= zone.endLoop - 1) - note.sampleHead -= (zone.endLoop - zone.startLoop - 1) / rateConversion / pitchConversion - } - } - - if (!note.on && note.time - note.offTime > (zone.releaseVolEnv || 0)) - this.notes = [...this.notes.slice(0, n), ...this.notes.slice(n + 1)] - } - - return true - } -} - - -function midiToHertz(midi: number): number -{ - return Math.pow(2, (midi - 69) / 12) * 440 -} - - -registerProcessor("SflibAudioProcessor", SflibAudioProcessor) -console.log("registered SflibAudioProcessor") \ No newline at end of file diff --git a/src_old/playback/synth.ts b/src_old/playback/synth.ts deleted file mode 100644 index 63b010c..0000000 --- a/src_old/playback/synth.ts +++ /dev/null @@ -1,168 +0,0 @@ -import Project from "../project/project2" -import { sflibGetInstrument } from "./libraryCache" -import { AppState } from "../AppState" -import { SflibMeta } from "./library" -import { InstrumentSflib } from "./instrumentSflib" - - -interface NoteEvent -{ - trackId: number - time: number - midiPitch: number - volume: number - duration: number -} - - -interface PlayingNote -{ - event: NoteEvent - remainingDuration: number -} - - -export class Synth -{ - audioCtx: AudioContext - audioCtxOutput: GainNode - audioTracks: InstrumentSflib[] - - cachedTracks: Project.Track[] = [] - - time: number - noteEvents: NoteEvent[] - playingNotes: PlayingNote[] - - - constructor() - { - this.audioCtx = new AudioContext() - this.audioTracks = [] - - this.audioCtxOutput = this.audioCtx.createGain() - this.audioCtxOutput.connect(this.audioCtx.destination) - this.audioCtxOutput.gain.value = 0.25 - - this.time = 0 - this.noteEvents = [] - this.playingNotes = [] - } - - - destroy() - { - this.audioCtx.close() - } - - - reset() - { - } - - - async prepare(sflibMeta: SflibMeta, project: Project) - { - await this.audioCtx.audioWorklet.addModule("/build/sflibWorklet.js") - - if (this.cachedTracks !== project.tracks) - { - for (const audioTrack of this.audioTracks) - audioTrack.destroy() - - this.audioTracks = [] - - for (const track of project.tracks) - { - if (track.trackType == Project.TrackType.Notes) - { - const trackNotes = track - if (trackNotes.instrument.instrumentType == Project.TrackInstrumentType.Sflib) - { - const audioTrack = new InstrumentSflib(this, track.id) - await audioTrack.prepare(sflibMeta, trackNotes.instrument) - this.audioTracks.push(audioTrack) - } - } - } - } - - this.cachedTracks = project.tracks - } - - - isFinished() - { - return this.noteEvents.length == 0 && this.playingNotes.length == 0 - } - - - play() - { - this.noteEvents.sort(function (a, b) { return a.time - b.time }) - } - - - stopAll() - { - this.time = 0 - this.noteEvents = [] - this.playingNotes = [] - - for (const audioTrack of this.audioTracks) - audioTrack.stop() - } - - - process(deltaTime: number) - { - this.time += deltaTime - - // Update audio output. - for (let i = this.playingNotes.length - 1; i >= 0; i--) - { - const note = this.playingNotes[i] - note.remainingDuration -= deltaTime - if (note.remainingDuration <= 0) - { - this.audioTracks.find(t => t.trackId == note.event.trackId)!.noteOff(note.event.midiPitch) - this.playingNotes.splice(i, 1) - } - } - - // Process pending note events up to the current time. - let noteEventsProcessed = 0 - while (noteEventsProcessed < this.noteEvents.length && - this.noteEvents[noteEventsProcessed].time <= this.time) - { - const ev = this.noteEvents[noteEventsProcessed] - noteEventsProcessed++ - - this.audioTracks.find(t => t.trackId == ev.trackId)!.noteOn(ev.midiPitch) - - const playingNote = - { - event: ev, - remainingDuration: ev.duration, - } - - this.playingNotes.push(playingNote) - } - - // Remove processed events. - this.noteEvents.splice(0, noteEventsProcessed) - } - - - addNoteEvent(trackId: number, time: number, midiPitch: number, volume: number, duration: number) - { - this.noteEvents.push( - { - trackId, - time: time + this.time, - midiPitch, - volume, - duration - }) - } -} \ No newline at end of file diff --git a/src_old/playback/synthFeed.ts b/src_old/playback/synthFeed.ts deleted file mode 100644 index 5029441..0000000 --- a/src_old/playback/synthFeed.ts +++ /dev/null @@ -1,56 +0,0 @@ -import Rational from "../util/rational" -import Project from "../project/project2" -import { Synth } from "./synth" -import MathUtils from "../util/mathUtils" - - -export default class SynthFeed -{ - static feed(project: Project, synth: Synth, startTick: Rational, useChordPatterns = true) - { - const chordVolumeMul = 0.5 - - const addNoteEvent = (trackId: number, tickStart: Rational, duration: Rational, midiPitch: number, volume: number) => - { - const offsetStart = tickStart.subtract(startTick) - - const measuresPerSecond = project.baseBpm / 4 / 60 - - let timeStart = offsetStart.asFloat() / measuresPerSecond - let timeDuration = duration.asFloat() / measuresPerSecond - - if (timeStart <= 0) - { - timeDuration += timeStart - timeStart = 0 - } - - if (timeDuration <= 0) - return - - //console.log("event note [" + pitch + "] at tick " + tickStart.toString() + " = " + timeStart + " s") - synth.addNoteEvent(trackId, timeStart, midiPitch, volume, timeDuration) - } - - // Register notes. - for (const track of project.tracks) - { - const rangedList = project.rangedLists.get(track.id) - if (!rangedList) - continue - - for (const elem of rangedList.iterAll()) - { - if (elem.type != Project.ElementType.Note) - continue - - const note = elem - - if (note.range.end.compare(startTick) <= 0) - continue - - addNoteEvent(track.id, note.range.start, note.range.duration, note.pitch, 1) - } - } - } -} diff --git a/src/playback/synthManager.ts b/src_old/playback/synthManager.ts similarity index 100% rename from src/playback/synthManager.ts rename to src_old/playback/synthManager.ts diff --git a/src/popup/Button.tsx b/src_old/popup/Button.tsx similarity index 100% rename from src/popup/Button.tsx rename to src_old/popup/Button.tsx diff --git a/src/popup/Divider.tsx b/src_old/popup/Divider.tsx similarity index 100% rename from src/popup/Divider.tsx rename to src_old/popup/Divider.tsx diff --git a/src_old/popup/MenuBar.tsx b/src_old/popup/MenuBar.tsx deleted file mode 100644 index a13b36a..0000000 --- a/src_old/popup/MenuBar.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React from "react" -import Rect from "../util/rect" -import { useAppManager } from "../AppContext" -import Project from "../project/project2" -import { AppReducer } from "../AppState" -import MenuFilePopup from "./MenuFilePopup" -import PlaybackToolbox from "./PlaybackToolbox" - - -interface MenuBarProps -{ -} - - -interface MenuBarItemProps -{ - label: string - popupElem: any -} - - -function MenuBarItem(props: MenuBarItemProps) -{ - const appManager = useAppManager() - - const refButton = React.useRef(null) - const onClick = () => - { - const domRect = refButton.current!.getBoundingClientRect() - const rect = new Rect(domRect.x, domRect.y, domRect.width, domRect.height) - appManager.appState = AppReducer.createPopup( - appManager.appState, - rect, - props.popupElem, - {}) - appManager.dispatch() - } - - const isOpen = - appManager.appState.popup != null && - appManager.appState.popup.elem == props.popupElem - - return -} - - -export default function MenuBar(props: MenuBarProps) -{ - return
- - - - - -
-} \ No newline at end of file diff --git a/src_old/popup/MenuFilePopup.tsx b/src_old/popup/MenuFilePopup.tsx deleted file mode 100644 index ed4d191..0000000 --- a/src_old/popup/MenuFilePopup.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React from "react" -import PopupButton from "../popup/PopupButton" -import Rect from "../util/rect" -import { useAppManager } from "../AppContext" -import Project from "../project/project2" -import IoMidi from "../project/ioMidi" - - -interface MenuFilePopupProps -{ -} - - -export default function MenuFilePopup(props: MenuFilePopupProps) -{ - const appManager = useAppManager() - - const doNew = () => - { - appManager.mergeAppState({ project: Project.getDefault() }) - appManager.dispatch() - } - - const doOpen = () => - { - document.getElementById("gInputFileOpen")!.click() - } - - React.useEffect(() => - { - const handleOpenFile = (ev: Event) => - { - const elem = ev.target as HTMLInputElement - - if (elem.files!.length != 1) - return - - let reader = new FileReader() - reader.readAsArrayBuffer(elem.files![0]) - reader.onload = () => - { - const bytes = new Uint8Array(reader.result as any) - - const project = IoMidi.read(bytes) - appManager.mergeAppState({ project }) - appManager.dispatch() - } - } - - const input = document.getElementById("gInputFileOpen") as HTMLInputElement - input!.addEventListener("change", handleOpenFile) - - return () => - { - //input!.removeEventListener("change", handleOpenFile) - } - - }, []) - - return <> - - - - - - - - - -} \ No newline at end of file diff --git a/src_old/popup/PlaybackToolbox.tsx b/src_old/popup/PlaybackToolbox.tsx deleted file mode 100644 index 65b3cb9..0000000 --- a/src_old/popup/PlaybackToolbox.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from "react" -import { useAppManager } from "../AppContext" - - -export default function PlaybackToolbox(props: {}) -{ - const appManager = useAppManager() - const togglePlayback = () => - { - appManager.mergeAppState({ playback: { ...appManager.appState.playback, - playing: !appManager.appState.playback.playing, - }}) - appManager.dispatch() - } - - - React.useEffect(() => - { - const handleSpacebarKey = (ev: KeyboardEvent) => - { - if (ev.key == " ") - { - ev.preventDefault() - ev.stopPropagation() - togglePlayback() - } - } - - window.addEventListener("keydown", handleSpacebarKey) - - return () => - { - window.removeEventListener("keydown", handleSpacebarKey) - } - - }, []) - - - return
- - - -
-} \ No newline at end of file diff --git a/src/popup/Root.tsx b/src_old/popup/Root.tsx similarity index 100% rename from src/popup/Root.tsx rename to src_old/popup/Root.tsx diff --git a/src/popup/_global.ts b/src_old/popup/_global.ts similarity index 100% rename from src/popup/_global.ts rename to src_old/popup/_global.ts diff --git a/src/popup/index.ts b/src_old/popup/index.ts similarity index 100% rename from src/popup/index.ts rename to src_old/popup/index.ts diff --git a/src/prefs/_global.ts b/src_old/prefs/_global.ts similarity index 100% rename from src/prefs/_global.ts rename to src_old/prefs/_global.ts diff --git a/src/prefs/index.ts b/src_old/prefs/index.ts similarity index 100% rename from src/prefs/index.ts rename to src_old/prefs/index.ts diff --git a/src/prefs/prefs.ts b/src_old/prefs/prefs.ts similarity index 100% rename from src/prefs/prefs.ts rename to src_old/prefs/prefs.ts diff --git a/src_old/project/ioCompressedStr.js b/src_old/project/ioCompressedStr.js deleted file mode 100644 index 67083b0..0000000 --- a/src_old/project/ioCompressedStr.js +++ /dev/null @@ -1,333 +0,0 @@ -import Project from "./project.js" -import Theory from "../theory.ts" -import { URLBinaryEncoder, URLBinaryDecoder } from "../util/urlBinaryEncoder.js" -import Rational from "../util/rational.js" -import Range from "../util/range.js" - - -export default class IOCompressedStr -{ - static read(str) - { - let song = new Project() - - if (!str.startsWith("3_") && - !str.startsWith("4_")) - throw "unsupported version" - - const r = new URLBinaryDecoder(str.substr(2)) - - // Read header. - const version = r.readInteger() - song.baseBpm = r.readInteger() - - if (version != 3 && version != 4) - throw "unsupported version" - - // Read note tracks. - const trackNum = r.readInteger() - for (let j = 0; j < trackNum; j++) - { - // Read note data as structure-of-arrays. - const noteNum = r.readInteger() - - let noteData = [] - - let prevNoteRangeStartInteger = 0 - for (let i = 0; i < noteNum; i++) - { - prevNoteRangeStartInteger += r.readInteger() // range.start.integer - noteData[i] = [ prevNoteRangeStartInteger ] - } - - for (let i = 0; i < noteNum; i++) - noteData[i][1] = r.readInteger() // range.start.numeratorWithoutInteger - - for (let i = 0; i < noteNum; i++) - noteData[i][2] = r.readInteger() // range.start.denominator - - for (let i = 0; i < noteNum; i++) - noteData[i][3] = r.readInteger() // range.duration.numerator - - for (let i = 0; i < noteNum; i++) - noteData[i][4] = r.readInteger() // range.duration.denominator - - for (let i = 0; i < noteNum; i++) - { - const start = Rational.fromIntegerPlusRational(noteData[i][0], noteData[i][1], noteData[i][2]) - const duration = new Rational(noteData[i][3], noteData[i][4]) - - song = song.upsertNote(new Project.Note( - Range.fromStartDuration(start, duration), - r.readInteger() + 60)) - } - } - - // Read chord data as structure-of-arrays. - const chordNum = r.readInteger() - - let chordData = [] - - let prevChordRangeStartInteger = 0 - for (let i = 0; i < chordNum; i++) - { - prevChordRangeStartInteger += r.readInteger() // range.start.integer - chordData[i] = [ prevChordRangeStartInteger ] - } - - for (let i = 0; i < chordNum; i++) - chordData[i][1] = r.readInteger() // range.start.numeratorWithoutInteger - - for (let i = 0; i < chordNum; i++) - chordData[i][2] = r.readInteger() // range.start.denominator - - for (let i = 0; i < chordNum; i++) - chordData[i][3] = r.readInteger() // range.duration.numerator - - for (let i = 0; i < chordNum; i++) - chordData[i][4] = r.readInteger() // range.duration.denominator - - for (let i = 0; i < chordNum; i++) - chordData[i][5] = r.readInteger() // chord.rootMidi - - for (let i = 0; i < chordNum; i++) - chordData[i][6] = r.readInteger() // chord.rootAccidental - - for (let i = 0; i < chordNum; i++) - chordData[i][7] = r.readString() // chord.kindId - - if (version >= 4) - { - for (let i = 0; i < chordNum; i++) - chordData[i][8] = r.readInteger() // chord.inversion - } - - for (let i = 0; i < chordNum; i++) - chordData[i][9] = r.readInteger() // chord.modifiers.length - - if (version >= 4) - { - for (let i = 0; i < chordNum; i++) - { - chordData[i][10] = [] - for (let mod = 0; mod < chordData[i][9]; mod++) - chordData[i][10].push([r.readString(), r.readInteger()]) // chord.modifiers[mod] - } - } - else - { - for (let i = 0; i < chordNum; i++) - for (let mod = 0; mod < chordData[i][8]; mod++) - r.readString() - } - - for (let i = 0; i < chordNum; i++) - { - const start = Rational.fromIntegerPlusRational(chordData[i][0], chordData[i][1], chordData[i][2]) - const duration = new Rational(chordData[i][3], chordData[i][4]) - - song = song.upsertChord(new Project.Chord( - Range.fromStartDuration(start, duration), - new Theory.Chord( - chordData[i][5], - chordData[i][6], - Theory.Chord.kindFromId(chordData[i][7]), - chordData[i][8], - chordData[i][10]))) - } - - // Read key change data as structure-of-arrays. - const keyChangeNum = r.readInteger() - - let keyChangeData = [] - - for (let i = 0; i < keyChangeNum; i++) - keyChangeData[i] = [ r.readInteger() ] // time.numerator - - for (let i = 0; i < keyChangeNum; i++) - keyChangeData[i][1] = r.readInteger() // time.denominator - - for (let i = 0; i < keyChangeNum; i++) - keyChangeData[i][2] = r.readInteger() // key.tonic.letter - - for (let i = 0; i < keyChangeNum; i++) - keyChangeData[i][3] = r.readInteger() // key.tonic.accidental - - for (let i = 0; i < keyChangeNum; i++) - keyChangeData[i][4] = r.readInteger() // key.scale.chromas.length - - for (let i = 0; i < keyChangeNum; i++) - { - keyChangeData[i][5] = [] - for (let p = 0; p < keyChangeData[i][4]; p++) - keyChangeData[i][5][p] = r.readInteger() // key.scale.chromas[p] - } - - for (let i = 0; i < keyChangeNum; i++) - { - const time = new Rational(keyChangeData[i][0], keyChangeData[i][1]) - - song = song.upsertKeyChange(new Project.KeyChange( - time, - new Theory.Key( - new Theory.PitchName(keyChangeData[i][2], keyChangeData[i][3]), - Theory.Scale.fromChromas(keyChangeData[i][5])))) - } - - // Read meter change data as structure-of-arrays. - const meterChangeNum = r.readInteger() - - let meterChangeData = [] - - for (let i = 0; i < meterChangeNum; i++) - meterChangeData[i] = [ r.readInteger() ] // time.numerator - - for (let i = 0; i < meterChangeNum; i++) - meterChangeData[i][1] = r.readInteger() // time.denominator - - for (let i = 0; i < meterChangeNum; i++) - meterChangeData[i][2] = r.readInteger() // numerator - - for (let i = 0; i < meterChangeNum; i++) - meterChangeData[i][3] = r.readInteger() // denominator - - for (let i = 0; i < meterChangeNum; i++) - { - const time = new Rational(meterChangeData[i][0], meterChangeData[i][1]) - - song = song.upsertMeterChange(new Project.MeterChange( - time, - new Theory.Meter(meterChangeData[i][2], meterChangeData[i][3]))) - } - - return song.withRefreshedRange() - } - - - static write(project) - { - const song = project.withRefreshedRange() - - const w = new URLBinaryEncoder() - - // Write header. - w.writeInteger(4) // Version - w.writeInteger(project.baseBpm) - - // Write note tracks. - const trackNum = 1 - w.writeInteger(trackNum) - for (var j = 0; j < trackNum; j++) - { - // Write note data as a structure-of-arrays. - w.writeInteger(project.notes.size) - - let prevNoteRangeStartInteger = 0 - for (const note of project.notes.iterAll()) - { - w.writeInteger(note.range.start.integer - prevNoteRangeStartInteger) - prevNoteRangeStartInteger = note.range.start.integer - } - - for (const note of project.notes.iterAll()) - w.writeInteger(note.range.start.numeratorWithoutInteger) - - for (const note of project.notes.iterAll()) - w.writeInteger(note.range.start.denominator) - - for (const note of project.notes.iterAll()) - w.writeInteger(note.range.duration.numerator) - - for (const note of project.notes.iterAll()) - w.writeInteger(note.range.duration.denominator) - - for (const note of project.notes.iterAll()) - w.writeInteger(note.pitch - 60) - } - - // Write chord data as a structure-of-arrays. - w.writeInteger(project.chords.size) - - let prevChordRangeStartInteger = 0 - for (const chord of project.chords.iterAll()) - { - w.writeInteger(chord.range.start.integer - prevChordRangeStartInteger) - prevChordRangeStartInteger = chord.range.start.integer - } - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.range.start.numeratorWithoutInteger) - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.range.start.denominator) - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.range.duration.numerator) - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.range.duration.denominator) - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.chord.rootMidi) - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.chord.rootAccidental) - - for (const chord of project.chords.iterAll()) - w.writeString(chord.chord.kindId) - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.chord.inversion) - - for (const chord of project.chords.iterAll()) - w.writeInteger(chord.chord.modifiers.length) - - for (const chord of project.chords.iterAll()) - for (const mod of chord.chord.modifiers) - { - w.writeString(mod[0]) - w.writeInteger(mod[1]) - } - - // Write key change data as a structure-of-arrays. - w.writeInteger(project.keyChanges.size) - - for (const keyChange of project.keyChanges.iterAll()) - w.writeInteger(keyChange.time.numerator) - - for (const keyChange of project.keyChanges.iterAll()) - w.writeInteger(keyChange.time.denominator) - - for (const keyChange of project.keyChanges.iterAll()) - w.writeInteger(keyChange.key.tonic.letter) - - for (const keyChange of project.keyChanges.iterAll()) - w.writeInteger(keyChange.key.tonic.accidental) - - for (const keyChange of project.keyChanges.iterAll()) - w.writeInteger(keyChange.key.scale.chromas.length) - - for (const keyChange of project.keyChanges.iterAll()) - for (const p of keyChange.key.scale.chromas) - w.writeInteger(p) - - // Write meter change data as a structure-of-arrays. - w.writeInteger(project.meterChanges.size) - - for (const meterChange of project.meterChanges.iterAll()) - w.writeInteger(meterChange.time.numerator) - - for (const meterChange of project.meterChanges.iterAll()) - w.writeInteger(meterChange.time.denominator) - - for (const meterChange of project.meterChanges.iterAll()) - w.writeInteger(meterChange.meter.numerator) - - for (const meterChange of project.meterChanges.iterAll()) - w.writeInteger(meterChange.meter.denominator) - - - console.log(w.getCompressedURLSafe().length) - return "4_" + w.getCompressedURLSafe() - } -} \ No newline at end of file diff --git a/src_old/project/ioJson.js b/src_old/project/ioJson.js deleted file mode 100644 index 9aa5284..0000000 --- a/src_old/project/ioJson.js +++ /dev/null @@ -1,191 +0,0 @@ -import Project from "./project.js" -import Theory from "../theory.ts" -import Rational from "../util/rational.js" -import Range from "../util/range.js" - - -export default class IOJson -{ - static write(project) - { - let str = "{\n" - - str += "\"version\": " + 4 + ",\n" - str += "\"bpm\": " + project.baseBpm + ",\n" - str += "\n" - - str += "\"tracks\":\n" - str += "[\n" - for (let track = 0; track < 1; track++) - { - str += "{\n" - str += "\"notes\":\n" - str += "[\n" - let firstNote = true - for (const note of project.notes.iterAll()) - { - if (!firstNote) - str += ",\n" - - firstNote = false - - str += "[" - str += note.range.start .toJSONString() + "," - str += note.range.duration.toJSONString() + "," - str += note.pitch - str += "]" - } - str += "\n" - str += "]\n" - str += "}\n" - } - str += "],\n" - str += "\n" - - str += "\"chords\":\n" - str += "[\n" - let firstChord = true - for (const chord of project.chords.iterAll()) - { - if (!firstChord) - str += ",\n" - - firstChord = false - - str += "[" - str += chord.range.start .toJSONString() + "," - str += chord.range.duration.toJSONString() + "," - str += chord.chord.rootMidi + "," - str += chord.chord.rootAccidental + "," - str += "\"" + chord.chord.kindId + "\"," - str += chord.chord.inversion + "," - str += JSON.stringify(chord.chord.modifiers) - str += "]" - } - str += "\n" - str += "],\n" - str += "\n" - - str += "\"keyChanges\":\n" - str += "[\n" - let firstKeyChange = true - for (const keyChange of project.keyChanges.iterAll()) - { - if (!firstKeyChange) - str += ",\n" - - firstKeyChange = false - - str += "[" - str += keyChange.time.toJSONString() + "," - str += keyChange.key.tonic.letter + "," - str += keyChange.key.tonic.accidental + "," - str += "[" + keyChange.key.scale.chromas.join(",") + "]" - str += "]" - } - str += "\n" - str += "],\n" - str += "\n" - - str += "\"meterChanges\":\n" - str += "[\n" - let firstMeterChange = true - for (const meterChange of project.meterChanges.iterAll()) - { - if (!firstMeterChange) - str += ",\n" - - firstMeterChange = false - - str += "[" - str += meterChange.time.toJSONString() + "," - str += meterChange.meter.numerator + "," - str += meterChange.meter.denominator - str += "]" - } - str += "\n" - str += "]\n" - - str += "}" - return str - } - - - static read(json) - { - let song = new Project() - song.baseBpm = json.bpm - - for (const note of json.tracks[0].notes) - song = song.upsertNote(new Project.Note( - Range.fromStartDuration(Rational.fromArray(note[0]), Rational.fromArray(note[1])), - note[2])) - - if (json.version >= 4) - { - for (const chord of json.chords) - { - let modifiers = [] - for (const mod of chord[6]) - modifiers.push(mod) - - song = song.upsertChord(new Project.Chord( - Range.fromStartDuration(Rational.fromArray(chord[0]), Rational.fromArray(chord[1])), - new Theory.Chord(chord[2], chord[3], Theory.Chord.kindFromId(chord[4]), chord[5], modifiers))) - } - - for (const keyChange of json.keyChanges) - song = song.upsertKeyChange(new Project.KeyChange( - Rational.fromArray(keyChange[0]), - new Theory.Key( - new Theory.PitchName(keyChange[1], keyChange[2]), - Theory.Scale.fromChromas(keyChange[3])))) - } - else if (json.version == 3) - { - for (const chord of json.chords) - { - song = song.upsertChord(new Project.Chord( - Range.fromStartDuration(Rational.fromArray(chord[0]), Rational.fromArray(chord[1])), - new Theory.Chord(chord[2], chord[3], Theory.Chord.kindFromId(chord[4]), 0, []))) - } - - for (const keyChange of json.keyChanges) - song = song.upsertKeyChange(new Project.KeyChange( - Rational.fromArray(keyChange[0]), - new Theory.Key( - new Theory.PitchName( - Theory.Utils.chromaToLetter(keyChange[1] + keyChange[2]) || 0, - Theory.Utils.chromaToAccidental(keyChange[1] + keyChange[2]) || 0), - Theory.Scale.fromChromas(keyChange[3])))) - } - else - { - const oldChordKinds = - ["M","m","+","o","5","6","m6","7","maj7","m7","mmaj7","+7","+maj7","o7","%7","9","maj9","m9","mmaj9","9?","+9","+maj9","o9","ob9","%9","%b9"] - - for (const chord of json.chords) - song = song.upsertChord(new Project.Chord( - Range.fromStartDuration(Rational.fromArray(chord[0]), Rational.fromArray(chord[1])), - new Theory.Chord(chord[3], chord[4], Theory.Chord.kindFromId(oldChordKinds[chord[2]]), 0, []))) - - const oldScales = [ "Major", "Dorian", "Phrygian", "Lydian", "Mixolydian", "Minor", "Locrian" ] - - for (const keyChange of json.keyChanges) - song = song.upsertKeyChange(new Project.KeyChange( - Rational.fromArray(keyChange[0]), - new Theory.Key( - new Theory.PitchName( - Theory.Utils.chromaToLetter(keyChange[2] + keyChange[3]) || 0, - Theory.Utils.chromaToAccidental(keyChange[2] + keyChange[3]) || 0), - Theory.Scale.parse(oldScales[keyChange[1]])))) - } - - for (const meterChange of json.meterChanges) - song = song.upsertMeterChange(new Project.MeterChange( - Rational.fromArray(meterChange[0]), - new Theory.Meter(meterChange[1], meterChange[2]))) - - return song.withRefreshedRange() - } -} \ No newline at end of file diff --git a/src_old/project/ioMidi.js b/src_old/project/ioMidi.js deleted file mode 100644 index 39bbe4d..0000000 --- a/src_old/project/ioMidi.js +++ /dev/null @@ -1,110 +0,0 @@ -import Project from "./project.js" -import Theory from "../theory.ts" -import { MidiFile } from "../util/midi.js" -import Rational from "../util/rational.js" -import Range from "../util/range.js" - - -export default class IOMidi -{ - static read(bytes) - { - const midi = MidiFile.fromBytes(bytes) - console.log(midi) - - const findFirstEvent = (kind) => - { - for (const track of midi.tracks) - for (const ev of track.events) - if (ev.kind == kind) - return ev - - return null - } - - let song = new Project() - - const tempoEv = findFirstEvent("setTempo") - const msPerQuarterNote = (tempoEv ? tempoEv.msPerQuarterNote : 500000) - song.baseBpm = Math.round(60 * 1000 * 1000 / msPerQuarterNote) - - let notesToAdd = [] - for (const track of midi.tracks) - { - for (const noteOn of track.events) - { - if (noteOn.kind != "noteOn" || noteOn.channel == 9 || noteOn.velocity == 0) - continue - - let noteOff = null - for (const ev of track.events) - { - if (ev.kind != "noteOn" && ev.kind != "noteOff") - continue - - if (ev.time <= noteOn.time || ev.channel != noteOn.channel || ev.key != noteOn.key) - continue - - if (noteOff == null || ev.time < noteOff.time) - { - noteOff = ev - break - } - } - - if (!noteOff) - continue - - const onTick = Rational.fromFloat(noteOn.time / midi.ticksPerQuarterNote / 4, 27720) - const offTick = Rational.fromFloat(noteOff.time / midi.ticksPerQuarterNote / 4, 27720) - - notesToAdd.push(new Project.Note(new Range(onTick, offTick), noteOn.key)) - } - } - - song = song.upsertNotes(notesToAdd) - - for (const track of midi.tracks) - { - for (const ev of track.events) - { - if (ev.kind != "setKeySignature") - continue - - const tonicPitches = [ 0, 7, 2, 9, 4, 11, 5, 0, 7, 2, 9, 4, 11, 5, 0, 7, 2, 9, 4, 11] - const tonicLetters = [ 0, 4, 1, 5, 2, 6, 3, 0, 4, 1, 5, 2, 6, 3, 0, 4, 1, 5, 2, 6] - const tonicAccidentals = [-1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1] - const index = ev.accidentals + 7 + (ev.scale == 0 ? 0 : 2) - - if (index < 0 || index >= tonicPitches.length) - continue - - const time = Rational.fromFloat(ev.time / midi.ticksPerQuarterNote / 4, 27720) - song = song.upsertKeyChange(new Project.KeyChange(time, - new Theory.Key( - new Theory.PitchName(tonicLetters[index], tonicAccidentals[index]), - Theory.Scale.parse(ev.scale == 0 ? "Major" : "Minor")))) - } - } - - for (const track of midi.tracks) - { - for (const ev of track.events) - { - if (ev.kind != "setTimeSignature") - continue - - const time = Rational.fromFloat(ev.time / midi.ticksPerQuarterNote / 4, 27720) - song = song.upsertMeterChange(new Project.MeterChange(time, new Theory.Meter(ev.numerator, ev.denominator))) - } - } - - if (!song.keyChanges.findActiveAt(new Rational(0))) - song = song.upsertKeyChange(new Project.KeyChange(new Rational(0), Theory.Key.parse("C Major"))) - - if (!song.meterChanges.findActiveAt(new Rational(0))) - song = song.upsertMeterChange(new Project.MeterChange(new Rational(0), new Theory.Meter(4, 4))) - - return song.withRefreshedRange() - } -} \ No newline at end of file diff --git a/src_old/project/ioMidi.ts b/src_old/project/ioMidi.ts deleted file mode 100644 index 387c61e..0000000 --- a/src_old/project/ioMidi.ts +++ /dev/null @@ -1,120 +0,0 @@ -import Project from "../project/project2" -import * as Theory from "../theory/theory" -import { MidiFileReader } from "../util/midi" -import Rational from "../util/rational.js" -import Range from "../util/range.js" - - -export default class IoMidi -{ - static read(bytes: number[] | Buffer | Uint8Array): Project - { - const midi = MidiFileReader.fromBytes(bytes) - console.log(midi) - - const findFirstEvent = (kind: string) => - { - for (const track of midi.tracks) - for (const ev of track.events) - if (ev.kind == kind) - return ev - - return null - } - - let project = new Project() - - const tempoEv = findFirstEvent("setTempo") - const msPerQuarterNote = (tempoEv ? tempoEv.msPerQuarterNote : 500000) - project.baseBpm = Math.round(60 * 1000 * 1000 / msPerQuarterNote) - - const track1Id = project.nextId - project = Project.upsertTrack(project, new Project.TrackKeyChanges()) - - const track2Id = project.nextId - project = Project.upsertTrack(project, new Project.TrackMeterChanges()) - - project = Project.upsertTimedElement(project, new Project.KeyChange(track1Id, new Rational(0), Theory.Key.parse("D Major"))) - project = Project.upsertTimedElement(project, new Project.MeterChange(track2Id, new Rational(0), new Theory.Meter(4, 4))) - - /*for (const track of midi.tracks) - { - for (const ev of track.events) - { - if (ev.kind != "setKeySignature") - continue - - const tonicPitches = [ 0, 7, 2, 9, 4, 11, 5, 0, 7, 2, 9, 4, 11, 5, 0, 7, 2, 9, 4, 11] - const tonicLetters = [ 0, 4, 1, 5, 2, 6, 3, 0, 4, 1, 5, 2, 6, 3, 0, 4, 1, 5, 2, 6] - const tonicAccidentals = [-1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1] - const index = ev.accidentals + 7 + (ev.scale == 0 ? 0 : 2) - - if (index < 0 || index >= tonicPitches.length) - continue - - const time = Rational.fromFloat(ev.time / midi.ticksPerQuarterNote / 4, 27720) - song = song.upsertKeyChange(new Project.KeyChange(time, - new Theory.Key( - new Theory.PitchName(tonicLetters[index], tonicAccidentals[index]), - Theory.Scale.parse(ev.scale == 0 ? "Major" : "Minor")))) - } - } - - for (const track of midi.tracks) - { - for (const ev of track.events) - { - if (ev.kind != "setTimeSignature") - continue - - const time = Rational.fromFloat(ev.time / midi.ticksPerQuarterNote / 4, 27720) - song = song.upsertMeterChange(new Project.MeterChange(time, new Theory.Meter(ev.numerator, ev.denominator))) - } - }*/ - - for (const track of midi.tracks) - { - const trackId = project.nextId - project = Project.upsertTrack(project, new Project.TrackNotes()) - - for (const noteOn of track.events) - { - if (noteOn.kind != "noteOn" || noteOn.channel == 9 || noteOn.velocity == 0) - continue - - let noteOff = null - for (const ev of track.events) - { - if (ev.kind != "noteOn" && ev.kind != "noteOff") - continue - - if (ev.time <= noteOn.time || ev.channel != noteOn.channel || ev.key != noteOn.key) - continue - - if (noteOff == null || ev.time < noteOff.time) - { - noteOff = ev - break - } - } - - if (!noteOff) - continue - - const onTick = Rational.fromFloat(noteOn.time / midi.ticksPerQuarterNote / 4, 27720) - const offTick = Rational.fromFloat(noteOff.time / midi.ticksPerQuarterNote / 4, 27720) - - project = Project.upsertRangedElement(project, - new Project.Note(trackId, new Range(onTick, offTick), noteOn.key)) - } - } - - /*if (!song.keyChanges.findActiveAt(new Rational(0))) - song = song.upsertKeyChange(new Project.KeyChange(new Rational(0), Theory.Key.parse("C Major"))) - - if (!song.meterChanges.findActiveAt(new Rational(0))) - song = song.upsertMeterChange(new Project.MeterChange(new Rational(0), new Theory.Meter(4, 4))) - */ - return project//.withRefreshedRange() - } -} \ No newline at end of file diff --git a/src_old/project/playbackSynth.js b/src_old/project/playbackSynth.js deleted file mode 100644 index bfcf0dc..0000000 --- a/src_old/project/playbackSynth.js +++ /dev/null @@ -1,174 +0,0 @@ -import Rational from "../util/rational.js" -import MathUtils from "../util/math.js" -import Editor from "../editor/editor.js" - - -export default class PlaybackSynth -{ - static feedToSynth(project, synth, startTick, useChordPatterns = true) - { - const chordVolumeMul = 0.5 - - const addNoteEvent = (tickStart, duration, instrument, pitch, volume) => - { - const offsetStart = tickStart.subtract(startTick) - - const measuresPerSecond = (project.baseBpm / 4 / 60) - - let timeStart = offsetStart.asFloat() / measuresPerSecond - let timeDuration = duration.asFloat() / measuresPerSecond - - if (timeStart <= 0) - { - timeDuration += timeStart - timeStart = 0 - } - - if (timeDuration <= 0) - return - - //console.log("event note [" + pitch + "] at tick " + tickStart.toString() + " = " + timeStart + " s") - synth.addNoteEvent(timeStart, instrument, MathUtils.midiToHertz(pitch), volume, timeDuration) - } - - // Register notes. - for (const note of project.notes.iterAll()) - { - if (note.range.end.compare(startTick) <= 0) - continue - - addNoteEvent(note.range.start, note.range.duration, 0, note.pitch, 1) - } - - // Register chords. - for (const chord of project.chords.iterAll()) - { - if (chord.range.end.compare(startTick) <= 0) - continue - - const pitches = chord.chord.strummingPitches - - if (!useChordPatterns) - { - for (let j = 0; j < pitches.length; j++) - addNoteEvent(chord.range.start, chord.range.duration, 1, pitches[j], chordVolumeMul) - - continue - } - - const meterCh = project.meterChanges.findActiveAt(chord.range.start) - const meter = meterCh ? meterCh.meter : Editor.defaultMeter() - const meterBeatLength = new Rational(1, meter.denominator) - const measureBreak = null//that.forcedMeasures.findActiveAt(chord.range.start) - - const pattern = getChordStrummingPattern(meter) - - let tick = meterCh ? meterCh.time : chord.range.start - //if (measureBreak != null) - // tick.max(measureBreak.tick) - - let skipTick = new Rational(0) - let patternIndex = 0 - let mustPlayFirstBeat = false - - while (tick.compare(chord.range.end) < 0) - { - const patternBeat = pattern[patternIndex] - const patternBeatKind = patternBeat[0] - let patternBeatLength = patternBeat[1].multiply(meterBeatLength) - patternIndex = (patternIndex + 1) % pattern.length - - let nextTick = tick.add(patternBeatLength) - if (nextTick.compare(chord.range.end) > 0) - { - nextTick = chord.range.end - patternBeatLength = nextTick.subtract(tick) - } - - // Handle beats after the first one. - if (tick.compare(chord.range.start) > 0 && skipTick.compare(new Rational(0)) <= 0) - { - if (mustPlayFirstBeat) - { - mustPlayFirstBeat = false - for (let j = 0; j < pitches.length; j++) - addNoteEvent(chord.range.start, tick.subtract(chord.range.start), 1, pitches[j], chordVolumeMul) - } - - switch (patternBeatKind) - { - case 0: - { - for (let j = 0; j < pitches.length; j++) - addNoteEvent(tick, patternBeatLength, 1, pitches[j], 0.9 * chordVolumeMul) - break - } - case 1: - { - for (let j = 1; j < pitches.length; j++) - addNoteEvent(tick, patternBeatLength, 1, pitches[j], 0.5 * chordVolumeMul) - break - } - case 2: - { - addNoteEvent(tick, patternBeatLength, 1, pitches[0], 0.5 * chordVolumeMul) - break - } - } - } - - skipTick = skipTick.subtract(patternBeatLength) - - if (tick.compare(chord.range.start) <= 0 && nextTick.compare(chord.range.start) > 0) - { - mustPlayFirstBeat = true - - if (!(tick.compare(chord.range.start) == 0 && patternBeatKind == 0)) - skipTick = pattern[0][1].multiply(meterBeatLength) - } - - tick = nextTick - } - - if (mustPlayFirstBeat) - { - mustPlayFirstBeat = false - for (let j = 0; j < pitches.length; j++) - addNoteEvent(chord.range.start, tick.subtract(chord.range.start), 1, pitches[j], 0.7) - } - } - } -} - - -function getChordStrummingPattern(meter) -{ - // [[beat kind, duration], ...] - // Beat kinds: - // 0: Full chord - // 1: Full chord minus bass - // 2: Only bass - const one = [[0, new Rational(1)]] - const two = [[0, new Rational(1)], [1, new Rational(1, 2)], [2, new Rational(1, 2)]] - const three = [[0, new Rational(1)], [1, new Rational(1) ], [1, new Rational(1) ]] - - switch (meter.numerator) - { - case 2: return two - case 3: return three - case 4: return two.concat(two) - case 5: return three.concat(two) - case 6: return three.concat(three) - case 7: return three.concat(two).concat(two) - case 8: return two.concat(two).concat(two).concat(two) - case 9: return three.concat(three).concat(three) - - default: - { - let pattern = [] - for (let i = 0; i < meter.numerator; i++) - pattern = pattern.concat(one) - return pattern - } - } -} diff --git a/src_old/project/project.js b/src_old/project/project.js deleted file mode 100644 index 5cd9015..0000000 --- a/src_old/project/project.js +++ /dev/null @@ -1,280 +0,0 @@ -import ListOfPoints from "../util/listOfPoints.js" -import ListOfRanges from "../util/listOfRanges.js" -import Rational from "../util/rational.js" -import Range from "../util/range.js" -import Theory from "../theory.ts" -import IOJson from "./ioJson.js" -import IOMidi from "./ioMidi.js" -import IOCompressedStr from "./ioCompressedStr.js" - - -export default class Project -{ - constructor() - { - this.nextId = 1 - this.baseBpm = 120 - this.range = new Range(new Rational(0), new Rational(4)) - this.notes = new ListOfRanges() - this.chords = new ListOfRanges() - this.meterChanges = new ListOfPoints() - this.keyChanges = new ListOfPoints() - } - - - static getDefault() - { - return new Project() - .upsertKeyChange(new Project.KeyChange(new Rational(0, 4), Theory.Key.parse("C Major"))) - .upsertMeterChange(new Project.MeterChange(new Rational(0, 4), new Theory.Meter(4, 4))) - .withRefreshedRange() - } - - - withChanges(obj) - { - let song = new Project() - song.nextId = this.nextId - song.baseBpm = this.baseBpm - song.range = this.range - song.notes = this.notes - song.chords = this.chords - song.meterChanges = this.meterChanges - song.keyChanges = this.keyChanges - - return Object.assign(song, obj) - } - - - withRefreshedRange() - { - let range = null - range = Range.merge(range, this.notes.getTotalRange()) - range = Range.merge(range, this.chords.getTotalRange()) - range = Range.merge(range, this.meterChanges.getTotalRange()) - range = Range.merge(range, this.keyChanges.getTotalRange()) - - if (range === null) - range = new Range(new Rational(0), new Rational(1)) - - if (range.duration.asFloat() < 1) - range = Range.fromStartDuration(range.start, new Rational(1)) - - if (this.range.start.compare(range.start) == 0 && - this.range.end.compare(range.end) == 0) - return this - - return this.withChanges({ range }) - } - - - _upsertElement(listField, elem, remove = false) - { - let nextId = this.nextId - let list = this[listField] - - if (elem.id < 0) - { - elem = elem.withChanges({ id: nextId }) - nextId++ - } - else - { - list = list.removeById(elem.id) - } - - if (!remove) - list = list.add(elem) - - return this.withChanges({ nextId, [listField]: list }) - } - - - _upsertElements(listField, elems, remove = false) - { - let nextId = this.nextId - let list = this[listField] - - let newElems = [] - for (let i = 0; i < elems.length; i++) - { - const elem = elems[i] - if (elem.id < 0) - { - newElems.push(elem.withChanges({ id: nextId })) - nextId++ - } - else - { - newElems.push(elem) - list = list.removeById(elem.id) - } - } - - if (!remove) - list = list.addMany(newElems) - - return this.withChanges({ nextId, [listField]: list }) - } - - - upsertNote(note, remove = false) - { - return this._upsertElement("notes", note, remove) - } - - - upsertNotes(notes, remove = false) - { - return this._upsertElements("notes", notes, remove) - } - - - upsertChord(chord, remove = false) - { - return this._upsertElement("chords", chord, remove) - } - - - upsertMeterChange(meterChange, remove = false) - { - return this._upsertElement("meterChanges", meterChange, remove) - } - - - upsertKeyChange(keyChange, remove = false) - { - return this._upsertElement("keyChanges", keyChange, remove) - } - - - findById(id) - { - return ( - this.notes.findById(id) || - this.chords.findById(id) || - this.keyChanges.findById(id) || - this.meterChanges.findById(id) - ) - } - - - update(elem) - { - let song = this.withChanges({}) - song.notes = song.notes.update(elem) - song.chords = song.chords.update(elem) - song.keyChanges = song.keyChanges.update(elem) - song.meterChanges = song.meterChanges.update(elem) - return song - } - - - removeById(id) - { - let song = this.withChanges({}) - song.notes = song.notes.removeById(id) - song.chords = song.chords.removeById(id) - song.keyChanges = song.keyChanges.removeById(id) - song.meterChanges = song.meterChanges.removeById(id) - return song - } - - - toJson() - { - return IOJson.write(this) - } - - - static fromJson(json) - { - return IOJson.read(json) - } - - - static fromMidi(bytes) - { - return IOMidi.read(bytes) - } - - - toCompressedStr() - { - return IOCompressedStr.write(this) - } - - - static fromCompressedStr(str) - { - return IOCompressedStr.read(str) - } - - - static Note = class ProjectNote - { - constructor(range, pitch) - { - this.id = -1 - this.range = range - this.pitch = pitch - } - - - withChanges(obj) - { - return Object.assign(new ProjectNote(this.range, this.pitch), { id: this.id }, obj) - } - } - - - static Chord = class ProjectChord - { - constructor(range, chord) - { - this.id = -1 - this.range = range - this.chord = chord - } - - - withChanges(obj) - { - return Object.assign(new ProjectChord(this.range, this.chord), { id: this.id }, obj) - } - } - - - static MeterChange = class ProjectMeterChange - { - constructor(time, meter) - { - this.id = -1 - this.time = time - this.meter = meter - } - - - withChanges(obj) - { - return Object.assign(new ProjectMeterChange(this.time, this.meter), { id: this.id }, obj) - } - } - - - static KeyChange = class ProjectKeyChange - { - constructor(time, key) - { - this.id = -1 - this.time = time - this.key = key - } - - - withChanges(obj) - { - return Object.assign(new ProjectKeyChange(this.time, this.key), { id: this.id }, obj) - } - } -} \ No newline at end of file diff --git a/src_old/project/project2.ts b/src_old/project/project2.ts deleted file mode 100644 index b36f78b..0000000 --- a/src_old/project/project2.ts +++ /dev/null @@ -1,329 +0,0 @@ -import Immutable from "immutable" -import Range from "../util/range" -import Rational from "../util/rational" -import ListOfPoints from "../util/listOfPoints" -import ListOfRanges from "../util/listOfRanges" -import * as Theory from "../theory/theory" - - -export class Project -{ - nextId: Project.ID - baseBpm: number - tracks: Project.Track[] - timedLists: Immutable.Map> - rangedLists: Immutable.Map> - elems: Immutable.Map - - - constructor() - { - this.nextId = 1 - this.baseBpm = 120 - this.tracks = [] - this.timedLists = Immutable.Map>() - this.rangedLists = Immutable.Map>() - this.elems = Immutable.Map() - } - - - static getDefault(): Project - { - let project = new Project() - - const track1Id = project.nextId - project = Project.upsertTrack(project, new Project.TrackKeyChanges()) - - const track2Id = project.nextId - project = Project.upsertTrack(project, new Project.TrackMeterChanges()) - - project = Project.upsertTimedElement(project, new Project.KeyChange(track1Id, new Rational(0), Theory.Key.parse("D Major"))) - project = Project.upsertTimedElement(project, new Project.MeterChange(track2Id, new Rational(0), new Theory.Meter(4, 4))) - - const track3Id = project.nextId - project = Project.upsertTrack(project, new Project.TrackNotes()) - for (let i = 0; i < 16; i++) - project = Project.upsertRangedElement(project, new Project.Note(track3Id, Range.fromStartDuration(new Rational(i, 4), new Rational(1, 4)), 60 + i % 8)) - - /*const track4Id = project.nextId - project = Project.upsertTrack(project, new Project.TrackNotes()) - for (let i = 0; i < 16; i++) - project = Project.upsertRangedElement(project, new Project.Note(track4Id, Range.fromStartDuration(new Rational(i, 4), new Rational(1, 4)), 68 - (i % 8))) - */ - - return project - } - - - static upsertTrack(project: Project, track: Project.Track, remove: boolean = false): Project - { - let nextId = project.nextId - let tracks = project.tracks - - if (!track.id) - { - track = track.withChanges({ id: nextId }) - nextId++ - } - else - { - tracks = tracks.filter(t => t.id !== track.id) - } - - if (!remove) - { - const trackIndex = tracks.findIndex(t => t.id === track.id) - if (trackIndex < 0) - tracks = [...tracks, track] - else - tracks = [ - ...tracks.slice(0, trackIndex), - track, - ...tracks.slice(trackIndex + 1) - ] - } - - let elems = project.elems - if (!remove) - elems = elems.set(track.id, track) - - return Object.assign({}, project, { nextId, elems, tracks }) - } - - - static upsertTimedElement(project: Project, elem: Project.TimedElement, remove: boolean = false): Project - { - let nextId = project.nextId - - if (!elem.id) - { - elem = Project.Element.withChanges(elem, { id: nextId }) - nextId++ - } - - let timedList = project.timedLists.get(elem.parentId) || new ListOfPoints() - timedList = timedList.add(elem) - - let elems = project.elems.set(elem.id, elem) - let timedLists = project.timedLists.set(elem.parentId, timedList) - - return Object.assign({}, project, { nextId, elems, timedLists }) - } - - - static upsertRangedElement(project: Project, elem: Project.RangedElement, remove: boolean = false): Project - { - let nextId = project.nextId - - if (!elem.id) - { - elem = Project.Element.withChanges(elem, { id: nextId }) - nextId++ - } - - let rangedList = project.rangedLists.get(elem.parentId) || new ListOfRanges() - rangedList = rangedList.add(elem) - - let elems = project.elems.set(elem.id, elem) - let rangedLists = project.rangedLists.set(elem.parentId, rangedList) - - return Object.assign({}, project, { nextId, elems, rangedLists }) - } - - - static keyChangeTrackForTrack(project: Project, trackId: Project.ID): Project.ID - { - return 1 - } - - - static meterChangeTrackForTrack(project: Project, trackId: Project.ID): Project.ID - { - return 2 - } -} - - -export namespace Project -{ - export type ID = number - - - export enum ElementType - { - Track, - Note, - KeyChange, - MeterChange, - } - - - export class Element - { - type: Project.ElementType = -1 - id: Project.ID = 0 - parentId: Project.ID = 0 - - - constructor(type: Project.ElementType, parentId: Project.ID) - { - this.type = type - this.parentId = parentId - } - - - static withChanges(original: T, changes: any): T - { - return Object.assign({}, original, changes) - } - } - - - export enum TrackType - { - Notes, - KeyChanges, - MeterChanges, - } - - - export class Track extends Element - { - trackType: Project.TrackType = 0 - - - constructor(trackType: Project.TrackType) - { - super(ElementType.Track, 0) - this.trackType = trackType - } - - - withChanges(changes: any): this - { - return Object.assign({}, this, changes) - } - } - - - export enum TrackInstrumentType - { - Sflib, - } - - - export interface TrackInstrument - { - instrumentType: TrackInstrumentType - } - - - export interface TrackInstrumentSflib extends TrackInstrument - { - collectionId: string - instrumentId: string - } - - - export class TrackNotes extends Track - { - instrument: TrackInstrument - - - constructor() - { - super(Project.TrackType.Notes) - this.instrument = { - instrumentType: TrackInstrumentType.Sflib, - collectionId: "arachno", - instrumentId: "grand_piano", - } - } - } - - - export class TrackKeyChanges extends Track - { - constructor() - { - super(Project.TrackType.KeyChanges) - } - } - - - export class TrackMeterChanges extends Track - { - constructor() - { - super(Project.TrackType.MeterChanges) - } - } - - - export class TimedElement extends Element - { - time: Rational - - - constructor(type: Project.ElementType, parentId: Project.ID, time: Rational) - { - super(type, parentId) - this.time = time - } - } - - - export class RangedElement extends Element - { - range: Range - - - constructor(type: Project.ElementType, parentId: Project.ID, range: Range) - { - super(type, parentId) - this.range = range - } - } - - - export class Note extends RangedElement - { - pitch: number - - - constructor(parentId: Project.ID, range: Range, pitch: number) - { - super(Project.ElementType.Note, parentId, range) - this.pitch = pitch - } - } - - - export class KeyChange extends TimedElement - { - key: Theory.Key - - - constructor(parentId: Project.ID, time: Rational, key: Theory.Key) - { - super(Project.ElementType.KeyChange, parentId, time) - this.key = key - } - } - - - export class MeterChange extends TimedElement - { - meter: Theory.Meter - - - constructor(parentId: Project.ID, time: Rational, meter: Theory.Meter) - { - super(Project.ElementType.MeterChange, parentId, time) - this.meter = meter - } - } -} - - -export default Project \ No newline at end of file diff --git a/src_old/synth/instrument.js b/src_old/synth/instrument.js deleted file mode 100644 index dbe736e..0000000 --- a/src_old/synth/instrument.js +++ /dev/null @@ -1,168 +0,0 @@ -// `sampleDefs` is an array containing each sample's -// URL and frequency, sorted by frequency, like so: -// [ -// [440, "piano/a4.mp3"], -// [880, "piano/a5.mp3"] -// ] -export class Instrument -{ - constructor(synth, sampleDefs) - { - this.synth = synth - - this.samples = [] - for (let i = 0; i < sampleDefs.length; i++) - this.samples.push(this.load(synth, sampleDefs[i][1], sampleDefs[i][0])) - } - - - load(synth, url, frequency) - { - let sample = - { - buffer: null, - frequency - } - - let request = new XMLHttpRequest() - request.open("GET", url, true) - request.responseType = "arraybuffer" - - request.onload = () => - { - synth.audioCtx.decodeAudioData( - request.response, - (buffer) => { sample.buffer = buffer }, - () => { console.log("Error loading audio <" + url + ">") }) - } - - request.send() - return sample - } - - - playNote(desiredFreq, desiredVolume, duration) - { - // Find the primary sample whose frequency is nearest to the desired frequency. - let sample1 = 0 - let sample1Dist = Math.abs(this.samples[0].frequency - desiredFreq) - for (let i = 1; i < this.samples.length; i++) - { - const dist = Math.abs(this.samples[i].frequency - desiredFreq) - if (dist < sample1Dist) - { - sample1 = i - sample1Dist = dist - } - } - - // Find the sample whose frequency is second nearest to the desired frequency, - // unless the primary sample is already exactly a match. - // Then, calculate a cross-fade between the two. - // TODO: Probably should use an equal-power (logarithmic) cross-fade, - // but this seems good enough for now. - let sample2 = null - - let volume1 = 1 - let volume2 = 0 - - if (this.samples[sample1].frequency < desiredFreq) - { - if (sample1 + 1 < this.samples.length) - { - sample2 = sample1 + 1 - - const t = - (desiredFreq - this.samples[sample1].frequency) / - (this.samples[sample2].frequency - this.samples[sample1].frequency) - - volume1 = 1 - t - volume2 = t - } - } - else if (this.samples[sample1].frequency > desiredFreq) - { - if (sample1 - 1 >= 0) - { - sample2 = sample1 - 1 - - const t = - (desiredFreq - this.samples[sample2].frequency) / - (this.samples[sample1].frequency - this.samples[sample2].frequency) - - volume1 = t - volume2 = 1 - t - } - } - - // Play the samples. - const voices = [ this.playVoice(this.samples[sample1], desiredFreq, desiredVolume * volume1) ] - if (sample2 != null) - voices.push(this.playVoice(this.samples[sample2], desiredFreq, desiredVolume * volume2)) - - const data = - { - duration, - released: false, - voices - } - - return data - } - - - playVoice(sample, frequency, volume) - { - let sourceNode = this.synth.audioCtx.createBufferSource() - sourceNode.playbackRate.value = frequency / sample.frequency - sourceNode.buffer = sample.buffer - sourceNode.start(0) - - let envelopeNode = this.synth.audioCtx.createGain() - envelopeNode.gain.setValueAtTime(1, this.synth.audioCtx.currentTime) - - let volumeNode = this.synth.audioCtx.createGain() - volumeNode.gain.value = volume - - sourceNode.connect(envelopeNode) - envelopeNode.connect(volumeNode) - volumeNode.connect(this.synth.audioCtxOutput) - - return { source: sourceNode, envelope: envelopeNode, volume: volumeNode } - } - - - processNote(noteData, deltaTime) - { - noteData.duration -= deltaTime - - const releaseFalloffDuration = 0.1 - - if (noteData.duration <= 0 && !noteData.released) - { - noteData.released = true - for (let i = 0; i < noteData.voices.length; i++) - { - noteData.voices[i].envelope.gain.setValueAtTime(1, this.synth.audioCtx.currentTime) - noteData.voices[i].envelope.gain.linearRampToValueAtTime(0, this.synth.audioCtx.currentTime + releaseFalloffDuration) - } - } - - if (noteData.duration <= -releaseFalloffDuration * 2) - { - for (let i = 0; i < noteData.voices.length; i++) - noteData.voices[i].source.stop() - - return true - } - - return false - } - - - stopNote(noteData) - { - for (let i = 0; i < noteData.voices.length; i++) - noteData.voices[i].source.stop() - } -} \ No newline at end of file diff --git a/src_old/synth/synth.js b/src_old/synth/synth.js deleted file mode 100644 index 9861eb3..0000000 --- a/src_old/synth/synth.js +++ /dev/null @@ -1,111 +0,0 @@ -import { Instrument } from "./instrument.js" - - -export class Synth -{ - constructor() - { - this.audioCtx = new AudioContext() - this.time = 0 - this.noteEvents = [] - this.playingNotes = [] - - this.audioCtxOutput = this.audioCtx.createGain() - this.audioCtxOutput.connect(this.audioCtx.destination) - this.audioCtxOutput.gain.value = 0.5 - - const piano = new Instrument(this, - [ - [ 55.0, "audio/piano/a1.mp3"], - [ 110.0, "audio/piano/a2.mp3"], - [ 220.0, "audio/piano/a3.mp3"], - [ 440.0, "audio/piano/a4.mp3"], - [ 880.0, "audio/piano/a5.mp3"], - [1760.0, "audio/piano/a6.mp3"], - //[3520.0, "audio/piano/a7.mp3"] - ]) - - this.instruments = [piano, piano] - } - - - isFinished() - { - return this.noteEvents.length == 0 && this.playingNotes.length == 0 - } - - - play() - { - this.noteEvents.sort(function (a, b) { return a.time - b.time }) - } - - - stopAll() - { - this.time = 0 - this.noteEvents = [] - - for (let i = 0; i < this.playingNotes.length; i++) - this.playingNotes[i].stop() - - this.playingNotes = [] - } - - - process(deltaTime) - { - this.time += deltaTime - - // Process pending note events up to the current time. - let noteEventsProcessed = 0 - while (noteEventsProcessed < this.noteEvents.length && - this.noteEvents[noteEventsProcessed].time <= this.time) - { - const ev = this.noteEvents[noteEventsProcessed] - noteEventsProcessed++ - - let noteData = - this.instruments[ev.instrumentIndex].playNote(ev.frequency, ev.volume, ev.duration) - - noteData.process = (deltaTime) => - { - return this.instruments[ev.instrumentIndex].processNote(noteData, deltaTime) - } - - noteData.stop = () => - { - this.instruments[ev.instrumentIndex].stopNote(noteData) - } - - this.playingNotes.push(noteData) - //console.log("play note " + ev.frequency) - } - - // Remove processed events. - this.noteEvents.splice(0, noteEventsProcessed) - - // Update audio output. - for (let i = this.playingNotes.length - 1; i >= 0; i--) - { - if (this.playingNotes[i].process(deltaTime)) - this.playingNotes.splice(i, 1) - } - } - - - addNoteEvent(time, instrumentIndex, frequency, volume, duration) - { - if (!isFinite(frequency)) - return - - this.noteEvents.push( - { - time: time + this.time, - instrumentIndex, - frequency, - volume, - duration - }) - } -} \ No newline at end of file diff --git a/src_old/test.ts b/src_old/test.ts deleted file mode 100644 index 968af28..0000000 --- a/src_old/test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import ListOfPoints from "./util/listOfPoints" -import ListOfRanges from "./util/listOfRanges" -import { test as testTheory } from "./theory/test" - - -ListOfPoints.test() -ListOfRanges.test() -testTheory() \ No newline at end of file diff --git a/src_old/timeline/Element.tsx b/src_old/timeline/Element.tsx new file mode 100644 index 0000000..53b28b2 --- /dev/null +++ b/src_old/timeline/Element.tsx @@ -0,0 +1,393 @@ +import React from "react" +import * as Timeline from "./index" +import * as Project from "../project" +import * as Playback from "../playback" +import * as Prefs from "../prefs" +import * as Popup from "../popup" +import * as Dockable from "../dockable" +import * as UI from "../ui" +import { useRefState, RefState } from "../util/refState" +import Rect from "../util/rect" +import styled from "styled-components" + + +const StyledTrackButton = styled.button` + pointer-events: auto; + color: #fff; + border: 1px solid #888; + border-radius: 0.5em; + background-color: #2f3136; + padding: 0.1em 0.3em; + cursor: pointer; + + &:hover + { + border: 1px solid #fff; + } +` + + +export function TimelineElement(props: { state?: RefState }) +{ + const refDiv = React.useRef(null) + const refCanvas = React.useRef(null) + + const editorState = props.state ?? useRefState(() => Timeline.init()) + const dockableWindow = Dockable.useWindow() + + const lastTimelineRenderRef = React.useRef(0) + + const render = (force?: boolean) => + { + if (!refCanvas.current) + return + + const now = new Date().getTime() + if (!force && now < lastTimelineRenderRef.current + 15) + return + + //console.log("Timeline render") + lastTimelineRenderRef.current = now + + Timeline.render( + editorState.ref.current, + refCanvas.current.getContext("2d")!) + } + + const onResize = () => + { + if (!refDiv.current || !refCanvas.current) + return + + const pixelRatio = window.devicePixelRatio || 1 + + const rect = refDiv.current.getBoundingClientRect() + const x = Math.floor(rect.x) + const y = Math.floor(rect.y) + const w = Math.floor(rect.width * pixelRatio) + const h = Math.floor(rect.height * pixelRatio) + + refCanvas.current.style.width = Math.floor(rect.width) + "px" + refCanvas.current.style.height = Math.floor(rect.height) + "px" + refCanvas.current.width = w + refCanvas.current.height = h + + const renderRect = new Rect(x, y, w, h) + + Timeline.resize(editorState.ref.current, pixelRatio, renderRect) + render(true) + } + + React.useLayoutEffect(() => + { + if (!refDiv.current) + return + + const observer = new ResizeObserver(entries => + { + onResize() + }) + + const elem = refDiv.current + observer.observe(elem) + + onResize() + return () => observer.unobserve(elem) + + }, [refDiv.current]) + + React.useEffect(() => + { + Timeline.scrollPlaybackTimeIntoView(editorState.ref.current) + render(!Playback.global.playing) + + }, [Playback.globalObservable.updateToken]) + + React.useEffect(() => + { + Timeline.refreshTracks(editorState.ref.current) + render(true) + + }, [Project.global.project.tracks]) + + React.useEffect(() => + { + const refCanvasCurrent = refCanvas.current + if (!refCanvasCurrent) + return + + const transformMousePos = (canvas: HTMLCanvasElement, ev: MouseEvent) => + { + const rect = canvas.getBoundingClientRect() + return { + x: (ev.clientX - rect.left) * editorState.ref.current.pixelRatio, + y: (ev.clientY - rect.top) * editorState.ref.current.pixelRatio, + } + } + + const preventDefault = (ev: Event) => ev.preventDefault() + + const setCursor = (state: Timeline.State) => + { + let cursor = "text" + const mouseAction = + state.mouse.down ? state.mouse.action : + state.hoverControl != Timeline.TrackControl.None ? Timeline.MouseAction.DragTrackControl : + state.hover ? state.hover.action : + Timeline.MouseAction.None + + if (state.tracks.some((tr: any) => !!tr.pencil) || + mouseAction == Timeline.MouseAction.Pencil) + cursor = "crosshair" + else if (mouseAction == Timeline.MouseAction.DragTrackControl) + cursor = "crosshair" + else if (mouseAction == Timeline.MouseAction.DragClone) + cursor = "crosshair" + else if (mouseAction == Timeline.MouseAction.DragTime || + mouseAction == Timeline.MouseAction.DragTimeAndRow || + mouseAction == Timeline.MouseAction.DragRow || + mouseAction == Timeline.MouseAction.DragTrackHeader) + cursor = (state.mouse.down ? "grabbing" : "grab") + else if (mouseAction == Timeline.MouseAction.Pan) + cursor = "move" + else if (mouseAction == Timeline.MouseAction.StretchTimeStart || + mouseAction == Timeline.MouseAction.StretchTimeEnd) + cursor = "col-resize" + + refCanvasCurrent.style.cursor = cursor + } + + const onMouseMove = (ev: MouseEvent) => + { + const state = editorState.ref.current + if (state.mouse.down) + ev.preventDefault() + + const pos = transformMousePos(refCanvasCurrent, ev) + const projectBefore = Project.global.project + const needsRender1 = Timeline.mouseMove(state, pos) + const needsRender2 = Timeline.mouseDrag(state, pos, false) + + if (projectBefore !== Project.global.project) + Project.notifyObservers() + + if (needsRender1 || needsRender2) + render(true) + + setCursor(state) + } + + const onMouseDown = (ev: MouseEvent) => + { + if (document.activeElement instanceof HTMLElement) + document.activeElement.blur() + + ev.preventDefault() + + Dockable.removeEphemerals(Dockable.global.state) + Dockable.notifyObservers() + + const state = editorState.ref.current + const pos = transformMousePos(refCanvasCurrent, ev) + const projectBefore = Project.global.project + Timeline.mouseMove(state, pos) + Timeline.mouseDown(state, ev.button != 0) + Timeline.mouseDrag(state, pos, true) + + if (projectBefore !== Project.global.project) + Project.notifyObservers() + + render() + setCursor(state) + editorState.commit() + } + + const onMouseUp = (ev: MouseEvent) => + { + const state = editorState.ref.current + if (state.mouse.down) + ev.preventDefault() + + const pos = transformMousePos(refCanvasCurrent, ev) + const projectBefore = Project.global.project + Timeline.mouseUp(state) + + if (projectBefore !== Project.global.project) + { + Project.notifyObservers() + window.dispatchEvent(new Event("timelineRefresh")) + } + + render() + setCursor(state) + editorState.commit() + } + + const onMouseWheel = (ev: WheelEvent) => + { + Timeline.mouseWheel(editorState.ref.current, ev.deltaX, ev.deltaY) + render() + } + + const onKeyDown = (ev: KeyboardEvent) => + { + const isActiveWindow = + Dockable.global.state.activePanel === dockableWindow.panel && + (!document.activeElement || document.activeElement.tagName != "INPUT") + + const projectBefore = Project.global.project + Timeline.keyDown(editorState.ref.current, isActiveWindow, ev.key.toLowerCase()) + + if (projectBefore !== Project.global.project) + Project.notifyObservers() + + render() + editorState.commit() + } + + const onKeyUp = (ev: KeyboardEvent) => + { + Timeline.keyUp(editorState.ref.current, ev.key.toLowerCase()) + } + + const onRewind = (ev: Event) => + { + Timeline.rewind(editorState.ref.current) + editorState.commit() + render(true) + } + + const onRefresh = (ev: Event) => + { + Timeline.refreshTracks(editorState.ref.current) + editorState.commit() + render(true) + } + + const onReset = (ev: Event) => + { + const state = editorState.ref.current + Timeline.modeStackPop(state, 0) + Timeline.reset(state) + Timeline.rewind(state) + Timeline.refreshTracks(state) + editorState.commit() + render(true) + } + + refCanvasCurrent.addEventListener("mousedown", onMouseDown) + refCanvasCurrent.addEventListener("wheel", onMouseWheel) + refCanvasCurrent.addEventListener("contextmenu", preventDefault) + + window.addEventListener("mousemove", onMouseMove) + window.addEventListener("mouseup", onMouseUp) + window.addEventListener("keydown", onKeyDown) + window.addEventListener("keyup", onKeyUp) + + window.addEventListener("timelineRewind", onRewind) + window.addEventListener("timelineRefresh", onRefresh) + window.addEventListener("timelineReset", onReset) + + return () => + { + refCanvasCurrent.removeEventListener("mousedown", onMouseDown) + refCanvasCurrent.removeEventListener("wheel", onMouseWheel) + refCanvasCurrent.removeEventListener("contextmenu", preventDefault) + + window.removeEventListener("mousemove", onMouseMove) + window.removeEventListener("mouseup", onMouseUp) + window.removeEventListener("keydown", onKeyDown) + window.removeEventListener("keyup", onKeyUp) + + window.removeEventListener("timelineRewind", onRewind) + window.removeEventListener("timelineRefresh", onRefresh) + window.removeEventListener("timelineReset", onReset) + } + + }, [refCanvas.current]) + + + const yTrackEnd = + editorState.ref.current.tracks.length == 0 ? + 0 : + editorState.ref.current.tracks[editorState.ref.current.tracks.length - 1].renderRect.y2 + + const onAddTrack = () => + { + let proj = Project.global.project + proj = Project.upsertTrack(proj, Project.makeTrackNotes()) + Project.global.project = proj + Project.splitUndoPoint() + Project.addUndoPoint("addTrack") + Project.notifyObservers() + + window.dispatchEvent(new Event("timelineRefresh")) + } + + const onTrackSettings = (ev: React.MouseEvent, trackIndex: number) => + { + Popup.global.elem = () => + { + return + + + } + Popup.global.rect = Rect.fromElement(ev.target as HTMLElement) + Popup.notifyObservers() + } + + const pixelRatio = window.devicePixelRatio || 1 + + return React.useMemo(() => +
+ + +
+ + +{/*➕*/} + +
+
+ , [ + Project.global.project.tracks, + editorState.ref.current.tracks, + editorState.ref.current.trackScroll, + ]) +} + + +export function sendEventRefresh() +{ + window.dispatchEvent(new Event("timelineRefresh")) +} + + +export function sendEventReset() +{ + window.dispatchEvent(new Event("timelineReset")) +} \ No newline at end of file diff --git a/src_old/timeline/index.ts b/src_old/timeline/index.ts new file mode 100644 index 0000000..924bf5f --- /dev/null +++ b/src_old/timeline/index.ts @@ -0,0 +1,18 @@ +export * from "./state" +export * from "./state_keyDown" +export * from "./state_keyUp" +export * from "./state_mouseMove" +export * from "./state_mouseDown" +export * from "./state_mouseUp" +export * from "./state_mouseDrag" +export * from "./state_mouseWheel" +export * from "./state_render" +export * from "./track" +export * from "./trackKeyChanges" +export * from "./trackMeterChanges" +export * from "./trackNoteBlocks" +export * from "./trackChords" +export * from "./trackNotes" +export * from "./trackNoteVolumes" +export * from "./trackNoteVelocities" +export * from "./Element" \ No newline at end of file diff --git a/src/timeline/state.ts b/src_old/timeline/state.ts similarity index 100% rename from src/timeline/state.ts rename to src_old/timeline/state.ts diff --git a/src/timeline/state_keyDown.ts b/src_old/timeline/state_keyDown.ts similarity index 100% rename from src/timeline/state_keyDown.ts rename to src_old/timeline/state_keyDown.ts diff --git a/src/timeline/state_keyUp.ts b/src_old/timeline/state_keyUp.ts similarity index 100% rename from src/timeline/state_keyUp.ts rename to src_old/timeline/state_keyUp.ts diff --git a/src/timeline/state_mouseDown.ts b/src_old/timeline/state_mouseDown.ts similarity index 100% rename from src/timeline/state_mouseDown.ts rename to src_old/timeline/state_mouseDown.ts diff --git a/src/timeline/state_mouseDrag.ts b/src_old/timeline/state_mouseDrag.ts similarity index 100% rename from src/timeline/state_mouseDrag.ts rename to src_old/timeline/state_mouseDrag.ts diff --git a/src/timeline/state_mouseMove.ts b/src_old/timeline/state_mouseMove.ts similarity index 100% rename from src/timeline/state_mouseMove.ts rename to src_old/timeline/state_mouseMove.ts diff --git a/src/timeline/state_mouseUp.tsx b/src_old/timeline/state_mouseUp.tsx similarity index 100% rename from src/timeline/state_mouseUp.tsx rename to src_old/timeline/state_mouseUp.tsx diff --git a/src/timeline/state_mouseWheel.ts b/src_old/timeline/state_mouseWheel.ts similarity index 100% rename from src/timeline/state_mouseWheel.ts rename to src_old/timeline/state_mouseWheel.ts diff --git a/src/timeline/state_render.ts b/src_old/timeline/state_render.ts similarity index 100% rename from src/timeline/state_render.ts rename to src_old/timeline/state_render.ts diff --git a/src/timeline/track.tsx b/src_old/timeline/track.tsx similarity index 100% rename from src/timeline/track.tsx rename to src_old/timeline/track.tsx diff --git a/src/timeline/trackChords.tsx b/src_old/timeline/trackChords.tsx similarity index 100% rename from src/timeline/trackChords.tsx rename to src_old/timeline/trackChords.tsx diff --git a/src/timeline/trackKeyChanges.tsx b/src_old/timeline/trackKeyChanges.tsx similarity index 100% rename from src/timeline/trackKeyChanges.tsx rename to src_old/timeline/trackKeyChanges.tsx diff --git a/src/timeline/trackMeterChanges.tsx b/src_old/timeline/trackMeterChanges.tsx similarity index 100% rename from src/timeline/trackMeterChanges.tsx rename to src_old/timeline/trackMeterChanges.tsx diff --git a/src/timeline/trackNoteBlocks.tsx b/src_old/timeline/trackNoteBlocks.tsx similarity index 100% rename from src/timeline/trackNoteBlocks.tsx rename to src_old/timeline/trackNoteBlocks.tsx diff --git a/src/timeline/trackNoteVelocities.tsx b/src_old/timeline/trackNoteVelocities.tsx similarity index 100% rename from src/timeline/trackNoteVelocities.tsx rename to src_old/timeline/trackNoteVelocities.tsx diff --git a/src/timeline/trackNoteVolumes.tsx b/src_old/timeline/trackNoteVolumes.tsx similarity index 100% rename from src/timeline/trackNoteVolumes.tsx rename to src_old/timeline/trackNoteVolumes.tsx diff --git a/src/timeline/trackNotes.tsx b/src_old/timeline/trackNotes.tsx similarity index 100% rename from src/timeline/trackNotes.tsx rename to src_old/timeline/trackNotes.tsx diff --git a/src_old/toolbox/App.js b/src_old/toolbox/App.js deleted file mode 100644 index 8d2ba0e..0000000 --- a/src_old/toolbox/App.js +++ /dev/null @@ -1,256 +0,0 @@ -import React from "react" -import Editor from "../editor/editor.js" -import Project from "../project/project.js" -import { usePlaybackController } from "./PlaybackController.js" -import ToolboxPlayback from "./ToolboxPlayback.js" -import ToolboxFile from "./ToolboxFile.js" -import ToolboxEdit from "./ToolboxEdit.js" -import ToolboxInput from "./ToolboxInput.js" -import Ribbon from "./Ribbon.js" - - -function EditorComponent(props) -{ - const refCanvas = React.useRef() - const needsResetView = React.useRef(true) - - const transformMousePos = (canvas, ev) => - { - const rect = canvas.getBoundingClientRect() - return { - x: (ev.clientX - rect.left), - y: (ev.clientY - rect.top) - } - } - - React.useEffect(() => - { - const preventDefault = (ev) => ev.preventDefault() - - const onResize = (ev) => - { - const rect = refCanvas.current.getBoundingClientRect() - refCanvas.current.width = rect.width - refCanvas.current.height = rect.height - - props.dispatch({ - type: "resize", - w: rect.width, - h: rect.height, - }) - - if (needsResetView.current) - { - needsResetView.current = false - props.dispatch({ type: "rewind" }) - } - } - - const onMouseMove = (ev) => - { - const p = transformMousePos(refCanvas.current, ev) - props.dispatch({ type: "mouseMove", ...p }) - } - - const onMouseDown = (ev) => - { - if (window.document.activeElement) - window.document.activeElement.blur() - - ev.preventDefault() - const p = transformMousePos(refCanvas.current, ev) - props.dispatch({ type: "mouseMove", ...p }) - props.dispatch({ type: "mouseDown", rightButton: ev.button != 0, ctrlKey: ev.ctrlKey }) - } - - const onMouseUp = (ev) => - { - const p = transformMousePos(refCanvas.current, ev) - props.dispatch({ type: "mouseMove", ...p }) - props.dispatch({ type: "mouseUp" }) - props.dispatch({ type: "mouseMove", ...p }) - } - - const onMouseWheel = (ev) => - { - ev.preventDefault() - props.dispatch({ type: "mouseWheel", deltaX: ev.deltaX, deltaY: ev.deltaY }) - } - - const onKeyDown = (ev) => - { - props.dispatch({ type: "keyDown", key: ev.key.toLowerCase() }) - props.dispatch({ - type: "keyCommand", - ev, - key: ev.key.toLowerCase(), - ctrlKey: ev.ctrlKey, - shiftKey: ev.shiftKey, - }) - } - - const onKeyUp = (ev) => - { - props.dispatch({ type: "keyUp", key: ev.key.toLowerCase() }) - } - - onResize() - - window.addEventListener("resize", onResize) - window.addEventListener("mousemove", onMouseMove) - window.addEventListener("mouseup", onMouseUp) - window.addEventListener("keydown", onKeyDown) - window.addEventListener("keyup", onKeyUp) - - refCanvas.current.addEventListener("mousedown", onMouseDown) - refCanvas.current.addEventListener("wheel", onMouseWheel) - refCanvas.current.addEventListener("mouseup", preventDefault) - refCanvas.current.addEventListener("contextmenu", preventDefault) - - return () => - { - window.removeEventListener("resize", onResize) - window.removeEventListener("mousemove", onMouseMove) - window.removeEventListener("mouseup", onMouseUp) - window.removeEventListener("keydown", onKeyDown) - window.removeEventListener("keyup", onKeyUp) - - refCanvas.current.removeEventListener("mousedown", onMouseDown) - refCanvas.current.removeEventListener("wheel", onMouseWheel) - refCanvas.current.removeEventListener("mouseup", preventDefault) - refCanvas.current.removeEventListener("contextmenu", preventDefault) - } - - }, []) - - React.useEffect(() => - { - Editor.render(props.state, refCanvas.current.getContext("2d")) - - const mouseAction = props.state.mouse.action || (props.state.mouse.hover && props.state.mouse.hover.action) - - if (props.state.mouse.draw || mouseAction & (Editor.actionDraw)) - refCanvas.current.style.cursor = "crosshair" - else if (mouseAction & (Editor.actionDragTime)) - refCanvas.current.style.cursor = (props.state.mouse.down ? "grabbing" : "grab") - else if (mouseAction & (Editor.actionPan)) - refCanvas.current.style.cursor = "move" - else if (mouseAction & (Editor.actionStretchTimeStart | Editor.actionStretchTimeEnd)) - refCanvas.current.style.cursor = "col-resize" - else - refCanvas.current.style.cursor = "text" - - }, [props.state]) - - return ( -
- -
- ) -} - - -export default function App(props) -{ - const initEditor = (state) => - { - state = Editor.reduce(state, { type: "init", project: Project.getDefault() }) - state = Editor.reduce(state, { type: "trackAdd", kind: "markers" }) - state = Editor.reduce(state, { type: "trackAdd", kind: "chords" }) - state = Editor.reduce(state, { type: "trackAdd", kind: "notes" }) - state = Editor.reduce(state, { type: "clearUndoStack" }) - - const urlData = - getQueryParam(window.location.search, "data") || - getQueryParam(window.location.search, "song") - - if (urlData) - { - try - { - state = Editor.reduce(state, { type: "projectLoad", project: Project.fromCompressedStr(urlData) }) - } - catch (e) - { - window.alert("An error occurred loading the project from the URL.\n\n" + e.toString()) - console.error(e) - } - } - - return state - } - - const [state, dispatch] = React.useReducer(Editor.reduce, {}, initEditor) - - const playbackController = usePlaybackController(state, dispatch, props.synth) - - return ( -
-
- - { ToolboxPlayback({ state, dispatch, playbackController }) } - - - - { ToolboxFile({ state, dispatch }) } - { ToolboxEdit({ state, dispatch }) } - { ToolboxInput({ state, dispatch }) } - - - {/* - - */} -
- - -
- ) -} - - -function getQueryParam(url, name) -{ - name = name.replace(/[\[\]]/g, "\\$&") - - const regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)") - const results = regex.exec(url) - - if (!results) - return null - - if (!results[2]) - return "" - - return decodeURIComponent(results[2].replace(/\+/g, " ")) -} \ No newline at end of file diff --git a/src_old/toolbox/ButtonList.tsx b/src_old/toolbox/ButtonList.tsx deleted file mode 100644 index c3952e3..0000000 --- a/src_old/toolbox/ButtonList.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React from "react" - - -interface ButtonListProps -{ - column?: boolean - multiple?: boolean - selected: any - - items: - { - label: any - value: any - bkgColor?: string - width?: string - }[] - - onChange: (item: any, index: number) => void -} - - -export default function ButtonList(props: ButtonListProps) -{ - const isSelected = (value: any) => - { - if (props.multiple && Array.isArray(props.selected)) - return props.selected.some(v => v == value) - else - return props.selected == value - } - - - return
- - { props.items.map((item, i) => - - )} - -
-} \ No newline at end of file diff --git a/src_old/toolbox/DropdownMenu.tsx b/src_old/toolbox/DropdownMenu.tsx deleted file mode 100644 index a4ae761..0000000 --- a/src_old/toolbox/DropdownMenu.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from "react" - - -interface DropdownMenuProps -{ - selected: any - - items: - { - label: any - value: any - }[] - - onChange: (item: any, index: number) => void - - style?: any -} - - -export default function DropdownMenu(props: DropdownMenuProps) -{ - //const selectedIndex = props.items.findIndex(i => i.value == props.selected) - - - return -} \ No newline at end of file diff --git a/src_old/toolbox/ListBox.tsx b/src_old/toolbox/ListBox.tsx deleted file mode 100644 index e95794a..0000000 --- a/src_old/toolbox/ListBox.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React from "react" - - -interface ListBoxProps -{ - selected: any - - items: - { - label: any - value: any - }[] - - onChange: (item: any, index: number) => void - - style?: any -} - - -export default function ListBox(props: ListBoxProps) -{ - //const selectedIndex = props.items.findIndex(i => i.value == props.selected) - - - return
-
- - { props.items.map((item, i) => - - )} - -
-
-} \ No newline at end of file diff --git a/src_old/toolbox/PlaybackController.js b/src_old/toolbox/PlaybackController.js deleted file mode 100644 index 68cd238..0000000 --- a/src_old/toolbox/PlaybackController.js +++ /dev/null @@ -1,129 +0,0 @@ -import React from "react" -import PlaybackSynth from "../project/playbackSynth.js" -import Rational from "../util/rational.js" -import MathUtils from "../util/math.js" - - -export function usePlaybackController(state, dispatch, synth) -{ - const stateRef = React.useRef(state) - stateRef.current = state - - const playbackPrevStart = React.useRef(null) - const playbackPrevTimestamp = React.useRef(-1) - const playbackInterval = React.useRef(null) - - const sampleInterval = React.useRef(null) - const samplePrevTimestamp = React.useRef(null) - - function cancelPlaybackInterval() - { - if (playbackInterval.current) - { - window.cancelAnimationFrame(playbackInterval.current) - playbackInterval.current = null - } - } - - function cancelSampleInterval() - { - if (sampleInterval.current) - { - window.cancelAnimationFrame(sampleInterval.current) - sampleInterval.current = null - } - } - - function playbackStep(timestamp) - { - const deltaTime = (playbackPrevTimestamp.current < 0 ? 0 : timestamp - playbackPrevTimestamp.current) - playbackPrevTimestamp.current = timestamp - - if (deltaTime > 0 && deltaTime < 250) - { - const measuresPerSecond = (stateRef.current.project.baseBpm / 4 / 60) - - synth.process(deltaTime / 1000) - const timeAsFloat = stateRef.current.playback.timeAsFloat + deltaTime / 1000 * measuresPerSecond - dispatch({ type: "playbackStep", timeAsFloat }) - } - - if (stateRef.current.playback.time.compare(stateRef.current.project.range.end.add(new Rational(1, 4))) > 0) - dispatch({ type: "playbackSet", playing: false }) - - if (stateRef.current.playback.playing) - playbackInterval.current = window.requestAnimationFrame(playbackStep) - } - - function playbackSet(playing) - { - const time = state.cursor.time1.min(state.cursor.time2) - dispatch({ type: "playbackSet", playing, time }) - } - - function sampleStep(timestamp) - { - const deltaTime = (samplePrevTimestamp.current < 0 ? 0 : timestamp - samplePrevTimestamp.current) - samplePrevTimestamp.current = timestamp - - if (deltaTime > 0 && deltaTime < 250) - synth.process(deltaTime / 1000) - - if (!synth.isFinished()) - sampleInterval.current = window.requestAnimationFrame(sampleStep) - } - - if (state.playback.playing) - { - if (!playbackPrevStart.current || state.playback.startTime.compare(playbackPrevStart.current) != 0) - { - cancelSampleInterval() - cancelPlaybackInterval() - synth.stopAll() - - PlaybackSynth.feedToSynth(state.project, synth, state.playback.startTime) - synth.play() - - playbackPrevStart.current = state.playback.startTime - playbackPrevTimestamp.current = -1 - playbackInterval.current = window.requestAnimationFrame(playbackStep) - } - } - else - { - if (playbackInterval.current) - { - cancelPlaybackInterval() - synth.stopAll() - playbackPrevStart.current = null - } - } - - if (state.soundPreview) - { - cancelSampleInterval() - synth.stopAll() - - if (state.soundPreview.kind == "note") - synth.addNoteEvent(0, 0, MathUtils.midiToHertz(state.soundPreview.pitch), 1, 0.5) - else if (state.soundPreview.kind == "chord") - { - for (const pitch of state.soundPreview.chord.strummingPitches) - synth.addNoteEvent(0, 0, MathUtils.midiToHertz(pitch), 1, 0.75) - } - - synth.play() - samplePrevTimestamp.current = -1 - sampleInterval.current = window.requestAnimationFrame(sampleStep) - dispatch({ type: "clearSoundPreview" }) - } - - const togglePlaying = () => - { - playbackSet(!state.playback.playing) - } - - return { - togglePlaying, - } -} \ No newline at end of file diff --git a/src_old/toolbox/Ribbon.js b/src_old/toolbox/Ribbon.js deleted file mode 100644 index 5c77e91..0000000 --- a/src_old/toolbox/Ribbon.js +++ /dev/null @@ -1,400 +0,0 @@ -import React from "react" - - -function Tab(props) -{ - return null -} - - -function FixedTab(props) -{ - return null -} - - -function Group(props) -{ - return null -} - - -function CustomGroup(props) -{ - return null -} - - -function TallBox(props) -{ - return null -} - - -function SlotLayout(props) -{ - if (props.tall) - { - const iconSize = (typeof props.icon === "string" ? "3em" : undefined) - - return <> -
-
{ props.icon }
-
{ props.label }
-
- - } - else - { - const iconSlotWidth = (props.icon ? "auto" : "0") - const sepSlotWidth = (props.icon ? "0.25em" : "0") - const iconSize = (typeof props.icon === "string" ? "1.15em" : undefined) - - return <> -
-
{ props.icon }
-
{ props.label }
-
- - } -} - - -function Slot(props) -{ - const baseStyle = - { - borderRadius: "0.5em", - boxSizing: "border-box", - } - - const className = - (props.supressClass ? "" : "ribbonSlot") + " " + - (props.selected ? "ribbonButtonSelected" : "") - - if (props.tall) - { - return <> -
- { props.children } -
- - } - else - { - return <> -
- { props.children } -
- - } -} - - -function Button(props) -{ - const className = - "ribbonButton " + - (props.selected ? "ribbonButtonSelected" : "") - - return <> - - -} - - -function SlotButton(props) -{ - return <> - - - - -} - - -function SlotRadioGroup(props) -{ - return <> - { props.options.map(option => - props.onChange(option.value) } - style={{ - height: "100%", - padding: "0.25em 0.5em", - margin: "0 0.125em", - }} - label={ option.render } - /> - )} - -} - - -function InlineRadioGroup(props) -{ - return <> - { props.options.map(option => - - )} - -} - - -function Input(props) -{ - return ev.stopPropagation() } - style={{ - gridRow: 1, - gridColumn: 1, - width: "4em", - border: 0, - fontFamily: "inherit", - textAlign: "left", - padding: "0.25em", - borderRadius: "0.25em", - ...props.style, - }}/> -} - - -function Select(props) -{ - return -} - - -function getChildren(children) -{ - if (!children) - children = [] - - else if (!Array.isArray(children)) - children = [children] - - return children.filter(c => !!c) -} - - -function flattenChildrenOfType(children, type) -{ - const res = [] - - for (const c of getChildren(children)) - { - if (c.type === type) - res.push(c) - else if (c.props && c.props.children) - { - for (const c2 of flattenChildrenOfType(c.props.children, type)) - res.push(c2) - } - } - - return res -} - - -function Toolbar(props) -{ - const [curTab, setCurTab] = React.useState(0) - - //console.log(props.children) - const tabs = flattenChildrenOfType(props.children, Tab) - const fixedTab = flattenChildrenOfType(props.children, FixedTab) - const groups = flattenChildrenOfType(tabs[curTab].props.children, Group) - const fixedGroups = []//fixedTab.length == 0 ? [] : flattenChildrenOfType(fixedTab[0].props.children, Group) - - return <> -
-
- { tabs.map((tab, i) => - - )} -
- -
- { [...fixedGroups, ...groups].map((group, i) => - -
-
- { group.props.children } -
-
-
- { group.props.label } -
-
- )} -
-
- -} - - -export default -{ - Toolbar, - Tab, - FixedTab, - Group, - TallBox, - Slot, - SlotLayout, - Button, - SlotButton, - InlineRadioGroup, - SlotRadioGroup, - Input, - Select, -} \ No newline at end of file diff --git a/src_old/toolbox/ToolboxChord.js b/src_old/toolbox/ToolboxChord.js deleted file mode 100644 index eaa88c0..0000000 --- a/src_old/toolbox/ToolboxChord.js +++ /dev/null @@ -1,178 +0,0 @@ -import React from "react" -import Editor from "../editor/editor.js" -import CanvasUtils from "../util/canvas.js" -import Theory from "../theory.ts" -import Ribbon from "./Ribbon.js" - - -function ChordButton(props) -{ - const refCanvas = React.useRef(null) - - const w = 60 - const h = 54 - - const key = props.theoryKey - const chord = props.chord - - React.useEffect(() => - { - const ctx = refCanvas.current.getContext("2d") - CanvasUtils.drawChord(ctx, 0, 0, w, h, chord, key) - - }, [props.theoryKey, props.chord]) - - const onClick = () => - { - const time = Editor.insertionTime(props.state) - props.dispatch({ type: "insertChord", chord, time }) - } - - return } - label="" - /> -} - - -function KindDropdown(props) -{ - return props.onChange(ev.target.value) } - style={{ height:"2em" }} - > - - { Theory.Chord.kinds.map((chord, index) => - - { chord.startGroup ? : null } - - - )} - - -} - - -export default function ToolboxChord(props) -{ - const state = props.state - const dispatch = props.dispatch - const [kindGroup, setKindGroup] = React.useState("inkey") - const [inKeyType, setInKeyType] = React.useState(5) - const [kindCustomId, setKindCustomId] = React.useState("M") - const [accidental, setAccidental] = React.useState(0) - - const time = Editor.insertionTime(props.state) - const cursorKeyCh = state.project.keyChanges.findActiveAt(time) - const key = cursorKeyCh ? cursorKeyCh.key : Editor.defaultKey() - - let title = null - let chordButtons = null - switch (kindGroup) - { - case "inkey": - switch (inKeyType) - { - case 5: title = "Triads in " + key.str; break - case 7: title = "Seventh chords in " + key.str; break - case 9: title = "Ninth chords in " + key.str; break - case 11: title = "Eleventh chords in " + key.str; break - case 13: title = "Thirteenth chords in " + key.str; break - } - - chordButtons = [0, 1, 2, 3, 4, 5, 6].map(degree => - { - const root = key.midiForDegree(degree) - - let pitches = [0] - pitches.push(key.midiForDegree(degree + 2) - root) - pitches.push(key.midiForDegree(degree + 4) - root) - - if (inKeyType >= 7) - pitches.push(key.midiForDegree(degree + 6) - root) - - if (inKeyType >= 9) - pitches.push(key.midiForDegree(degree + 8) - root) - - if (inKeyType >= 11) - pitches.push(key.midiForDegree(degree + 10) - root) - - if (inKeyType >= 13) - pitches.push(key.midiForDegree(degree + 12) - root) - - const kind = Theory.Chord.kindFromPitches(pitches) - const chord = new Theory.Chord(root, accidental, kind, 0, []) - - return - }) - break - - case "custom": - title = Theory.Chord.kinds[Theory.Chord.kindFromId(kindCustomId)].name + " chords" - chordButtons = [0, 1, 2, 3, 4, 5, 6].map(degree => { - const kind = Theory.Chord.kindFromId(kindCustomId) - const root = key.midiForDegree(degree) - const chord = new Theory.Chord(root, accidental, kind, 0, []) - - return - }) - break - } - - return <> - - { chordButtons } - - - - setKindGroup("inkey") }> - In-Key } - label={ - } - /> - - - setKindGroup("custom") } - > - Other } - label={ } - /> - - - - - - - - -} \ No newline at end of file diff --git a/src_old/toolbox/ToolboxEdit.js b/src_old/toolbox/ToolboxEdit.js deleted file mode 100644 index dd2f9b7..0000000 --- a/src_old/toolbox/ToolboxEdit.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from "react" -import Ribbon from "./Ribbon.js" -import Editor from "../editor/editor.js" - - -export default function ToolboxEdit(props) -{ - return - - - props.dispatch({ type: "undo" })} - /> - props.dispatch({ type: "redo" })} - /> - - - - props.dispatch({ type: "paste" })} - /> - props.dispatch({ type: "copy" })} - /> - props.dispatch({ type: "cut" })} - /> - - - -} \ No newline at end of file diff --git a/src_old/toolbox/ToolboxFile.js b/src_old/toolbox/ToolboxFile.js deleted file mode 100644 index fe1b4cb..0000000 --- a/src_old/toolbox/ToolboxFile.js +++ /dev/null @@ -1,180 +0,0 @@ -import React from "react" -import Ribbon from "./Ribbon.js" -import Project from "../project/project.js" - - -function loadFile(dispatch, elem) -{ - if (elem.files.length != 1) - return - - let reader = new FileReader() - reader.readAsArrayBuffer(elem.files[0]) - reader.onload = () => - { - const bytes = new Uint8Array(reader.result) - if (bytes[0] == "M".charCodeAt(0) && - bytes[1] == "T".charCodeAt(0) && - bytes[2] == "h".charCodeAt(0) && - bytes[3] == "d".charCodeAt(0)) - loadFileMidi(dispatch, elem) - else - loadFileJson(dispatch, elem) - } -} - - -function loadFileJson(dispatch, elem) -{ - if (elem.files.length != 1) - return - - let reader = new FileReader() - reader.readAsText(elem.files[0]) - reader.onload = () => - { - const json = JSON.parse(reader.result) - dispatch({ type: "projectLoad", project: Project.fromJson(json) }) - } -} - - -function loadFileMidi(dispatch, elem) -{ - if (elem.files.length != 1) - return - - let reader = new FileReader() - reader.readAsArrayBuffer(elem.files[0]) - reader.onload = () => - { - const bytes = new Uint8Array(reader.result) - dispatch({ type: "projectLoad", project: Project.fromMidi(bytes) }) - } -} - - -function loadJson(dispatch) -{ - const json = window.prompt("Paste JSON song data:", "") - if (json) - dispatch({ type: "projectLoad", project: Project.fromJson(JSON.parse(json)) }) -} - - -function saveJson(project) -{ - const json = project.toJson() - const newWindow = window.open() - newWindow.document.write("") - newWindow.document.write(json) - newWindow.document.write("") -} - - -function saveAndSetUrl(project) -{ - const str = project.toCompressedStr() - window.location = location.protocol + "//" + location.host + location.pathname + "?data=" + str -} - - -export default function ToolboxFile(props) -{ - const state = props.state - - const inputFileRef = React.useRef(null) - const performInputFileClick = () => inputFileRef.current.click() - - const newProject = () => - { - props.dispatch({ type: "projectSet", project: Project.getDefault() }) - props.dispatch({ type: "rewind" }) - } - - const examples = - [ - "mozartk453", - "letitgo", - "rollercoaster", - "adventure", - "isaac", - "dontstarve", - "chronotrigger", - "jimmyneutron", - "whensomebodylovedme", - ] - - const loadExample = (filename) => - { - if (filename == "") - return - - fetch("examples/" + filename + ".json") - .then(res => res.json()) - .then(json => - { - props.dispatch({ type: "projectLoad", project: Project.fromJson(json) }) - }) - } - - return - - - - - - - saveAndSetUrl(state.project) } - /> - - - - saveJson(state.project) } - /> - loadJson(props.dispatch) } - /> - - loadFile(props.dispatch, ev.target) } - style={{ display:"none", width:"1em" }} - /> - - - - - - loadExample(ev.target.value) }> - - { examples.map(ex => ) } - - } - /> - - - - -} \ No newline at end of file diff --git a/src_old/toolbox/ToolboxInput.js b/src_old/toolbox/ToolboxInput.js deleted file mode 100644 index 34afe71..0000000 --- a/src_old/toolbox/ToolboxInput.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react" -import Editor from "../editor/editor.js" -import Ribbon from "./Ribbon.js" -import ToolboxNote from "./ToolboxNote.js" -import ToolboxChord from "./ToolboxChord.js" -import ToolboxMarkers from "./ToolboxMarkers.js" - - -export default function ToolboxInput(props) -{ - const state = props.state - const dispatch = props.dispatch - - const track = Editor.insertionTrack(state) - const trackKind = state.tracks[track].kind - - const toolboxNote = ToolboxNote({ state, dispatch }) - const toolboxChord = ToolboxChord({ state, dispatch }) - const toolboxMarkers = ToolboxMarkers({ state, dispatch }) - - return - { trackKind != "notes" ? null : toolboxNote } - { trackKind != "chords" ? null : toolboxChord } - { trackKind != "markers" ? null : toolboxMarkers } - -} \ No newline at end of file diff --git a/src_old/toolbox/ToolboxMarkers.js b/src_old/toolbox/ToolboxMarkers.js deleted file mode 100644 index 1a530c8..0000000 --- a/src_old/toolbox/ToolboxMarkers.js +++ /dev/null @@ -1,170 +0,0 @@ -import React from "react" -import Editor from "../editor/editor.js" -import Theory from "../theory.ts" -import Ribbon from "./Ribbon.js" - - -function KeyChangeToolbox(props) -{ - const state = props.state - const dispatch = props.dispatch - - const time = Editor.insertionTime(props.state) - const cursorKeyCh = state.project.keyChanges.findActiveAt(time) - const key = cursorKeyCh ? cursorKeyCh.key : Editor.defaultKey() - - const accidentalNames = ["♭♭", "♭", "♮", "♯", "♯♯"] - - const setTonicLetter = (letter) => - { - if (!cursorKeyCh) - return - - const newKey = new Theory.Key(new Theory.PitchName(letter, key.tonic.accidental), key.scale) - const newKeyCh = cursorKeyCh.withChanges({ key: newKey }) - const project = state.project.upsertKeyChange(newKeyCh) - dispatch({ type: "projectSet", project }) - } - - const setTonicAccidental = (acc) => - { - if (!cursorKeyCh) - return - - const newKey = new Theory.Key(new Theory.PitchName(key.tonic.letter, acc), key.scale) - const newKeyCh = cursorKeyCh.withChanges({ key: newKey }) - const project = state.project.upsertKeyChange(newKeyCh) - dispatch({ type: "projectSet", project }) - } - - const setScale = (scale) => - { - if (!cursorKeyCh) - return - - const newKey = new Theory.Key(key.tonic, scale) - const newKeyCh = cursorKeyCh.withChanges({ key: newKey }) - const project = state.project.upsertKeyChange(newKeyCh) - dispatch({ type: "projectSet", project }) - } - - return - - - setTonicLetter(parseInt(ev.target.value)) } - > - { [0, 1, 2, 3, 4, 5, 6].map(i => ) } - - setTonicAccidental(parseInt(ev.target.value)) } - > - { [2, 1, 0, -1, -2].map(acc => ) } - - setScale(Theory.Scale.fromId(ev.target.value)) } - > - { Theory.Scale.list.map(scale => ) } - - } - /> - - -} - - -function MeterChangeToolbox(props) -{ - const state = props.state - const dispatch = props.dispatch - - const time = Editor.insertionTime(props.state) - const cursorMeterCh = state.project.meterChanges.findActiveAt(time) - const meter = cursorMeterCh ? cursorMeterCh.meter : Editor.defaultMeter() - - const meterDenominators = [1, 2, 4, 8, 16, 32, 64] - - const setNumerator = (numerator) => - { - if (!cursorMeterCh) - return - - const newMeter = new Theory.Meter(numerator, meter.denominator) - const newMeterCh = cursorMeterCh.withChanges({ meter: newMeter }) - const project = state.project.upsertMeterChange(newMeterCh) - dispatch({ type: "projectSet", project }) - } - - const setDenominator = (denominator) => - { - if (!cursorMeterCh) - return - - const newMeter = new Theory.Meter(meter.numerator, denominator) - const newMeterCh = cursorMeterCh.withChanges({ meter: newMeter }) - const project = state.project.upsertMeterChange(newMeterCh) - dispatch({ type: "projectSet", project }) - } - - return - - - setNumerator(Math.max(1, Math.min(64, ev.target.value))) } - onKeyDown={ ev => ev.stopPropagation() } - min="1" max="64" - style={{ width:"3em" }} - /> - { " / " } - setDenominator(parseInt(ev.target.value)) } - style={{ height:"2em" }} - > - { meterDenominators.map(d => ) } - - } - /> - - -} - - -export default function ToolboxMarkers(props) -{ - const state = props.state - const dispatch = props.dispatch - - const time = Editor.insertionTime(props.state) - const insertKeyChange = () => dispatch({ type: "insertKeyChange", time, key: Editor.defaultKey() }) - const insertMeterChange = () => dispatch({ type: "insertMeterChange", time, meter: Editor.defaultMeter() }) - - const insertIconStyle = - { - fontWeight: "bold", - } - - return <> - - + } - label="Key Change" - /> - + } - label="Meter Change" - /> - - - { KeyChangeToolbox({ state, dispatch }) } - { MeterChangeToolbox({ state, dispatch }) } - -} \ No newline at end of file diff --git a/src_old/toolbox/ToolboxNote.js b/src_old/toolbox/ToolboxNote.js deleted file mode 100644 index 6db0967..0000000 --- a/src_old/toolbox/ToolboxNote.js +++ /dev/null @@ -1,58 +0,0 @@ -import React from "react" -import Ribbon from "./Ribbon.js" -import Editor from "../editor/editor.js" -import CanvasUtils from "../util/canvas.js" - - -function NoteButton(props) -{ - const refCanvas = React.useRef(null) - - const w = 30 - const h = 50 - - const key = props.theoryKey - const midi = props.noteIndex + key.tonic.midi - const degree = key.degreeForMidi(midi) + key.scale.metadata.mode - - React.useEffect(() => - { - const ctx = refCanvas.current.getContext("2d") - ctx.fillStyle = CanvasUtils.fillStyleForDegree(ctx, degree) - ctx.fillRect(0, 0, w, h) - - }, [props.theoryKey, props.noteIndex]) - - const onClick = () => - { - const time = Editor.insertionTime(props.state) - props.dispatch({ type: "insertNote", chroma: midi, time }) - } - - return } - label={ key.nameForMidi(midi).str } - /> -} - - -export default function ToolboxNote(props) -{ - const state = props.state - const dispatch = props.dispatch - - const time = Editor.insertionTime(props.state) - const cursorKeyCh = state.project.keyChanges.findActiveAt(time) - const key = cursorKeyCh ? cursorKeyCh.key : Editor.defaultKey() - - return - { [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map(noteIndex => - - )} - -} \ No newline at end of file diff --git a/src_old/toolbox/ToolboxPlayback.js b/src_old/toolbox/ToolboxPlayback.js deleted file mode 100644 index 9647698..0000000 --- a/src_old/toolbox/ToolboxPlayback.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from "react" -import Ribbon from "./Ribbon.js" - - -export default function ToolboxPlayback(props) -{ - const state = props.state - const playbackController = props.playbackController - - const rewind = () => - { - props.dispatch({ type: "rewind" }) - } - - const setBaseBpm = (value) => - { - props.dispatch({ type: "set", state: { project: state.project.withChanges({ baseBpm: value }) } }) - } - - return - - - - - Base BPM} - label={ setBaseBpm(ev.target.value) } - />} - /> - - - -} \ No newline at end of file diff --git a/src/types.ts b/src_old/types.ts similarity index 100% rename from src/types.ts rename to src_old/types.ts diff --git a/src/ui/Button.tsx b/src_old/ui/Button.tsx similarity index 100% rename from src/ui/Button.tsx rename to src_old/ui/Button.tsx diff --git a/src/ui/ButtonList.tsx b/src_old/ui/ButtonList.tsx similarity index 100% rename from src/ui/ButtonList.tsx rename to src_old/ui/ButtonList.tsx diff --git a/src/ui/ChordButton.tsx b/src_old/ui/ChordButton.tsx similarity index 100% rename from src/ui/ChordButton.tsx rename to src_old/ui/ChordButton.tsx diff --git a/src/ui/Dial.tsx b/src_old/ui/Dial.tsx similarity index 100% rename from src/ui/Dial.tsx rename to src_old/ui/Dial.tsx diff --git a/src/ui/DropdownMenu.tsx b/src_old/ui/DropdownMenu.tsx similarity index 100% rename from src/ui/DropdownMenu.tsx rename to src_old/ui/DropdownMenu.tsx diff --git a/src/ui/Input.tsx b/src_old/ui/Input.tsx similarity index 100% rename from src/ui/Input.tsx rename to src_old/ui/Input.tsx diff --git a/src/ui/ListBox.tsx b/src_old/ui/ListBox.tsx similarity index 100% rename from src/ui/ListBox.tsx rename to src_old/ui/ListBox.tsx diff --git a/src/ui/LoadingBar.tsx b/src_old/ui/LoadingBar.tsx similarity index 100% rename from src/ui/LoadingBar.tsx rename to src_old/ui/LoadingBar.tsx diff --git a/src/ui/index.ts b/src_old/ui/index.ts similarity index 100% rename from src/ui/index.ts rename to src_old/ui/index.ts diff --git a/src/util/async.ts b/src_old/util/async.ts similarity index 100% rename from src/util/async.ts rename to src_old/util/async.ts diff --git a/src/util/binaryReader.ts b/src_old/util/binaryReader.ts similarity index 100% rename from src/util/binaryReader.ts rename to src_old/util/binaryReader.ts diff --git a/src/util/binaryWriter.ts b/src_old/util/binaryWriter.ts similarity index 100% rename from src/util/binaryWriter.ts rename to src_old/util/binaryWriter.ts diff --git a/src/util/canvasUtils.ts b/src_old/util/canvasUtils.ts similarity index 100% rename from src/util/canvasUtils.ts rename to src_old/util/canvasUtils.ts diff --git a/src/util/globalObservable.ts b/src_old/util/globalObservable.ts similarity index 100% rename from src/util/globalObservable.ts rename to src_old/util/globalObservable.ts diff --git a/src/util/misc.ts b/src_old/util/misc.ts similarity index 100% rename from src/util/misc.ts rename to src_old/util/misc.ts diff --git a/src/util/refState.ts b/src_old/util/refState.ts similarity index 100% rename from src/util/refState.ts rename to src_old/util/refState.ts diff --git a/src/util/wavEncode.ts b/src_old/util/wavEncode.ts similarity index 100% rename from src/util/wavEncode.ts rename to src_old/util/wavEncode.ts diff --git a/src/windows/Inspector.tsx b/src_old/windows/Inspector.tsx similarity index 100% rename from src/windows/Inspector.tsx rename to src_old/windows/Inspector.tsx diff --git a/src/windows/InspectorChord.tsx b/src_old/windows/InspectorChord.tsx similarity index 100% rename from src/windows/InspectorChord.tsx rename to src_old/windows/InspectorChord.tsx diff --git a/src/windows/InspectorKeyChange.tsx b/src_old/windows/InspectorKeyChange.tsx similarity index 100% rename from src/windows/InspectorKeyChange.tsx rename to src_old/windows/InspectorKeyChange.tsx diff --git a/src/windows/InspectorMeterChange.tsx b/src_old/windows/InspectorMeterChange.tsx similarity index 100% rename from src/windows/InspectorMeterChange.tsx rename to src_old/windows/InspectorMeterChange.tsx diff --git a/src/windows/InspectorMultitype.tsx b/src_old/windows/InspectorMultitype.tsx similarity index 100% rename from src/windows/InspectorMultitype.tsx rename to src_old/windows/InspectorMultitype.tsx diff --git a/src/windows/InspectorTrack.tsx b/src_old/windows/InspectorTrack.tsx similarity index 100% rename from src/windows/InspectorTrack.tsx rename to src_old/windows/InspectorTrack.tsx diff --git a/src/windows/InstrumentSelect.tsx b/src_old/windows/InstrumentSelect.tsx similarity index 100% rename from src/windows/InstrumentSelect.tsx rename to src_old/windows/InstrumentSelect.tsx diff --git a/src/windows/Render.tsx b/src_old/windows/Render.tsx similarity index 100% rename from src/windows/Render.tsx rename to src_old/windows/Render.tsx diff --git a/src/windows/Test.tsx b/src_old/windows/Test.tsx similarity index 100% rename from src/windows/Test.tsx rename to src_old/windows/Test.tsx diff --git a/src/windows/Timeline.tsx b/src_old/windows/Timeline.tsx similarity index 100% rename from src/windows/Timeline.tsx rename to src_old/windows/Timeline.tsx diff --git a/src/windows/index.ts b/src_old/windows/index.ts similarity index 100% rename from src/windows/index.ts rename to src_old/windows/index.ts diff --git a/tsconfig.json b/tsconfig.json index 01c2a6b..bd2e131 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,22 @@ { "compilerOptions": { - "sourceMap": true, - "target": "esnext", - "module": "esnext", - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "strict": true, - "jsx": "react" + "baseUrl": "./src/", + "jsx": "preserve", + "jsxImportSource": "solid-js", + "module": "esnext", + "moduleResolution": "bundler", + "target": "es2022", + "allowImportingTsExtensions": true, + "noEmit": true, + "strictNullChecks": true, + "noImplicitAny": true }, - "exclude": ["src_old"] + "include": [ + "./src/*.ts", + "./src/*.tsx" + ], + "exclude": [ + "src_old", + "src_old2" + ] } \ No newline at end of file diff --git a/watch.bat b/watch.bat deleted file mode 100644 index 7946708..0000000 --- a/watch.bat +++ /dev/null @@ -1 +0,0 @@ -npm run watch \ No newline at end of file diff --git a/webpack.config.cjs b/webpack.config.cjs index 7ec9698..6cd31f6 100644 --- a/webpack.config.cjs +++ b/webpack.config.cjs @@ -1,53 +1,43 @@ const path = require("path") -module.exports = -{ - mode: "production", - entry: - { - main: path.resolve(__dirname, "src/main.js"), +module.exports = { + mode: "production", + devtool: "source-map", + + entry: { + main: path.resolve(__dirname, "src/main.tsx"), }, - output: - { + output: { filename: "[name].js", - path: path.resolve(__dirname, "build") + path: path.resolve(__dirname, ".build"), + publicPath: "/.build/", }, - - resolve: { - extensions: [".ts", ".tsx", ".js", ".json"], + + resolve: { + extensions: [".ts", ".tsx"], fallback: { "assert": false, - /*"zlib": require.resolve("browserify-zlib"), - "util": require.resolve("util/"), - "buffer": require.resolve("buffer/"), - "stream": require.resolve("stream-browserify"),*/ }, - }, - - module: - { - rules: - [ - { - test: /\.tsx?$/, - exclude: /src_old/, - loader: "ts-loader", - }, - { test: /\.js$/, loader: "source-map-loader" }, + }, + + module: { + rules: [ { - test: /\.(js|jsx)$/, + test: /\.(ts|tsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { - plugins: ["@babel/plugin-proposal-class-properties"], - presets: ["@babel/preset-env", "@babel/preset-react"] + presets: [ + "@babel/preset-typescript", + "babel-preset-solid", + ] } } } ] - } + }, } \ No newline at end of file From eedcc59a63660565bbdf1730f3eca4938e70690a Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Fri, 12 Dec 2025 11:43:10 -0300 Subject: [PATCH 02/20] update dependencies --- .build/main.js | 12447 ------------------------------------------- .build/main.js.map | 1 - .gitignore | 2 +- package-lock.json | 2673 +++++----- package.json | 16 +- 5 files changed, 1244 insertions(+), 13895 deletions(-) delete mode 100644 .build/main.js delete mode 100644 .build/main.js.map diff --git a/.build/main.js b/.build/main.js deleted file mode 100644 index 3774c83..0000000 --- a/.build/main.js +++ /dev/null @@ -1,12447 +0,0 @@ -/******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ({ - -/***/ "./src/prefs.ts": -/*!**********************!*\ - !*** ./src/prefs.ts ***! - \**********************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ makeNew: () => (/* binding */ makeNew) -/* harmony export */ }); -function makeNew() { - return { - timeline: { - bkgColor: "#202225", - bkgAlternateMeasureColor: "#1a1c1f", - bkgInactiveOverlayColor: "#0008", - trackVBorderColor: "#888", - trackHBorderColor: "#888", - selectionCursorColor: "#0af", - selectionBkgColor: "#8cf8", - playbackCursorColor: "#f00", - trackSeparatorColor: "#aaa", - measureColor: "#040404", - submeasureColor: "#080808", - halfSubmeasureColor: "#181818", - measureLabelColor: "#aaa", - octaveLabelColor: "#aaa", - meterChangeColor: "#0cf", - keyChangeColor: "#f0c", - noteVelocityMarkerColor: "#0c4", - noteVelocityMarkerInactiveColor: "#063", - keyPan: " ", - keyPencil: "a", - keySelectMultiple: "control", - keySelectRange: "shift", - keySelectRect: "shift", - keySelectClone: "alt", - keyDisplaceCursor2: "shift", - keyDisplaceFast: "control", - keyDisplaceChromatically: "shift", - keyDisplaceStretch: "shift", - mouseDoubleClickThresholdMs: 300, - mouseDragXLockedDistance: 10, - mouseDragYLockedDistance: 10, - mouseEdgeScrollThreshold: 10, - mouseEdgeScrollSpeed: 1 - } - }; -} - -/***/ }), - -/***/ "./src/project/elem.ts": -/*!*****************************!*\ - !*** ./src/project/elem.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ DefaultChordVolumeDb: () => (/* binding */ DefaultChordVolumeDb), -/* harmony export */ DefaultVolumeDb: () => (/* binding */ DefaultVolumeDb), -/* harmony export */ MaxVolumeDb: () => (/* binding */ MaxVolumeDb), -/* harmony export */ MinVolumeDb: () => (/* binding */ MinVolumeDb), -/* harmony export */ elemModify: () => (/* binding */ elemModify), -/* harmony export */ makeChord: () => (/* binding */ makeChord), -/* harmony export */ makeKeyChange: () => (/* binding */ makeKeyChange), -/* harmony export */ makeMeterChange: () => (/* binding */ makeMeterChange), -/* harmony export */ makeNote: () => (/* binding */ makeNote), -/* harmony export */ makeTrackChords: () => (/* binding */ makeTrackChords), -/* harmony export */ makeTrackKeyChanges: () => (/* binding */ makeTrackKeyChanges), -/* harmony export */ makeTrackMeterChanges: () => (/* binding */ makeTrackMeterChanges), -/* harmony export */ makeTrackNotes: () => (/* binding */ makeTrackNotes), -/* harmony export */ trackDisplayName: () => (/* binding */ trackDisplayName) -/* harmony export */ }); -/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); - -const MinVolumeDb = -30; -const MaxVolumeDb = 0; -const DefaultVolumeDb = 0; -const DefaultChordVolumeDb = -4; -function elemModify(original, changes) { - return { - ...original, - ...changes - }; -} -function makeTrackNotes() { - return { - type: "track", - trackType: "notes", - id: -1, - parentId: 0, - range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), - name: "", - mute: false, - solo: false - }; -} -function makeTrackChords() { - return { - type: "track", - trackType: "chords", - id: -1, - parentId: 0, - range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), - name: "Chords", - mute: false, - solo: false - }; -} -function trackDisplayName(track) { - if (track.name) return track.name; - return "New Track"; -} -function makeTrackKeyChanges() { - return { - type: "track", - trackType: "keyChanges", - id: -1, - parentId: 0, - range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), - name: "Key Changes" - }; -} -function makeTrackMeterChanges() { - return { - type: "track", - trackType: "meterChanges", - id: -1, - parentId: 0, - range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].dummy(), - name: "Meter Changes" - }; -} -function makeMeterChange(parentId, time, meter) { - return { - type: "meterChange", - id: -1, - parentId, - range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromPoint(time), - meter - }; -} -function makeKeyChange(parentId, time, key) { - return { - type: "keyChange", - id: -1, - parentId, - range: _utils_range_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromPoint(time), - key - }; -} -function makeNote(parentId, range, midiPitch) { - return { - type: "note", - id: -1, - parentId, - range, - midiPitch - }; -} -function makeChord(parentId, range, chord) { - return { - type: "chord", - id: -1, - parentId, - range, - chord - }; -} - -/***/ }), - -/***/ "./src/project/index.ts": -/*!******************************!*\ - !*** ./src/project/index.ts ***! - \******************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ DefaultChordVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.DefaultChordVolumeDb), -/* harmony export */ DefaultVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.DefaultVolumeDb), -/* harmony export */ MAX_RATIONAL_DENOMINATOR: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR), -/* harmony export */ MaxVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.MaxVolumeDb), -/* harmony export */ MinVolumeDb: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.MinVolumeDb), -/* harmony export */ cloneElem: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.cloneElem), -/* harmony export */ defaultKey: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.defaultKey), -/* harmony export */ defaultMeter: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.defaultMeter), -/* harmony export */ elemModify: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.elemModify), -/* harmony export */ ensureMeasureCacheRefreshed: () => (/* reexport safe */ _measures__WEBPACK_IMPORTED_MODULE_1__.ensureMeasureCacheRefreshed), -/* harmony export */ getAbsoluteRange: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange), -/* harmony export */ getAbsoluteTime: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteTime), -/* harmony export */ getElem: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getElem), -/* harmony export */ getMillisecondsAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getMillisecondsAt), -/* harmony export */ getRangeForElems: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getRangeForElems), -/* harmony export */ getRelativeRange: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getRelativeRange), -/* harmony export */ getRelativeTime: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getRelativeTime), -/* harmony export */ getTrack: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.getTrack), -/* harmony export */ iterMeasuresAtRange: () => (/* reexport safe */ _measures__WEBPACK_IMPORTED_MODULE_1__.iterMeasuresAtRange), -/* harmony export */ keyAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.keyAt), -/* harmony export */ keyChangeTrackId: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.keyChangeTrackId), -/* harmony export */ makeChord: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeChord), -/* harmony export */ makeEmpty: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.makeEmpty), -/* harmony export */ makeKeyChange: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeKeyChange), -/* harmony export */ makeMeterChange: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeMeterChange), -/* harmony export */ makeNew: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.makeNew), -/* harmony export */ makeNote: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeNote), -/* harmony export */ makeTest: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.makeTest), -/* harmony export */ makeTrackChords: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackChords), -/* harmony export */ makeTrackKeyChanges: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackKeyChanges), -/* harmony export */ makeTrackMeterChanges: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackMeterChanges), -/* harmony export */ makeTrackNotes: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.makeTrackNotes), -/* harmony export */ meterAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.meterAt), -/* harmony export */ meterChangeAt: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.meterChangeAt), -/* harmony export */ meterChangeTrackId: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.meterChangeTrackId), -/* harmony export */ parentTrackFor: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.parentTrackFor), -/* harmony export */ splitElem: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.splitElem), -/* harmony export */ trackDisplayName: () => (/* reexport safe */ _elem__WEBPACK_IMPORTED_MODULE_2__.trackDisplayName), -/* harmony export */ upsertElement: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.upsertElement), -/* harmony export */ upsertTrack: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.upsertTrack), -/* harmony export */ withRefreshedRange: () => (/* reexport safe */ _root__WEBPACK_IMPORTED_MODULE_0__.withRefreshedRange) -/* harmony export */ }); -/* harmony import */ var _root__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./root */ "./src/project/root.ts"); -/* harmony import */ var _measures__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./measures */ "./src/project/measures.ts"); -/* harmony import */ var _elem__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./elem */ "./src/project/elem.ts"); -//export * from "./_global" - - - -//export * from "./midiImport" -//export * from "./midiExport" -//export * from "./jsonExport" -//export * from "./jsonImport" - -/***/ }), - -/***/ "./src/project/measures.ts": -/*!*********************************!*\ - !*** ./src/project/measures.ts ***! - \*********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ensureMeasureCacheRefreshed: () => (/* binding */ ensureMeasureCacheRefreshed), -/* harmony export */ iterMeasuresAtRange: () => (/* binding */ iterMeasuresAtRange) -/* harmony export */ }); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/project/index.ts"); -/* harmony import */ var _utils_binarySearch_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/binarySearch.ts */ "./src/utils/binarySearch.ts"); - - -let measureCacheKey = null; -let measureCache = []; -let firstMeterCh = null; -let lastMeterCh = null; -function ensureMeasureCacheRefreshed(project) { - const meterChangeTrackId = _index_ts__WEBPACK_IMPORTED_MODULE_0__.meterChangeTrackId(project); - const meterChangeList = project.lists.get(meterChangeTrackId); - if (meterChangeList === measureCacheKey) return; - measureCacheKey = meterChangeList; - measureCache = []; - if (!meterChangeList) return; - let num = 0; - for (const [elem1, elem2] of meterChangeList.iterAllPairwise()) { - if (!elem1) firstMeterCh = elem2; - if (!elem2) lastMeterCh = elem1; - if (!elem1 || !elem2) continue; - const meterCh1 = elem1; - const meterCh2 = elem2; - let numLocal = 0; - for (const [measureN, measureD, time1, time2] of meterCh1.meter.iterMeasuresPairwise(meterCh1.range.start)) { - if (meterCh2 && time1.compare(meterCh2.range.start) >= 0) break; - measureCache.push({ - num, - numLocal, - time1, - time2: time2.min(meterCh2 ? meterCh2.range.start : time2), - meterCh: meterCh1 - }); - num++; - numLocal++; - } - } -} -function* iterMeasuresAtRange(project, range) { - ensureMeasureCacheRefreshed(project); - const measureStart = _utils_binarySearch_ts__WEBPACK_IMPORTED_MODULE_1__["default"].findPreviousOrEqual(measureCache, m => range.start.compare(m.time1)); - if (measureStart === null && firstMeterCh) { - let time = firstMeterCh.range.start; - let num = 0; - while (time.compare(range.start) > 0) { - time = time.subtract(firstMeterCh.meter.fullCycleDuration); - num--; - } - while (time.compare(firstMeterCh.range.start) < 0) { - const time2 = time.add(firstMeterCh.meter.fullCycleDuration); - if (time2.compare(range.start) >= 0) { - yield { - meterCh: firstMeterCh, - num, - numLocal: num, - time1: time, - time2 - }; - } - time = time2; - num++; - } - } - let lastMeasureNum = -1; - let measureIndex = measureStart ?? 0; - while (true) { - if (measureIndex >= measureCache.length) break; - const measure = measureCache[measureIndex]; - if (measure.time1.compare(range.end) >= 0) break; - yield measure; - lastMeasureNum = measure.num; - measureIndex++; - } - if (lastMeterCh) { - let num = lastMeasureNum + 1; - let time = lastMeterCh.range.start; - while (time.compare(range.end) < 0) { - const time2 = time.add(lastMeterCh.meter.fullCycleDuration); - if (time2.compare(range.start) >= 0) { - yield { - meterCh: lastMeterCh, - num, - numLocal: num, - time1: time, - time2 - }; - } - time = time2; - num++; - } - } -} - -/***/ }), - -/***/ "./src/project/root.ts": -/*!*****************************!*\ - !*** ./src/project/root.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ MAX_RATIONAL_DENOMINATOR: () => (/* binding */ MAX_RATIONAL_DENOMINATOR), -/* harmony export */ cloneElem: () => (/* binding */ cloneElem), -/* harmony export */ defaultKey: () => (/* binding */ defaultKey), -/* harmony export */ defaultMeter: () => (/* binding */ defaultMeter), -/* harmony export */ getAbsoluteRange: () => (/* binding */ getAbsoluteRange), -/* harmony export */ getAbsoluteTime: () => (/* binding */ getAbsoluteTime), -/* harmony export */ getElem: () => (/* binding */ getElem), -/* harmony export */ getMillisecondsAt: () => (/* binding */ getMillisecondsAt), -/* harmony export */ getRangeForElems: () => (/* binding */ getRangeForElems), -/* harmony export */ getRelativeRange: () => (/* binding */ getRelativeRange), -/* harmony export */ getRelativeTime: () => (/* binding */ getRelativeTime), -/* harmony export */ getTrack: () => (/* binding */ getTrack), -/* harmony export */ keyAt: () => (/* binding */ keyAt), -/* harmony export */ keyChangeTrackId: () => (/* binding */ keyChangeTrackId), -/* harmony export */ makeEmpty: () => (/* binding */ makeEmpty), -/* harmony export */ makeNew: () => (/* binding */ makeNew), -/* harmony export */ makeTest: () => (/* binding */ makeTest), -/* harmony export */ meterAt: () => (/* binding */ meterAt), -/* harmony export */ meterChangeAt: () => (/* binding */ meterChangeAt), -/* harmony export */ meterChangeTrackId: () => (/* binding */ meterChangeTrackId), -/* harmony export */ parentTrackFor: () => (/* binding */ parentTrackFor), -/* harmony export */ splitElem: () => (/* binding */ splitElem), -/* harmony export */ upsertElement: () => (/* binding */ upsertElement), -/* harmony export */ upsertTrack: () => (/* binding */ upsertTrack), -/* harmony export */ withRefreshedRange: () => (/* binding */ withRefreshedRange) -/* harmony export */ }); -/* harmony import */ var immutable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! immutable */ "./node_modules/immutable/dist/immutable.es.js"); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/project/index.ts"); -/* harmony import */ var _theory__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../theory */ "./src/theory/index.ts"); -/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); -/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); -/* harmony import */ var _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/listOfRanges.ts */ "./src/utils/listOfRanges.ts"); - - - - - - - -// Least Common Multiple of 2, 3, 4, 5, 6, 7, 8, 9, and 10. -const MAX_RATIONAL_DENOMINATOR = 2520; -function makeEmpty() { - return { - nextId: 1, - range: new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](4)), - baseBpm: 120, - tracks: [], - lists: immutable__WEBPACK_IMPORTED_MODULE_5__["default"].Map(), - elems: immutable__WEBPACK_IMPORTED_MODULE_5__["default"].Map(), - keyChangeTrackId: -1, - meterChangeTrackId: -1, - chordTrackId: -1, - noteTrackId: -1 - }; -} -function makeNew() { - let project = makeEmpty(); - const track1Id = project.nextId; - project.keyChangeTrackId = track1Id; - project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackKeyChanges()); - const track2Id = project.nextId; - project.meterChangeTrackId = track2Id; - project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackMeterChanges()); - project = upsertElement(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeKeyChange(track1Id, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), _theory__WEBPACK_IMPORTED_MODULE_1__.Key.parse("C Major"))); - project = upsertElement(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeMeterChange(track2Id, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), new _theory__WEBPACK_IMPORTED_MODULE_1__.Meter(4, 4))); - const track3Id = project.nextId; - project.chordTrackId = track3Id; - project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackChords()); - const track4Id = project.nextId; - project.noteTrackId = track4Id; - project = upsertTrack(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeTrackNotes()); - return project; -} -function makeTest() { - let project = makeNew(); - for (let i = 0; i < 24; i++) project = upsertElement(project, _index_ts__WEBPACK_IMPORTED_MODULE_0__.makeNote(project.noteTrackId, _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"].fromStartDuration(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](i, 4), new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](1, 4)), _theory__WEBPACK_IMPORTED_MODULE_1__.Utils.midiMiddleC + i)); - return project; -} -function upsertTrack(project, track, remove = false, insertBefore = -1) { - let nextId = project.nextId; - let tracks = project.tracks; - if (track.id < 0) { - track = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(track, { - id: nextId - }); - nextId++; - } - if (remove) { - const trackIndex = tracks.findIndex(t => t.id === track.id); - if (trackIndex >= 0) tracks = [...tracks.slice(0, trackIndex), ...tracks.slice(trackIndex + 1)]; - } else { - const trackIndex = tracks.findIndex(t => t.id === track.id); - if (trackIndex < 0) { - if (insertBefore < 0) tracks = [...tracks, track];else tracks = [...tracks.slice(0, insertBefore), track, ...tracks.slice(insertBefore)]; - } else { - tracks = [...tracks.slice(0, trackIndex), track, ...tracks.slice(trackIndex + 1)]; - } - } - let elems = project.elems; - if (remove) elems = elems.delete(track.id);else elems = elems.set(track.id, track); - return { - ...project, - nextId, - elems, - tracks - }; -} -function upsertElement(project, elem) { - let nextId = project.nextId; - if (elem.id < 0) { - elem = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, { - id: nextId - }); - nextId++; - } - const prevElem = project.elems.get(elem.id); - const changeParent = !!prevElem && prevElem.parentId != elem.parentId; - if (!changeParent) { - let list = project.lists.get(elem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); - list = list.upsert(elem); - let elems = project.elems.set(elem.id, elem); - let lists = project.lists.set(elem.parentId, list); - return { - ...project, - nextId, - elems, - lists - }; - } else if (elem.parentId < 0) { - let prevList = project.lists.get(prevElem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); - prevList = prevList.removeById(prevElem.id); - let elems = project.elems.delete(elem.id); - let lists = project.lists.set(prevElem.parentId, prevList); - return { - ...project, - nextId, - elems, - lists - }; - } else { - let prevList = project.lists.get(prevElem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); - prevList = prevList.removeById(prevElem.id); - let nextList = project.lists.get(elem.parentId) ?? new _utils_listOfRanges_ts__WEBPACK_IMPORTED_MODULE_4__["default"](); - nextList = nextList.upsert(elem); - let elems = project.elems.set(elem.id, elem); - let lists = project.lists.set(prevElem.parentId, prevList).set(elem.parentId, nextList); - return { - ...project, - nextId, - elems, - lists - }; - } -} -function keyChangeTrackId(project) { - return project.keyChangeTrackId; -} -function meterChangeTrackId(project) { - return project.meterChangeTrackId; -} -function keyAt(project, trackId, time) { - const keyChangeTrackId = _index_ts__WEBPACK_IMPORTED_MODULE_0__.keyChangeTrackId(project); - const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId); - if (!keyChangeTrackTimedElems) return defaultKey(); - const keyCh = keyChangeTrackTimedElems.findActiveAt(time); - if (keyCh) return keyCh.key; - const firstKeyCh = keyChangeTrackTimedElems.findFirst(); - if (firstKeyCh) return firstKeyCh.key; - return defaultKey(); -} -function meterChangeAt(project, trackId, time) { - const meterChangeTrackId = _index_ts__WEBPACK_IMPORTED_MODULE_0__.meterChangeTrackId(project); - const meterChangeTrackTimedElems = project.lists.get(meterChangeTrackId); - if (!meterChangeTrackTimedElems) return null; - const meterCh = meterChangeTrackTimedElems.findActiveAt(time); - if (meterCh) return meterCh; - const firstMeterCh = meterChangeTrackTimedElems.findFirst(); - if (firstMeterCh) return firstMeterCh; - return null; -} -function meterAt(project, trackId, time) { - const meterCh = meterChangeAt(project, trackId, time); - if (meterCh) return meterCh.meter; - return defaultMeter(); -} -function withRefreshedRange(project) { - let range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](4)); - for (const track of project.tracks) { - const list = project.lists.get(track.id); - if (list) range = range.merge(list.getTotalRange()); - } - if (range.start.compare(project.range.start) == 0 && range.end.compare(project.range.end) == 0) return project; - return { - ...project, - range - }; -} -function getElem(project, id, type) { - const elem = project.elems.get(id); - if (!elem || elem.type != type) return null; - return elem; -} -function getTrack(project, id, trackType) { - const elem = project.elems.get(id); - if (!elem || elem.type != "track" || elem.trackType != trackType) return null; - return elem; -} -function cloneElem(fromProject, elem, toProject) { - const newElem = { - ...elem - }; - newElem.id = -1; - const newId = toProject.nextId; - toProject = _index_ts__WEBPACK_IMPORTED_MODULE_0__.upsertElement(toProject, newElem); - const innerList = fromProject.lists.get(elem.id); - if (innerList) { - for (const innerElem of innerList.iterAll()) { - const newInnerElem = { - ...innerElem - }; - newInnerElem.parentId = newId; - toProject = cloneElem(fromProject, newInnerElem, toProject); - } - } - return toProject; -} -function splitElem(project, elem, splitRange) { - const origProject = project; - const absRange = getAbsoluteRange(origProject, elem.parentId, elem.range); - if (!absRange.overlapsRange(splitRange)) return project; - const removeElem = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, { - parentId: -1 - }); - project = _index_ts__WEBPACK_IMPORTED_MODULE_0__.upsertElement(project, removeElem); - project = splitInnerElem(origProject, project, elem.parentId, elem, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0), splitRange, absRange); - return project; -} -function splitInnerElem(origProject, project, newParentId, elem, relativeDisplace, splitRange, keepRange) { - const innerList = origProject.lists.get(elem.id); - - // FIXME: Also keep inner elements that were outside parent's range - const absRange = getAbsoluteRange(origProject, elem.parentId, elem.range); - if (!absRange.overlapsRange(keepRange)) return project; - for (const slice of absRange.iterSlices(splitRange)) { - const newElemPart = _index_ts__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, { - id: -1, - parentId: newParentId, - range: getRelativeRange(origProject, elem.parentId, slice).subtract(relativeDisplace) - }); - const newElemPartId = project.nextId; - project = _index_ts__WEBPACK_IMPORTED_MODULE_0__.upsertElement(project, newElemPart); - if (innerList) { - const innerRelativeDisplace = slice.start.subtract(absRange.start); - for (const innerElem of innerList.iterAll()) { - project = splitInnerElem(origProject, project, newElemPartId, innerElem, innerRelativeDisplace, splitRange, slice); - } - } - } - return project; -} -function parentTrackFor(project, elemId) { - while (true) { - const elem = project.elems.get(elemId); - if (!elem) return null; - if (elem.type == "track") return elem; - elemId = elem.parentId; - } -} -function getAbsoluteTime(project, parentId, time) { - while (true) { - const elem = project.elems.get(parentId); - if (!elem) return time; - if (elem.type == "track") return time; - time = time.add(elem.range.start); - parentId = elem.parentId; - } -} -function getRelativeTime(project, parentId, time) { - while (true) { - const elem = project.elems.get(parentId); - if (!elem) return time; - if (elem.type == "track") return time; - time = time.subtract(elem.range.start); - parentId = elem.parentId; - } -} -function getAbsoluteRange(project, parentId, range) { - while (true) { - const elem = project.elems.get(parentId); - if (!elem) return range; - if (elem.type == "track") return range; - range = range.displace(elem.range.start); - parentId = elem.parentId; - } -} -function getRelativeRange(project, parentId, range) { - while (true) { - const elem = project.elems.get(parentId); - if (!elem) return range; - if (elem.type == "track") return range; - range = range.subtract(elem.range.start); - parentId = elem.parentId; - } -} -function getRangeForElems(project, elemIds) { - let range = null; - for (const id of elemIds) { - const elem = project.elems.get(id); - if (!elem) continue; - if (elem.type == "track") continue; - const absRange = _index_ts__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange(project, elem.parentId, elem.range); - range = _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"].merge(range, absRange); - } - return range; -} -function getMillisecondsAt(project, time) { - const measuresPerSecond = project.baseBpm / 4 / 60; - return time.subtract(project.range.start).asFloat() / measuresPerSecond * 1000; -} -function defaultKey() { - return _theory__WEBPACK_IMPORTED_MODULE_1__.Key.parse("C Major"); -} -function defaultMeter() { - return new _theory__WEBPACK_IMPORTED_MODULE_1__.Meter(4, 4); -} - -/***/ }), - -/***/ "./src/state.ts": -/*!**********************!*\ - !*** ./src/state.ts ***! - \**********************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ get: () => (/* binding */ get), -/* harmony export */ makeNew: () => (/* binding */ makeNew), -/* harmony export */ refresh: () => (/* binding */ refresh) -/* harmony export */ }); -/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); -/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./project */ "./src/project/index.ts"); -/* harmony import */ var _timeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./timeline */ "./src/timeline/index.ts"); -/* harmony import */ var _prefs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./prefs */ "./src/prefs.ts"); - - - - -const [state, setState] = solid_js__WEBPACK_IMPORTED_MODULE_3__.createSignal(makeNew()); -function makeNew() { - return { - test: 0, - prefs: _prefs__WEBPACK_IMPORTED_MODULE_2__.makeNew(), - project: { - root: _project__WEBPACK_IMPORTED_MODULE_0__.makeTest() - }, - timeline: _timeline__WEBPACK_IMPORTED_MODULE_1__.makeNew() - }; -} -function get() { - return state(); -} -function refresh() { - setState({ - ...state() - }); -} - -/***/ }), - -/***/ "./src/theory/chord.ts": -/*!*****************************!*\ - !*** ./src/theory/chord.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ chordKinds: () => (/* binding */ chordKinds), -/* harmony export */ "default": () => (/* binding */ Chord) -/* harmony export */ }); -/* harmony import */ var _utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/mathUtils.ts */ "./src/utils/mathUtils.ts"); -/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); - - -const chordKinds = [{ - pitches: [0, 4, 7], - id: "M", - symbol: [false, "", null], - name: "Major", - startGroup: "Triads" -}, { - pitches: [0, 3, 7], - id: "m", - symbol: [true, "", null], - name: "Minor" -}, { - pitches: [0, 4, 8], - id: "+", - symbol: [false, "", "+"], - name: "Augmented" -}, { - pitches: [0, 3, 6], - id: "o", - symbol: [true, "", "o"], - name: "Diminished" -}, { - pitches: [0, 2, 6], - id: "oo", - symbol: [true, "", "oo"], - name: "Doubly-Diminished" -}, { - pitches: [0, 4, 6], - id: "b5", - symbol: [false, "", "(b5)"], - name: "Flat-Fifth" -}, { - pitches: [0, 7], - id: "5", - symbol: [false, "", "5"], - name: "Power" -}, { - pitches: [0, 4, 7, 9], - id: "6", - symbol: [false, "", "6"], - name: "Major Sixth", - startGroup: "Sixths" -}, { - pitches: [0, 3, 7, 9], - id: "m6", - symbol: [true, "", "6"], - name: "Minor Sixth" -}, { - pitches: [0, 4, 7, 10], - id: "7", - symbol: [false, "", "7"], - name: "Dominant Seventh", - startGroup: "Sevenths" -}, { - pitches: [0, 4, 7, 11], - id: "maj7", - symbol: [false, "", "M7"], - name: "Major Seventh" -}, { - pitches: [0, 3, 7, 10], - id: "m7", - symbol: [true, "", "7"], - name: "Minor Seventh" -}, { - pitches: [0, 3, 7, 11], - id: "mmaj7", - symbol: [true, "", "M7"], - name: "Minor-Major Seventh" -}, { - pitches: [0, 4, 8, 10], - id: "+7", - symbol: [false, "+", "7"], - name: "Augmented Seventh" -}, { - pitches: [0, 4, 8, 11], - id: "+maj7", - symbol: [false, "+", "M7"], - name: "Augmented Major Seventh" -}, { - pitches: [0, 3, 6, 9], - id: "o7", - symbol: [true, "", "o7"], - name: "Diminished Seventh" -}, { - pitches: [0, 3, 6, 10], - id: "%7", - symbol: [true, "", "ø7"], - name: "Half-Diminished Seventh" -}, { - pitches: [0, 4, 7, 10, 14], - id: "9", - symbol: [false, "", "9"], - name: "Dominant Ninth", - startGroup: "Ninths" -}, { - pitches: [0, 4, 7, 11, 14], - id: "maj9", - symbol: [false, "", "M9"], - name: "Major Ninth" -}, { - pitches: [0, 3, 7, 10, 14], - id: "m9", - symbol: [true, "", "9"], - name: "Minor Ninth" -}, { - pitches: [0, 3, 7, 11, 14], - id: "mmaj9", - symbol: [true, "", "M9"], - name: "Minor-Major Ninth" -}, { - pitches: [0, 3, 7, 10, 13], - id: "9?", - symbol: [true, "", "9?"], - name: "???" -}, { - pitches: [0, 4, 8, 10, 14], - id: "+9", - symbol: [false, "+", "9"], - name: "Augmented Ninth" -}, { - pitches: [0, 4, 8, 11, 14], - id: "+maj9", - symbol: [false, "+", "M9"], - name: "Augmented Major Ninth" -}, { - pitches: [0, 3, 6, 9, 14], - id: "o9", - symbol: [true, "", "o9"], - name: "Diminished Ninth" -}, { - pitches: [0, 3, 6, 9, 13], - id: "ob9", - symbol: [true, "", "o♭9"], - name: "Diminished Minor Ninth" -}, { - pitches: [0, 3, 6, 10, 14], - id: "%9", - symbol: [true, "", "ø9"], - name: "Half-Diminished Ninth" -}, { - pitches: [0, 3, 6, 10, 13], - id: "%b9", - symbol: [true, "", "ø♭9"], - name: "Half-Diminished Minor Ninth" -}]; -class Chord { - static kinds = chordKinds; - constructor(rootChroma, kind, inversion = 0, modifiers = []) { - this.rootChroma = rootChroma; - this.kind = kind; - this.inversion = inversion; - this.modifiers = modifiers; - } - withChanges(obj) { - return Object.assign(new Chord(this.rootChroma, this.kind, this.inversion, this.modifiers), obj); - } - static kindFromId(id) { - return chordKinds.findIndex(k => k.id === id); - } - static kindFromPitches(pitches) { - return chordKinds.findIndex(k => k.pitches.length === pitches.length && k.pitches.every((p, i) => pitches[i] === p)); - } - static suggestChordsForPitches(pitches) { - const suggestions = []; - for (let k = 0; k < chordKinds.length; k++) { - const kind = chordKinds[k]; - for (let root = 0; root < pitches.length; root++) { - const rootPitch = pitches[root]; - const matches = new Set(); - let misses = 0; - for (let i = 0; i < pitches.length; i++) { - const pitch = pitches[(root + i) % pitches.length]; - const relPitch = _utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__.mod(pitch - rootPitch, 12); - const kindMatch = kind.pitches.findIndex(p => p === relPitch); - if (kindMatch >= 0) matches.add(kindMatch);else misses++; - } - suggestions.push({ - chord: new Chord(_utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__.mod(rootPitch, 12), k, 0, []), - matches: matches.size, - misses - }); - } - } - suggestions.sort((a, b) => { - if (a.misses != b.misses) return a.misses - b.misses; - return b.matches - a.matches; - }); - - //console.log("suggestions", pitches, suggestions) - return suggestions.slice(0, 10); - } - get kindId() { - return chordKinds[this.kind].id; - } - romanBase(key) { - const degree = key.degreeForMidi(this.rootChroma); - const chordKind = chordKinds[this.kind] || { - symbol: [false, "", "?"] - }; - let roman = Math.floor(degree); - let accidental = 0; - if (Math.floor(degree) != degree) { - roman = _utils_mathUtils_ts__WEBPACK_IMPORTED_MODULE_0__.mod(roman + 1, 7); - accidental = -1; - } - let baseStr = _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].accidentalToStr(accidental, true) + _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].degreeToRomanStr(roman); - if (chordKind.symbol[0]) baseStr = baseStr.toLowerCase(); - return baseStr + chordKind.symbol[1]; - } - romanSup(key) { - const chordKind = chordKinds[this.kind] || { - symbol: [false, "", "?"] - }; - let supStr = chordKind.symbol[2] || ""; - if (this.modifiers) { - if (this.modifiers.add9) supStr += "(add9)"; - if (this.modifiers.add11) supStr += "(add11)"; - if (this.modifiers.add13) supStr += "(add13)"; - if (this.modifiers.no3) supStr += "(no3)"; - if (this.modifiers.no5) supStr += "(no5)"; - } - return supStr; - } - romanSub(key) { - let subStr = ""; - if (this.modifiers) { - if (this.modifiers.sus2) { - if (this.modifiers.sus4) subStr += "sus24";else subStr += "sus2"; - } else if (this.modifiers.sus4) subStr += "sus4"; - } - return subStr; - } - get pitches() { - const chordData = chordKinds[this.kind]; - if (!chordData) return []; - const rootMidi = _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].mod(this.rootChroma, 12); - const pitches = []; - for (let i = 0; i < chordData.pitches.length; i++) pitches.push(rootMidi + chordData.pitches[i]); - if (this.modifiers.sus2) pitches[1] = rootMidi + 2; - if (this.modifiers.sus4) { - if (this.modifiers.sus2) pitches.splice(2, 0, rootMidi + 5);else pitches[1] = rootMidi + 5; - } - return pitches; - } - get strummingPitches() { - const rootMidi = _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].mod(this.rootChroma, 12); - let pitches = this.pitches; - if (pitches.length == 0) return []; - let octave = 12 * 4; - if (rootMidi >= 6) octave -= 12; - pitches = pitches.map(p => p + octave); - if (pitches.length <= 3) pitches.push(pitches[0] + 12); - pitches = pitches.sort((x, y) => x - y); - let sum = pitches.reduce((x, y) => x + y) / pitches.length; - while (sum < 60) { - const x = pitches.shift(); - pitches.push(x + 12); - sum += 12 / pitches.length; - } - if (pitches.length >= 4) { - pitches[0] += 12; - pitches[3] -= 12; - } - pitches.unshift(octave + rootMidi); - return pitches; - } -} - -/***/ }), - -/***/ "./src/theory/index.ts": -/*!*****************************!*\ - !*** ./src/theory/index.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Chord: () => (/* reexport safe */ _chord_ts__WEBPACK_IMPORTED_MODULE_5__["default"]), -/* harmony export */ Key: () => (/* reexport safe */ _key_ts__WEBPACK_IMPORTED_MODULE_3__["default"]), -/* harmony export */ Meter: () => (/* reexport safe */ _meter_ts__WEBPACK_IMPORTED_MODULE_4__["default"]), -/* harmony export */ Pitch: () => (/* reexport safe */ _pitch_ts__WEBPACK_IMPORTED_MODULE_0__["default"]), -/* harmony export */ PitchName: () => (/* reexport safe */ _pitchName_ts__WEBPACK_IMPORTED_MODULE_1__["default"]), -/* harmony export */ Scale: () => (/* reexport safe */ _scale_ts__WEBPACK_IMPORTED_MODULE_2__["default"]), -/* harmony export */ Utils: () => (/* reexport safe */ _utils_ts__WEBPACK_IMPORTED_MODULE_6__["default"]) -/* harmony export */ }); -/* harmony import */ var _pitch_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitch.ts */ "./src/theory/pitch.ts"); -/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); -/* harmony import */ var _scale_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./scale.ts */ "./src/theory/scale.ts"); -/* harmony import */ var _key_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./key.ts */ "./src/theory/key.ts"); -/* harmony import */ var _meter_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./meter.ts */ "./src/theory/meter.ts"); -/* harmony import */ var _chord_ts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./chord.ts */ "./src/theory/chord.ts"); -/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); - - - - - - - - -/***/ }), - -/***/ "./src/theory/key.ts": -/*!***************************!*\ - !*** ./src/theory/key.ts ***! - \***************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Key) -/* harmony export */ }); -/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); -/* harmony import */ var _pitch_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pitch.ts */ "./src/theory/pitch.ts"); -/* harmony import */ var _scale_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./scale.ts */ "./src/theory/scale.ts"); -/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); - - - - -class Key { - constructor(tonic, scale) { - this.tonic = tonic; - this.scale = scale; - this._chromaToDegree = []; - for (let degree = 0; degree < this.scale.chromas.length; degree++) { - let chroma = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.tonic.midi + this.scale.chromas[degree], 12); - this._chromaToDegree[chroma] = degree; - const nextDegree = (degree + 1) % this.scale.chromas.length; - let nextChroma = chroma + 1; - while (true) { - let testNextChroma = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.tonic.midi + this.scale.chromas[nextDegree], 12); - while (testNextChroma < chroma) testNextChroma += 12; - if (nextChroma >= testNextChroma) break; - this._chromaToDegree[nextChroma % 12] = (degree + 0.5) % this.scale.chromas.length; - nextChroma += 1; - } - } - } - static fromTonicAndScale(tonic, scale) { - return new Key(tonic, scale); - } - static parse(str) { - str = str.toLowerCase().trim(); - const separator = str.indexOf(" "); - if (separator < 1) throw "invalid key string"; - const tonicStr = str.substr(0, separator); - const scaleStr = str.substr(separator); - const tonic = _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].parse(tonicStr); - const scale = _scale_ts__WEBPACK_IMPORTED_MODULE_2__["default"].parse(scaleStr); - return new Key(tonic, scale); - } - get str() { - const scaleStr = this.scale.name || "Unknown Scale"; - const tonicStr = this.tonic.str; - return tonicStr + " " + scaleStr; - } - toString() { - return this.str; - } - degreeForChroma(chroma) { - return _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this._chromaToDegree[chroma], this.scale.chromas.length); - } - degreeForMidi(midi) { - return this.degreeForChroma(_utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi, 12)); - } - degreeForPitch(pitch) { - return this.degreeForMidi(pitch.midi); - } - octavedDegreeForMidi(midi) { - const degree = this.degreeForMidi(midi); - const degreeOctave = Math.floor((midi - this.tonic.midi) / 12); - return degree + this.scale.chromas.length * degreeOctave; - } - octavedDegreeForPitch(pitch) { - return this.octavedDegreeForMidi(pitch.midi); - } - midiForDegree(octavedDegree) { - const degree = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(octavedDegree, this.scale.chromas.length); - const degreeOctave = Math.floor(octavedDegree / this.scale.chromas.length); - return this.tonic.midi + this.scale.chromas[degree] + degreeOctave * 12; - } - pitchForDegree(octavedDegree) { - return _pitch_ts__WEBPACK_IMPORTED_MODULE_1__["default"].fromMidi(this.midiForDegree(octavedDegree)); - } - chromaForDegree(octavedDegree) { - return _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.midiForDegree(octavedDegree), 12); - } - nameForMidi(midi) { - const degree = this.degreeForMidi(midi); - const letter1 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(this.tonic.letter + Math.floor(degree), 7); - const accidental1 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi - _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].letterToChroma(letter1) + 6, 12) - 6; - if (degree == Math.floor(degree)) return new _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"](letter1, accidental1); - const letter2 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(letter1 + 1, 7); - const accidental2 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi - _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].letterToChroma(letter2) + 6, 12) - 6; - const letter3 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(letter1 - 1, 7); - const accidental3 = _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(midi - _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].letterToChroma(letter3) + 6, 12) - 6; - const attempts = [[letter1, accidental1], [letter2, accidental2], [letter3, accidental3]]; - attempts.sort((a, b) => Math.abs(a[1]) - Math.abs(b[1])); - return new _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"](attempts[0][0], attempts[0][1]); - } - nameForPitch(pitch) { - return this.nameForMidi(pitch.midi); - } - nameForChroma(chroma) { - return this.nameForMidi(chroma); - } - nameForDegree(degree) { - return this.nameForMidi(this.midiForDegree(degree)); - } - get midi() { - return this.scale.chromas.map(chroma => chroma + this.tonic.midi); - } - get chroma() { - return this.scale.chromas.map(chroma => _utils_ts__WEBPACK_IMPORTED_MODULE_3__["default"].mod(chroma + this.tonic.midi, 12)); - } - get namedPitches() { - return this.scale.chromas.map(chroma => this.nameForMidi(chroma + this.tonic.midi)); - } -} - -/***/ }), - -/***/ "./src/theory/meter.ts": -/*!*****************************!*\ - !*** ./src/theory/meter.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Meter) -/* harmony export */ }); -/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); - -class Meter { - constructor(numerator, denominator) { - this.numerator = numerator; - this.denominator = denominator; - } - withChanges(obj) { - return Object.assign(new Meter(this.numerator, this.denominator), obj); - } - *iterMeasuresPairwise(time = null) { - time = time || new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0); - while (true) { - const nextTime = time.add(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](this.numerator, this.denominator)); - yield [this.numerator, this.denominator, time, nextTime]; - time = nextTime; - } - } - get fullCycleDuration() { - return new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](this.numerator, this.denominator); - } - get alternatingMeasureCount() { - return 1; - } - get str() { - return this.numerator + " / " + this.denominator; - } - static parse(src) { - const split = src.split("/"); - if (split.length != 2) throw "invalid meter syntax"; - const numerator = parseInt(split[0].trim()); - const denominator = parseInt(split[1].trim()); - if (!isFinite(numerator) || !isFinite(denominator)) throw "invalid meter syntax"; - return new Meter(numerator, denominator); - } -} - -/***/ }), - -/***/ "./src/theory/pitch.ts": -/*!*****************************!*\ - !*** ./src/theory/pitch.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Pitch) -/* harmony export */ }); -/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); -/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); - - -class Pitch { - constructor(midi) { - this.midi = midi; - } - static fromMidi(midi) { - return new Pitch(midi); - } - static fromOctaveAndChroma(octave, chroma) { - return Pitch.fromMidi(12 * octave + chroma); - } - static fromOctaveAndName(octave, pitchName) { - return Pitch.fromMidi(12 * octave + pitchName.midi); - } - static parse(str) { - const pitchName = _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].parse(str); - str = str.toLowerCase().trim(); - - // Determine octave - let octave = 0; - for (let i = 1; i < str.length; i++) { - const c = str.charCodeAt(i); - if (c == "-".charCodeAt(0) || c >= "0".charCodeAt(0) && c <= "9".charCodeAt(0)) { - octave = parseInt(str.substr(i)); - break; - } - } - if (octave === undefined || octave === null || isNaN(octave) || !isFinite(octave)) throw "invalid pitch string"; - return Pitch.fromOctaveAndName(octave, pitchName); - } - get frequency() { - return Math.pow(2, (this.midi - 69) / 12) * 440; - } - get octave() { - return Math.floor(this.midi / 12); - } - get chroma() { - return _utils_ts__WEBPACK_IMPORTED_MODULE_1__["default"].mod(this.midi, 12); - } - get name() { - return _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromMidi(this.midi); - } - get str() { - return this.name.str + this.octave.toString(); - } - toString() { - return this.str; - } -} - -/***/ }), - -/***/ "./src/theory/pitchName.ts": -/*!*********************************!*\ - !*** ./src/theory/pitchName.ts ***! - \*********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ PitchName) -/* harmony export */ }); -/* harmony import */ var _utils_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils.ts */ "./src/theory/utils.ts"); - -class PitchName { - constructor(letter, accidental) { - this.letter = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].mod(letter, 7); - this.accidental = accidental; - } - static fromMidi(midi) { - const chroma = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].mod(midi, 12); - const letter = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].chromaToLetter(chroma); - const accidental = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].chromaToAccidental(chroma); - return new PitchName(letter, accidental); - } - static fromChroma(chroma) { - return PitchName.fromMidi(chroma); - } - static parse(str) { - if (str.length < 1) throw "invalid pitch string"; - str = str.toLowerCase().trim(); - - // Determine letter - const letterStr = str[0]; - const letter = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].strToLetter(letterStr); - if (letter === undefined) throw "invalid pitch string"; - - // Determine accidental - let accidental = 0; - for (let i = 1; i < str.length; i++) { - const c = str.charCodeAt(i); - if (c == "b".charCodeAt(0) || c == "♭".charCodeAt(0)) accidental -= 1;else if (c == "#".charCodeAt(0) || c == "♯".charCodeAt(0)) accidental += 1; - } - return new PitchName(letter, accidental); - } - get midi() { - return _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].letterToChroma(this.letter) + this.accidental; - } - get chroma() { - return _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].mod(this.midi, 12); - } - altered(additionalAccidental) { - return new PitchName(this.letter, this.accidental + additionalAccidental); - } - get simplified() { - if (this.accidental === 0) return this;else return PitchName.fromMidi(this.midi); - } - get str() { - const letterStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].letterToStr(this.letter); - const accidentalStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].accidentalToStr(this.accidental); - return letterStr + accidentalStr; - } - get strUnicode() { - const letterStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].letterToStr(this.letter); - const accidentalStr = _utils_ts__WEBPACK_IMPORTED_MODULE_0__["default"].accidentalToStr(this.accidental, true); - return letterStr + accidentalStr; - } - toString() { - return this.str; - } -} - -/***/ }), - -/***/ "./src/theory/scale.ts": -/*!*****************************!*\ - !*** ./src/theory/scale.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Scale), -/* harmony export */ knownScales: () => (/* binding */ knownScales) -/* harmony export */ }); -/* harmony import */ var _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pitchName.ts */ "./src/theory/pitchName.ts"); - -const knownScales = [{ - chromas: [0, 2, 4, 5, 7, 9, 11], - mode: 0, - id: "maj", - names: ["Major", "Ionian"] -}, { - chromas: [0, 2, 3, 5, 7, 9, 10], - mode: 1, - id: "dor", - names: ["Dorian"] -}, { - chromas: [0, 1, 3, 5, 7, 8, 10], - mode: 2, - id: "phr", - names: ["Phrygian"] -}, { - chromas: [0, 2, 4, 6, 7, 9, 11], - mode: 3, - id: "lyd", - names: ["Lydian"] -}, { - chromas: [0, 2, 4, 5, 7, 9, 10], - mode: 4, - id: "mix", - names: ["Mixolydian"] -}, { - chromas: [0, 2, 3, 5, 7, 8, 10], - mode: 5, - id: "min", - names: ["Natural Minor", "Minor", "Aeolian"] -}, { - chromas: [0, 1, 3, 5, 6, 8, 10], - mode: 6, - id: "loc", - names: ["Locrian"] -}, { - chromas: [0, 1, 4, 5, 7, 8, 11], - mode: 0, - id: "dharmaj", - names: ["Double Harmonic Major"] -}]; -class Scale { - static list = knownScales; - constructor(chromas) { - if (chromas.length <= 1 || chromas.length > 12) throw "invalid scale length"; - this.chromas = chromas; - this.metadata = knownScales.find(s => s.chromas.length == this.chromas.length && s.chromas.every((p, index) => p == this.chromas[index])); - } - static fromChromas(chromas) { - return new Scale(chromas); - } - static fromId(id) { - return new Scale(knownScales.find(s => s.id === id).chromas); - } - static parse(str) { - str = str.toLowerCase().trim(); - const knownScale = knownScales.find(s => s.names.some(n => n.toLowerCase() == str)); - if (!knownScale) throw "no known scale with given name"; - return new Scale(knownScale.chromas); - } - get id() { - if (!this.metadata) return null; - return this.metadata.id; - } - get name() { - if (!this.metadata) return null; - return this.metadata.names[0]; - } - get alterationsFromMajor() { - if (this.chromas.length != 7) throw "not a seven-note scale"; - return this.chromas.map((pitch, i) => pitch - knownScales[0].chromas[i]); - } - get str() { - return this.name || "[" + this.chromas.map(chroma => _pitchName_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromChroma(chroma).str).join(", ") + "]"; - } - toString() { - return this.str; - } -} - -/***/ }), - -/***/ "./src/theory/utils.ts": -/*!*****************************!*\ - !*** ./src/theory/utils.ts ***! - \*****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Utils) -/* harmony export */ }); -class Utils { - static mod(x, m) { - return (x % m + m) % m; - } - static midiMiddleC = 60; - static chromaToLetter = chroma => [0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][chroma]; - static chromaToAccidental = chroma => [0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0][chroma]; - static chromaToDegreeInCMajor = chroma => [0, 0.5, 1, 1.5, 2, 3, 3.5, 4, 4.5, 5, 5.5, 6][chroma]; - static letterToChroma = letter => [0, 2, 4, 5, 7, 9, 11][letter]; - static letterToStr = letter => ["C", "D", "E", "F", "G", "A", "B"][letter]; - static strToLetter = str => { - const map = { - c: 0, - d: 1, - e: 2, - f: 3, - g: 4, - a: 5, - b: 6 - }; - return map[str]; - }; - static degreeToRomanStr = degree => ["I", "II", "III", "IV", "V", "VI", "VII"][degree]; - static degreeToColor = degree => ["#f00", "#f80", "#fd0", "#0d0", "#00f", "#80f", "#f0f"][degree]; - static degreeToColorFaded = degree => ["#400", "#420", "#430", "#030", "#004", "#204", "#404"][degree]; - static accidentalToStr(accidental, useUnicode = false) { - if (accidental < 0) return (useUnicode ? "\u{266d}" : "b").repeat(-accidental);else return (useUnicode ? "\u{266f}" : "#").repeat(accidental); - } -} - -/***/ }), - -/***/ "./src/timeline/Element.tsx": -/*!**********************************!*\ - !*** ./src/timeline/Element.tsx ***! - \**********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Element: () => (/* binding */ Element) -/* harmony export */ }); -/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/web/dist/dev.js"); -/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); -/* harmony import */ var _state_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../state.ts */ "./src/state.ts"); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); - - -var _tmpl$ = /*#__PURE__*/(0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.template)(`
`); - - - - -function Element(props) { - let div = undefined; - let canvas = undefined; - solid_js__WEBPACK_IMPORTED_MODULE_4__.createEffect(() => { - if (!div || !canvas) return; - const cleanup = registerHandlers(div, canvas); - solid_js__WEBPACK_IMPORTED_MODULE_4__.onCleanup(cleanup); - }); - return (() => { - var _el$ = _tmpl$(), - _el$2 = _el$.firstChild; - var _ref$ = div; - typeof _ref$ === "function" ? (0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.use)(_ref$, _el$) : div = _el$; - _el$.style.setProperty("width", "100%"); - _el$.style.setProperty("height", "100%"); - var _ref$2 = canvas; - typeof _ref$2 === "function" ? (0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.use)(_ref$2, _el$2) : canvas = _el$2; - return _el$; - })(); -} -function canvasResize(div, canvas, timeline) { - const pixelRatio = window.devicePixelRatio || 1; - const domRect = div.getBoundingClientRect(); - const x = Math.floor(domRect.x); - const y = Math.floor(domRect.y); - const w = Math.floor(domRect.width * pixelRatio); - const h = Math.floor(domRect.height * pixelRatio); - canvas.style.width = domRect.width + "px"; - canvas.style.height = domRect.height + "px"; - canvas.width = w; - canvas.height = h; - const rect = new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0, 0, w, h); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.resize(timeline, pixelRatio, rect); -} -function registerHandlers(div, canvas) { - const ctx = canvas.getContext("2d"); - const transformMousePos = (canvas, ev) => { - const rect = canvas.getBoundingClientRect(); - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - return { - x: (ev.clientX - rect.left) * timeline.pixelRatio, - y: (ev.clientY - rect.top) * timeline.pixelRatio - }; - }; - const setCursor = () => { - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - const action = timeline.mouse.down ? timeline.mouse.action : timeline.hover?.action; - canvas.style.cursor = action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.DragTime || action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.DragRow || action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.DragTimeAndRow ? timeline.mouse.down ? "grabbing" : "grab" : action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.StretchTimeStart || action === _index_ts__WEBPACK_IMPORTED_MODULE_2__.MouseAction.StretchTimeEnd ? "col-resize" : "inherit"; - }; - const onResize = () => { - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; - canvasResize(div, canvas, timeline); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.layout(timeline, project.root); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); - }; - const onMouseMove = ev => { - ev.preventDefault(); - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; - const mouse = transformMousePos(canvas, ev); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseMove(timeline, project.root, mouse.x, mouse.y); - if (_index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseDrag(timeline, project)) _index_ts__WEBPACK_IMPORTED_MODULE_2__.layout(timeline, project.root); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); - setCursor(); - }; - const onMouseDown = ev => { - ev.preventDefault(); - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; - const prefs = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().prefs; - const mouse = transformMousePos(canvas, ev); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseMove(timeline, project.root, mouse.x, mouse.y); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseDown(timeline, project.root, prefs, ev.button !== 0); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); - setCursor(); - }; - const onMouseUp = ev => { - ev.preventDefault(); - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; - const mouse = transformMousePos(canvas, ev); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseMove(timeline, project.root, mouse.x, mouse.y); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseUp(timeline, project.root, ev.button !== 0); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); - setCursor(); - }; - const onMouseWheel = ev => { - ev.preventDefault(); - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - const project = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().project; - _index_ts__WEBPACK_IMPORTED_MODULE_2__.mouseWheel(timeline, ev.deltaX, ev.deltaY); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.layout(timeline, project.root); - _index_ts__WEBPACK_IMPORTED_MODULE_2__.draw(timeline, ctx); - }; - const onKeyDown = ev => { - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - _index_ts__WEBPACK_IMPORTED_MODULE_2__.keyDown(timeline, ev.key.toLowerCase()); - }; - const onKeyUp = ev => { - const timeline = _state_ts__WEBPACK_IMPORTED_MODULE_1__.get().timeline; - _index_ts__WEBPACK_IMPORTED_MODULE_2__.keyUp(timeline, ev.key.toLowerCase()); - }; - const preventDefault = ev => { - ev.preventDefault(); - }; - onResize(); - canvas.addEventListener("resize", onResize); - window.addEventListener("mousemove", onMouseMove); - canvas.addEventListener("mousedown", onMouseDown); - window.addEventListener("mouseup", onMouseUp); - canvas.addEventListener("wheel", onMouseWheel); - canvas.addEventListener("contextmenu", preventDefault); - window.addEventListener("keydown", onKeyDown); - window.addEventListener("keyup", onKeyUp); - return () => { - canvas.removeEventListener("resize", onResize); - window.removeEventListener("mousemove", onMouseMove); - canvas.removeEventListener("mousedown", onMouseDown); - window.removeEventListener("mouseup", onMouseUp); - canvas.removeEventListener("wheel", onMouseWheel); - canvas.removeEventListener("contextmenu", preventDefault); - window.removeEventListener("keydown", onKeyDown); - window.removeEventListener("keyup", onKeyUp); - }; -} - -/***/ }), - -/***/ "./src/timeline/draw.ts": -/*!******************************!*\ - !*** ./src/timeline/draw.ts ***! - \******************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ draw: () => (/* binding */ draw), -/* harmony export */ drawLaneBkgCenterStroke: () => (/* binding */ drawLaneBkgCenterStroke), -/* harmony export */ drawLaneBkgMeasures: () => (/* binding */ drawLaneBkgMeasures), -/* harmony export */ drawLaneBkgOctaves: () => (/* binding */ drawLaneBkgOctaves), -/* harmony export */ drawLaneBkgSolid: () => (/* binding */ drawLaneBkgSolid), -/* harmony export */ drawLaneFrgOutline: () => (/* binding */ drawLaneFrgOutline) -/* harmony export */ }); -/* harmony import */ var _state_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../state.ts */ "./src/state.ts"); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _theory__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../theory */ "./src/theory/index.ts"); -/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); - - - - -function draw(timeline, ctx) { - ctx.save(); - ctx.translate(0.5, 0.5); - ctx.fillStyle = "#fff"; - ctx.fillRect(0, 0, timeline.renderRect.w, timeline.renderRect.h); - drawElements(timeline, ctx, timeline.layout.elements); - if (timeline.cursor.visible) { - const timeMin = timeline.cursor.time1.min(timeline.cursor.time2); - const timeMax = timeline.cursor.time1.max(timeline.cursor.time2); - drawCursorBeam(timeline, ctx, timeMin, false); - drawCursorBeam(timeline, ctx, timeMax, true); - } - ctx.restore(); -} -function drawElements(timeline, ctx, elements) { - for (const element of elements) { - if (element.kind === "lane") { - ctx.save(); - ctx.beginPath(); - ctx.rect(element.rect.x, element.rect.y, element.rect.w, element.rect.h); - ctx.clip(); - drawLaneBkgSolid(timeline, ctx, element); - drawLaneBkgMeasures(timeline, ctx, element, false); - drawLaneBkgMeasures(timeline, ctx, element, true); - drawCursorBkg(timeline, ctx, element); - if (element.subElements) drawElements(timeline, ctx, element.subElements); - drawLaneFrgOutline(timeline, ctx, element); - ctx.restore(); - } - if (element.kind === "laneNotes") { - ctx.save(); - ctx.beginPath(); - ctx.rect(element.rect.x, element.rect.y, element.rect.w, element.rect.h); - ctx.clip(); - drawLaneBkgSolid(timeline, ctx, element); - drawLaneBkgOctaves(timeline, ctx, element, false); - drawLaneBkgMeasures(timeline, ctx, element, false); - drawLaneBkgOctaves(timeline, ctx, element, true); - drawLaneBkgMeasures(timeline, ctx, element, true); - drawCursorBkg(timeline, ctx, element); - if (element.subElements) drawElements(timeline, ctx, element.subElements); - drawLaneFrgOutline(timeline, ctx, element); - ctx.restore(); - } - if (element.kind === "note") { - ctx.fillStyle = timeline.hover?.id === element.id ? "#f88" : "#f00"; - ctx.beginPath(); - ctx.roundRect(element.rect.x, element.rect.y, element.rect.w, element.rect.h, timeline.noteRowH / 4); - ctx.fill(); - if (element.id !== undefined && timeline.selection.has(element.id)) { - ctx.strokeStyle = "#fbb"; - ctx.lineWidth = 4; - ctx.stroke(); - } - } - } -} -function drawLaneBkgCenterStroke(timeline, ctx, lane) { - const yCenter = Math.floor(lane.rect.y + lane.rect.h / 2) + 0.5; - ctx.strokeStyle = "#fff"; - ctx.lineWidth = 2; - ctx.beginPath(); - ctx.moveTo(lane.rect.x, yCenter); - ctx.lineTo(lane.rect.x + lane.rect.w, yCenter); - ctx.stroke(); -} -function drawLaneBkgSolid(timeline, ctx, lane) { - ctx.fillStyle = "#eee"; - ctx.fillRect(lane.rect.x, lane.rect.y, lane.rect.w, lane.rect.h); -} -function drawLaneFrgOutline(timeline, ctx, lane) { - ctx.strokeStyle = "#000"; - ctx.lineWidth = 1; - ctx.beginPath(); - ctx.moveTo(lane.rect.x, lane.rect.y); - ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y); - ctx.moveTo(lane.rect.x, lane.rect.y + lane.rect.h); - ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y + lane.rect.h); - ctx.stroke(); -} -function drawLaneBkgMeasures(timeline, ctx, lane, mainLinePass) { - // Render alternating measure background and sub-measure dividers. - const measureHalfH = lane.rect.h / 2; - const submeasureHalfH = lane.rect.h / 2; - for (const measure of timeline.layout.measures) { - const x1 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time1)); - const x2 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time2)); - const submeasureSize = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](1, measure.meterCh.meter.denominator)) - _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_3__["default"](0)); - if (mainLinePass) { - ctx.strokeStyle = "#444"; - ctx.lineWidth = 2; - ctx.beginPath(); - ctx.moveTo(x1 + 0.5, lane.rect.y); - ctx.lineTo(x1 + 0.5, lane.rect.y + lane.rect.h); - ctx.stroke(); - } - if (!mainLinePass && submeasureSize > 8) { - ctx.strokeStyle = "#fff"; - ctx.lineWidth = 1; - ctx.beginPath(); - for (let n = 1; n < measure.meterCh.meter.numerator; n++) { - const submeasureX = x1 + Math.round(submeasureSize * n); - if (submeasureX >= x2) break; - ctx.moveTo(submeasureX, lane.rect.y); - ctx.lineTo(submeasureX, lane.rect.y + lane.rect.h); - } - ctx.stroke(); - } - } -} -function drawLaneBkgOctaves(timeline, ctx, lane, mainLinePass) { - const rowAtTop = _index_ts__WEBPACK_IMPORTED_MODULE_1__.rowAtY(timeline, lane, lane.rect.y); - const rowAtBottom = _index_ts__WEBPACK_IMPORTED_MODULE_1__.rowAtY(timeline, lane, lane.rect.y + lane.rect.h); - const octaveAtTop = Math.ceil(rowAtTop / 7) + 1; - const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1; - ctx.fillStyle = "#444"; - ctx.font = Math.floor(timeline.noteRowH - 4) + "px system-ui"; - ctx.textAlign = "left"; - ctx.textBaseline = "bottom"; - for (const keyRegion of timeline.layout.keyRegions) { - const tonicRowOffset = _theory__WEBPACK_IMPORTED_MODULE_2__.Utils.chromaToDegreeInCMajor(keyRegion.keyCh1.key.tonic.chroma); - let needsOctaveLabels = true; - let drewOctaveLabels = false; - for (const measure of timeline.layout.measures) { - /*if (measure.time1.lessThan(keyRegion.keyCh1.range.start) || - measure.time2.greaterThan(keyRegion.keyCh2.range.start)) - continue*/ - - const x1 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time1)); - const x2 = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, measure.time2)); - for (let i = octaveAtBottom; i <= octaveAtTop; i++) { - const y = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.yForRow(timeline, lane, tonicRowOffset + i * 7) + timeline.noteRowH); - if (mainLinePass) { - const labelX = Math.max(x1 + 5, 5); - if (needsOctaveLabels && labelX + 30 < x2) { - ctx.fillText(keyRegion.keyCh1.key.tonic.str + (i + 5).toString(), labelX, y - 1); - drewOctaveLabels = true; - } - ctx.strokeStyle = "#444"; - ctx.beginPath(); - ctx.moveTo(x1, y); - ctx.lineTo(x2, y); - ctx.moveTo(x1, y + 1); - ctx.lineTo(x2, y + 1); - ctx.stroke(); - } - if (!mainLinePass) { - ctx.strokeStyle = "#fff"; - ctx.beginPath(); - for (let j = 1; j < 7; j += 1) { - const ySuboctave = Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.yForRow(timeline, lane, tonicRowOffset + i * 7 + j) + timeline.noteRowH); - ctx.moveTo(x1, ySuboctave); - ctx.lineTo(x2, ySuboctave); - } - ctx.stroke(); - } - } - if (drewOctaveLabels) needsOctaveLabels = false; - } - } -} -function drawCursorBeam(timeline, ctx, time, tipOffsetSide) { - const prefs = _state_ts__WEBPACK_IMPORTED_MODULE_0__.get().prefs; - const laneIndexMin = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMin(timeline); - const laneIndexMax = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMax(timeline); - const laneMin = timeline.layout.lanes[laneIndexMin]; - const laneMax = timeline.layout.lanes[laneIndexMax]; - const x = 0.5 + Math.floor(_index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, time)); - ctx.strokeStyle = prefs.timeline.selectionCursorColor; - ctx.fillStyle = prefs.timeline.selectionCursorColor; - ctx.lineCap = "square"; - ctx.lineWidth = 2; - const headYSize = 10; - const headXSize = headYSize * (tipOffsetSide ? -1 : 1); - const y1 = Math.floor(laneMin.rect.y); - const y2 = Math.floor(laneMax.rect.y2); - ctx.beginPath(); - ctx.moveTo(x, y1 + headYSize); - ctx.lineTo(x + headXSize, y1); - ctx.lineTo(x, y1); - ctx.fill(); - ctx.beginPath(); - ctx.moveTo(x, y2 - headYSize); - ctx.lineTo(x + headXSize, y2); - ctx.lineTo(x, y2); - ctx.fill(); - ctx.beginPath(); - ctx.moveTo(x, y1 + 1); - ctx.lineTo(x, y2 - 1); - ctx.stroke(); -} -function drawCursorBkg(timeline, ctx, lane) { - if (!timeline.cursor.visible) return; - const prefs = _state_ts__WEBPACK_IMPORTED_MODULE_0__.get().prefs; - const timeMin = timeline.cursor.time1.min(timeline.cursor.time2); - const timeMax = timeline.cursor.time1.max(timeline.cursor.time2); - const laneIndexMin = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMin(timeline); - const laneIndexMax = _index_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMax(timeline); - if (laneIndexMin > lane.laneIndex || laneIndexMax < lane.laneIndex) return; - const y1 = Math.floor(lane.rect.y); - const y2 = Math.floor(lane.rect.y2); - const x1 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, timeMin); - const x2 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, timeMax); - ctx.fillStyle = prefs.timeline.selectionBkgColor; - ctx.fillRect(x1, y1, x2 - x1, y2 - y1); -} - -/***/ }), - -/***/ "./src/timeline/index.ts": -/*!*******************************!*\ - !*** ./src/timeline/index.ts ***! - \*******************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Element: () => (/* reexport safe */ _Element_tsx__WEBPACK_IMPORTED_MODULE_0__.Element), -/* harmony export */ Layout: () => (/* reexport safe */ _layout_ts__WEBPACK_IMPORTED_MODULE_2__.Layout), -/* harmony export */ MouseAction: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction), -/* harmony export */ cursorGetLaneIndexMax: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMax), -/* harmony export */ cursorGetLaneIndexMin: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorGetLaneIndexMin), -/* harmony export */ cursorSetTime: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorSetTime), -/* harmony export */ cursorSetTrack: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.cursorSetTrack), -/* harmony export */ draw: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.draw), -/* harmony export */ drawLaneBkgCenterStroke: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgCenterStroke), -/* harmony export */ drawLaneBkgMeasures: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgMeasures), -/* harmony export */ drawLaneBkgOctaves: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgOctaves), -/* harmony export */ drawLaneBkgSolid: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneBkgSolid), -/* harmony export */ drawLaneFrgOutline: () => (/* reexport safe */ _draw_ts__WEBPACK_IMPORTED_MODULE_11__.drawLaneFrgOutline), -/* harmony export */ keyDown: () => (/* reexport safe */ _key_down_ts__WEBPACK_IMPORTED_MODULE_9__.keyDown), -/* harmony export */ keyUp: () => (/* reexport safe */ _key_up_ts__WEBPACK_IMPORTED_MODULE_10__.keyUp), -/* harmony export */ laneIndexAtY: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.laneIndexAtY), -/* harmony export */ layout: () => (/* reexport safe */ _layout_ts__WEBPACK_IMPORTED_MODULE_2__.layout), -/* harmony export */ layoutLaneNotes: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.layoutLaneNotes), -/* harmony export */ makeNew: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.makeNew), -/* harmony export */ mouseDown: () => (/* reexport safe */ _mouse_down_ts__WEBPACK_IMPORTED_MODULE_5__.mouseDown), -/* harmony export */ mouseDrag: () => (/* reexport safe */ _mouse_drag_ts__WEBPACK_IMPORTED_MODULE_6__.mouseDrag), -/* harmony export */ mouseMove: () => (/* reexport safe */ _mouse_move_ts__WEBPACK_IMPORTED_MODULE_4__.mouseMove), -/* harmony export */ mouseUp: () => (/* reexport safe */ _mouse_up_ts__WEBPACK_IMPORTED_MODULE_7__.mouseUp), -/* harmony export */ mouseWheel: () => (/* reexport safe */ _mouse_wheel_ts__WEBPACK_IMPORTED_MODULE_8__.mouseWheel), -/* harmony export */ pitchForRow: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.pitchForRow), -/* harmony export */ pointAt: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.pointAt), -/* harmony export */ resize: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.resize), -/* harmony export */ rowAtY: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.rowAtY), -/* harmony export */ rowForPitch: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.rowForPitch), -/* harmony export */ selectionAdd: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionAdd), -/* harmony export */ selectionAddAtCursor: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionAddAtCursor), -/* harmony export */ selectionClear: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionClear), -/* harmony export */ selectionRange: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionRange), -/* harmony export */ selectionToggle: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.selectionToggle), -/* harmony export */ timeAtX: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.timeAtX), -/* harmony export */ timeRangeAtX: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.timeRangeAtX), -/* harmony export */ visibleTimeRange: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.visibleTimeRange), -/* harmony export */ xAtTime: () => (/* reexport safe */ _timeline_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime), -/* harmony export */ yForRow: () => (/* reexport safe */ _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__.yForRow) -/* harmony export */ }); -/* harmony import */ var _Element_tsx__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Element.tsx */ "./src/timeline/Element.tsx"); -/* harmony import */ var _timeline_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./timeline.ts */ "./src/timeline/timeline.ts"); -/* harmony import */ var _layout_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./layout.ts */ "./src/timeline/layout.ts"); -/* harmony import */ var _layout_notes_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./layout_notes.ts */ "./src/timeline/layout_notes.ts"); -/* harmony import */ var _mouse_move_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./mouse_move.ts */ "./src/timeline/mouse_move.ts"); -/* harmony import */ var _mouse_down_ts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mouse_down.ts */ "./src/timeline/mouse_down.ts"); -/* harmony import */ var _mouse_drag_ts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./mouse_drag.ts */ "./src/timeline/mouse_drag.ts"); -/* harmony import */ var _mouse_up_ts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./mouse_up.ts */ "./src/timeline/mouse_up.ts"); -/* harmony import */ var _mouse_wheel_ts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./mouse_wheel.ts */ "./src/timeline/mouse_wheel.ts"); -/* harmony import */ var _key_down_ts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./key_down.ts */ "./src/timeline/key_down.ts"); -/* harmony import */ var _key_up_ts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./key_up.ts */ "./src/timeline/key_up.ts"); -/* harmony import */ var _draw_ts__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./draw.ts */ "./src/timeline/draw.ts"); - - - - - - - - - - - - - -/***/ }), - -/***/ "./src/timeline/key_down.ts": -/*!**********************************!*\ - !*** ./src/timeline/key_down.ts ***! - \**********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ keyDown: () => (/* binding */ keyDown) -/* harmony export */ }); -function keyDown(timeline, key) { - timeline.keysDown.add(key); -} - -/***/ }), - -/***/ "./src/timeline/key_up.ts": -/*!********************************!*\ - !*** ./src/timeline/key_up.ts ***! - \********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ keyUp: () => (/* binding */ keyUp) -/* harmony export */ }); -function keyUp(timeline, key) { - timeline.keysDown.delete(key); -} - -/***/ }), - -/***/ "./src/timeline/layout.ts": -/*!********************************!*\ - !*** ./src/timeline/layout.ts ***! - \********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Layout: () => (/* binding */ Layout), -/* harmony export */ layout: () => (/* binding */ layout) -/* harmony export */ }); -/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../project */ "./src/project/index.ts"); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); - - - -class Layout { - lanes = []; - elements = []; - elementCount = 0; - measures = []; - keyRegions = []; - constructor() {} - add(parent, elem) { - this.elementCount++; - if (parent !== undefined) { - if (parent.subElements === undefined) parent.subElements = []; - parent.subElements.push(elem); - } else { - this.elements.push(elem); - if (elem.kind === "lane" || elem.kind === "laneNotes") this.lanes.push(elem); - } - } -} -function layout(timeline, project) { - const layout = new Layout(); - layout.range = _index_ts__WEBPACK_IMPORTED_MODULE_1__.visibleTimeRange(timeline); - layout.measures = [..._project__WEBPACK_IMPORTED_MODULE_0__.iterMeasuresAtRange(project, layout.range)]; - layout.keyRegions = [...iterKeyChangePairsAtRange(timeline, project, layout.range)]; - const laneMarkerH = 32; - const laneChordH = 60; - const laneMarginH = 8; - const laneKeyChanges = { - kind: "lane", - laneIndex: 0, - rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, 0, timeline.renderRect.w, laneMarkerH) - }; - const laneMeterChanges = { - kind: "lane", - laneIndex: 1, - rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, laneMarkerH + laneMarginH, timeline.renderRect.w, laneMarkerH) - }; - const laneChords = { - kind: "lane", - laneIndex: 2, - rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, laneMarkerH + laneMarginH + laneMarkerH + laneMarginH, timeline.renderRect.w, laneChordH) - }; - const laneNotesY = laneMarkerH + laneMarginH + laneMarkerH + laneMarginH + laneChordH + laneMarginH; - const laneNotes = { - kind: "laneNotes", - laneIndex: 3, - rect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0, laneNotesY, timeline.renderRect.w, timeline.renderRect.h - laneNotesY) - }; - layout.add(undefined, laneKeyChanges); - layout.add(undefined, laneMeterChanges); - layout.add(undefined, laneChords); - layout.add(undefined, laneNotes); - layout.laneNotes = laneNotes; - _index_ts__WEBPACK_IMPORTED_MODULE_1__.layoutLaneNotes(timeline, project, layout, laneNotes); - timeline.layout = layout; - console.log(layout.elementCount, layout); -} -function* iterKeyChangePairsAtRange(timeline, project, range) { - const keyChangeTrackId = _project__WEBPACK_IMPORTED_MODULE_0__.keyChangeTrackId(project); - const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId); - if (!keyChangeTrackTimedElems) return; - const firstKeyCh = keyChangeTrackTimedElems.findFirst(); - const defaultKey = firstKeyCh?.key ?? _project__WEBPACK_IMPORTED_MODULE_0__.defaultKey(); - for (const pair of keyChangeTrackTimedElems.iterActiveAtRangePairwise(range)) { - const keyCh1 = pair[0] ?? _project__WEBPACK_IMPORTED_MODULE_0__.makeKeyChange(-1, range.start, defaultKey); - const keyCh2 = pair[1] ?? _project__WEBPACK_IMPORTED_MODULE_0__.makeKeyChange(-1, range.end, defaultKey); - const x1 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, keyCh1.range.start); - const x2 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, keyCh2.range.start); - yield { - keyCh1, - keyCh2, - x1, - x2 - }; - } -} - -/***/ }), - -/***/ "./src/timeline/layout_notes.ts": -/*!**************************************!*\ - !*** ./src/timeline/layout_notes.ts ***! - \**************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ layoutLaneNotes: () => (/* binding */ layoutLaneNotes), -/* harmony export */ pitchForRow: () => (/* binding */ pitchForRow), -/* harmony export */ rowAtY: () => (/* binding */ rowAtY), -/* harmony export */ rowForPitch: () => (/* binding */ rowForPitch), -/* harmony export */ yForRow: () => (/* binding */ yForRow) -/* harmony export */ }); -/* harmony import */ var _theory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../theory */ "./src/theory/index.ts"); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); -/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); - - - - -function layoutLaneNotes(timeline, project, layout, laneNotes) { - laneNotes.iterElementsAtRegion = (timeline, project, range, verticalRegion) => iterNotesAtRegion(timeline, project, laneNotes, range, verticalRegion); - for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, layout)) { - const key = keyChPair.keyCh1.key; - const row = rowForPitch(note.midiPitch, key); - const [rect, cutStart, cutEnd] = rectForNote(timeline, laneNotes, note.range, row, keyChPair.x1, keyChPair.x2, true); - if (!cutStart) { - const rectStretchStart = rect.withX1(rect.x1 - 8); - layout.add(laneNotes, { - kind: "hidden", - id: note.id, - action: _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeStart, - rect: rectStretchStart - }); - } - if (!cutEnd) { - const rectStretchEnd = rect.withX2(rect.x2 + 8); - layout.add(laneNotes, { - kind: "hidden", - id: note.id, - action: _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeEnd, - rect: rectStretchEnd - }); - } - layout.add(laneNotes, { - kind: "note", - id: note.id, - action: _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow, - rect, - priority: 1 - }); - } -} -function* iterNotesAndKeyChanges(timeline, project, layout) { - for (const keyRegion of layout.keyRegions) { - const time1 = keyRegion.keyCh1.range.start.max(layout.range.start); - const time2 = keyRegion.keyCh2.range.start.min(layout.range.end); - for (const note of iterNotes(timeline, project, new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](time1, time2))) yield [note, keyRegion]; - } -} -function* iterNotes(timeline, project, range) { - const list = project.lists.get(project.noteTrackId); - if (!list) return; - for (const elem of list.iterAtRange(range)) yield elem; -} -function rowForPitch(pitch, key) { - const tonicRowOffset = _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.chromaToDegreeInCMajor(key.tonic.chroma); - return key.octavedDegreeForMidi(pitch - _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.midiMiddleC) + tonicRowOffset; -} -function pitchForRow(row, key) { - const tonicRowOffset = _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.chromaToDegreeInCMajor(key.tonic.chroma); - return key.midiForDegree(row - Math.floor(tonicRowOffset)) + _theory__WEBPACK_IMPORTED_MODULE_0__.Utils.midiMiddleC; -} -function yForRow(timeline, lane, row) { - return lane.rect.y + lane.rect.h / 2 - (row + 1) * timeline.noteRowH - timeline.yScroll; -} -function rowAtY(timeline, lane, y) { - return -Math.floor((y - lane.rect.y + timeline.yScroll - lane.rect.h / 2) / timeline.noteRowH) - 1; -} -function rectForNote(timeline, lane, noteRange, noteRow, keyChXStart, keyChXEnd, clampY) { - const noteOrigX1 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, noteRange.start); - const noteOrigX2 = _index_ts__WEBPACK_IMPORTED_MODULE_1__.xAtTime(timeline, noteRange.end); - let noteY = 0.5 + Math.floor(yForRow(timeline, lane, noteRow)); - if (clampY) { - noteY = Math.max(lane.rect.y - timeline.noteRowH / 2, Math.min(lane.rect.y + lane.rect.h - timeline.noteRowH / 2, noteY)); - } - let noteX1 = Math.max(noteOrigX1, keyChXStart); - let noteX2 = Math.min(noteOrigX2, keyChXEnd); - const cutStart = noteOrigX1 < noteX1; - const cutEnd = noteOrigX2 > noteX2; - - //if (!cutStart) noteX1 += 1 - //if (!cutEnd) noteX2 -= 1 - - noteX1 = 0.5 + Math.floor(noteX1); - noteX2 = 0.5 + Math.floor(noteX2); - const noteW = Math.max(2, noteX2 - noteX1); - return [new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_2__["default"](noteX1, noteY, noteW, timeline.noteRowH), cutStart, cutEnd]; -} -function* iterNotesAtRegion(timeline, project, lane, range, verticalRegion) { - for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, timeline.layout)) { - if (!note.range.overlapsRange(range)) continue; - if (verticalRegion !== undefined) { - const [rect] = rectForNote(timeline, lane, note.range, rowForPitch(note.midiPitch, keyChPair.keyCh1.key), keyChPair.x1, keyChPair.x2, false); - if (verticalRegion.y1 > rect.y2 || verticalRegion.y2 < rect.y1) continue; - } - yield note.id; - } -} - -/***/ }), - -/***/ "./src/timeline/mouse_down.ts": -/*!************************************!*\ - !*** ./src/timeline/mouse_down.ts ***! - \************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ mouseDown: () => (/* binding */ mouseDown) -/* harmony export */ }); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); - - -function mouseDown(timeline, project, prefs, rightButton) { - if (timeline.mouse.down) return; - const prevDownDate = timeline.mouse.downDate; - timeline.mouse.down = true; - timeline.mouse.downDate = new Date(); - timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.None; - const selectMultiple = timeline.keysDown.has(prefs.timeline.keySelectMultiple); - const selectRange = timeline.keysDown.has(prefs.timeline.keySelectRange); - const selectClone = timeline.keysDown.has(prefs.timeline.keySelectClone); - const selectRect = timeline.keysDown.has(prefs.timeline.keySelectRect); - const forcePan = timeline.keysDown.has(prefs.timeline.keyPan); - const doubleClick = timeline.mouse.downDate.getTime() - prevDownDate.getTime() < prefs.timeline.mouseDoubleClickThresholdMs; - timeline.drag = { - origin: { - point: { - ...timeline.mouse.point - }, - range: null, - timeScroll: timeline.timeScroll, - yScroll: timeline.yScroll, - project - }, - xLocked: true, - yLocked: true, - posDelta: { - x: 0, - y: 0 - }, - timeDelta: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](0), - rowDelta: 0, - trackDelta: 0, - trackInsertionBefore: -1, - elemId: -1, - notePreviewLast: null - }; - if (rightButton || forcePan) { - timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.Pan; - return; - } - const hoverIsSelected = timeline.hover !== undefined && timeline.hover.id !== undefined && timeline.selection.has(timeline.hover.id); - if (!selectMultiple && !hoverIsSelected) _index_ts__WEBPACK_IMPORTED_MODULE_0__.selectionClear(timeline); - if (timeline.hover === undefined || timeline.hover.action === undefined) { - timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.SelectCursor; - timeline.cursor.visible = true; //!selectRect - _index_ts__WEBPACK_IMPORTED_MODULE_0__.cursorSetTime(timeline, timeline.mouse.point.time, timeline.mouse.point.time); - timeline.cursor.rectY1 = timeline.cursor.rectY2 = timeline.mouse.point.trackPos.y; - timeline.cursor.laneIndex1 = timeline.cursor.laneIndex2 = timeline.mouse.point.laneIndex; - - /*if (doubleClick) - { - const anchor = Timeline.findPreviousAnchor( - timeline, timeline.mouse.point.time, - timeline.mouse.point.trackIndex, timeline.mouse.point.trackIndex) - - Timeline.cursorSetTime(timeline, anchor, anchor) - Timeline.scrollTimeIntoView(timeline, anchor) - }*/ - - return; - } - if (timeline.hover !== undefined) { - timeline.cursor.visible = false; - if (!hoverIsSelected) _index_ts__WEBPACK_IMPORTED_MODULE_0__.selectionToggle(timeline, project, timeline.hover); - timeline.drag.origin.range = _index_ts__WEBPACK_IMPORTED_MODULE_0__.selectionRange(timeline, project); - timeline.mouse.action = timeline.hover.action; - return; - } -} - -/***/ }), - -/***/ "./src/timeline/mouse_drag.ts": -/*!************************************!*\ - !*** ./src/timeline/mouse_drag.ts ***! - \************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ mouseDrag: () => (/* binding */ mouseDrag) -/* harmony export */ }); -/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../project */ "./src/project/index.ts"); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); - - - -function mouseDrag(timeline, project) { - if (!timeline.mouse.down) return false; - timeline.mouse.pointPrev = timeline.mouse.point; - timeline.mouse.point = _index_ts__WEBPACK_IMPORTED_MODULE_1__.pointAt(timeline, timeline.mouse.point.pos.x, timeline.mouse.point.pos.y); - timeline.drag.posDelta = { - x: timeline.mouse.point.pos.x - timeline.drag.origin.point.pos.x, - y: timeline.mouse.point.pos.y - timeline.drag.origin.point.pos.y - }; - timeline.drag.timeDelta = timeline.mouse.point.time.subtract(timeline.drag.origin.point.time); - timeline.drag.rowDelta = timeline.mouse.point.row - timeline.drag.origin.point.row; - timeline.drag.xLocked = timeline.drag.xLocked && Math.abs(timeline.drag.posDelta.x) < 10; - timeline.drag.yLocked = timeline.drag.yLocked && Math.abs(timeline.drag.posDelta.y) < 10; - if (timeline.mouse.action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.Pan) return handlePanning(timeline, project);else if (timeline.mouse.action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.SelectCursor) return handleSelectCursor(timeline, project);else return handleDragElements(timeline, project); -} -function handlePanning(timeline, project) { - timeline.timeScroll = timeline.drag.origin.timeScroll - timeline.drag.posDelta.x / timeline.timeScale; - timeline.yScroll = timeline.drag.origin.yScroll - timeline.drag.posDelta.y; - return true; -} -function handleSelectCursor(timeline, project) { - timeline.cursor.time2 = timeline.mouse.point.time; - timeline.cursor.laneIndex2 = timeline.mouse.point.laneIndex; - _index_ts__WEBPACK_IMPORTED_MODULE_1__.selectionClear(timeline); - _index_ts__WEBPACK_IMPORTED_MODULE_1__.selectionAddAtCursor(timeline, project.root); - return true; -} -function handleDragElements(timeline, project) { - let action = timeline.mouse.action; - if (timeline.drag.xLocked) { - if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTime || action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeStart || action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeEnd) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.None;else if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragRow; - } - if (timeline.drag.yLocked) { - if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTime;else if (action === _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragRow) action = _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.None; - } - const origProject = timeline.drag.origin.project; - let newProject = origProject; - for (const id of timeline.selection) { - const elem = origProject.elems.get(id); - if (!elem) continue; - if (elem.type === "track") continue; - const changes = {}; - if (action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTime || action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) { - changes.range = elem.range.displace(timeline.drag.timeDelta).quantize(_project__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR); - } - if (action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeStart && timeline.drag.origin.range) { - changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange(origProject, elem.parentId, elem.range); - changes.range = changes.range.stretch(timeline.drag.timeDelta, timeline.drag.origin.range.end, timeline.drag.origin.range.start); - if (elem.range.start.compare(timeline.drag.origin.range.start) == 0) changes.range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](changes.range.start.snap(timeline.timeSnap), changes.range.end).quantize(_project__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR); - changes.range = changes.range.sorted(); - changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getRelativeRange(origProject, elem.parentId, changes.range); - } - if (action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.StretchTimeEnd && timeline.drag.origin.range) { - changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getAbsoluteRange(origProject, elem.parentId, elem.range); - changes.range = changes.range.stretch(timeline.drag.timeDelta, timeline.drag.origin.range.start, timeline.drag.origin.range.end); - if (elem.range.end.compare(timeline.drag.origin.range.end) == 0) changes.range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](changes.range.start, changes.range.end.snap(timeline.timeSnap)).quantize(_project__WEBPACK_IMPORTED_MODULE_0__.MAX_RATIONAL_DENOMINATOR); - changes.range = changes.range.sorted(); - changes.range = _project__WEBPACK_IMPORTED_MODULE_0__.getRelativeRange(origProject, elem.parentId, changes.range); - } - if ((action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragRow || action == _index_ts__WEBPACK_IMPORTED_MODULE_1__.MouseAction.DragTimeAndRow) && elem.type === "note") { - const note = elem; - const trackId = project.root.noteTrackId; - const key = _project__WEBPACK_IMPORTED_MODULE_0__.keyAt(project.root, trackId, note.range.start); - const degree = key.octavedDegreeForMidi(note.midiPitch); - const newPitch = key.midiForDegree(Math.floor(degree + timeline.drag.rowDelta)); - changes.midiPitch = newPitch; - } - newProject = _project__WEBPACK_IMPORTED_MODULE_0__.upsertElement(newProject, _project__WEBPACK_IMPORTED_MODULE_0__.elemModify(elem, changes)); - } - project.root = newProject; - return newProject !== origProject; -} - -/***/ }), - -/***/ "./src/timeline/mouse_move.ts": -/*!************************************!*\ - !*** ./src/timeline/mouse_move.ts ***! - \************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ mouseMove: () => (/* binding */ mouseMove) -/* harmony export */ }); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); - -function mouseMove(timeline, project, x, y) { - timeline.mouse.point = _index_ts__WEBPACK_IMPORTED_MODULE_0__.pointAt(timeline, x, y); - if (!timeline.mouse.down) { - timeline.hover = undefined; - hoverRecursive(timeline, timeline.layout.elements, x, y); - } -} -function hoverRecursive(timeline, elements, x, y) { - for (const elem of elements) { - if (x >= elem.rect.x && x < elem.rect.x + elem.rect.w && y >= elem.rect.y && y < elem.rect.y + elem.rect.h) { - if (timeline.hover === undefined || (elem.priority ?? 0) >= (timeline.hover.priority ?? 0)) timeline.hover = elem; - if (elem.subElements) hoverRecursive(timeline, elem.subElements, x, y); - } - } -} - -/***/ }), - -/***/ "./src/timeline/mouse_up.ts": -/*!**********************************!*\ - !*** ./src/timeline/mouse_up.ts ***! - \**********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ mouseUp: () => (/* binding */ mouseUp) -/* harmony export */ }); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); - -function mouseUp(timeline, project, rightButton) { - if (!timeline.mouse.down) return; - timeline.mouse.down = false; - timeline.mouse.action = _index_ts__WEBPACK_IMPORTED_MODULE_0__.MouseAction.None; -} - -/***/ }), - -/***/ "./src/timeline/mouse_wheel.ts": -/*!*************************************!*\ - !*** ./src/timeline/mouse_wheel.ts ***! - \*************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ mouseWheel: () => (/* binding */ mouseWheel) -/* harmony export */ }); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); - - -function mouseWheel(timeline, deltaX, deltaY) { - if (Math.abs(deltaX) > 0) { - timeline.timeScroll = timeline.timeScroll + 0.01 / (timeline.timeScale / 100) * deltaX; - timeline.mouse.wheelDate = new Date(); - } else if (new Date().getTime() - timeline.mouse.wheelDate.getTime() > 250) { - const snap = new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](1, 1024); - const prevMouseTime = _index_ts__WEBPACK_IMPORTED_MODULE_0__.timeAtX(timeline, timeline.mouse.point.pos.x, snap); - let newTimeScale = timeline.timeScale * (deltaY > 0 ? 0.8 : 1.25); - newTimeScale = Math.max(4, Math.min(2048, newTimeScale)); - timeline.timeScale = newTimeScale; - const newMouseTime = _index_ts__WEBPACK_IMPORTED_MODULE_0__.timeAtX(timeline, timeline.mouse.point.pos.x, snap); - const newTimeScroll = timeline.timeScroll - newMouseTime.subtract(prevMouseTime).asFloat(); - const timeSnapAdjustThresholdUpper = 24; - const timeSnapAdjustThresholdLower = 8; - let newTimeSnap = timeline.timeSnapBase; - if (newTimeSnap.asFloat() * newTimeScale > timeSnapAdjustThresholdUpper) while (newTimeSnap.asFloat() * newTimeScale > timeSnapAdjustThresholdUpper) newTimeSnap = newTimeSnap.divide(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](2));else if (newTimeSnap.asFloat() * newTimeScale < timeSnapAdjustThresholdLower) while (newTimeSnap.asFloat() * newTimeScale < timeSnapAdjustThresholdLower) newTimeSnap = newTimeSnap.divide(new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](1, 2)); - timeline.timeScroll = newTimeScroll; - timeline.timeSnap = newTimeSnap; - } -} - -/***/ }), - -/***/ "./src/timeline/timeline.ts": -/*!**********************************!*\ - !*** ./src/timeline/timeline.ts ***! - \**********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ MouseAction: () => (/* binding */ MouseAction), -/* harmony export */ cursorGetLaneIndexMax: () => (/* binding */ cursorGetLaneIndexMax), -/* harmony export */ cursorGetLaneIndexMin: () => (/* binding */ cursorGetLaneIndexMin), -/* harmony export */ cursorSetTime: () => (/* binding */ cursorSetTime), -/* harmony export */ cursorSetTrack: () => (/* binding */ cursorSetTrack), -/* harmony export */ laneIndexAtY: () => (/* binding */ laneIndexAtY), -/* harmony export */ makeNew: () => (/* binding */ makeNew), -/* harmony export */ pointAt: () => (/* binding */ pointAt), -/* harmony export */ resize: () => (/* binding */ resize), -/* harmony export */ selectionAdd: () => (/* binding */ selectionAdd), -/* harmony export */ selectionAddAtCursor: () => (/* binding */ selectionAddAtCursor), -/* harmony export */ selectionClear: () => (/* binding */ selectionClear), -/* harmony export */ selectionRange: () => (/* binding */ selectionRange), -/* harmony export */ selectionToggle: () => (/* binding */ selectionToggle), -/* harmony export */ timeAtX: () => (/* binding */ timeAtX), -/* harmony export */ timeRangeAtX: () => (/* binding */ timeRangeAtX), -/* harmony export */ visibleTimeRange: () => (/* binding */ visibleTimeRange), -/* harmony export */ xAtTime: () => (/* binding */ xAtTime) -/* harmony export */ }); -/* harmony import */ var immutable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! immutable */ "./node_modules/immutable/dist/immutable.es.js"); -/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../project */ "./src/project/index.ts"); -/* harmony import */ var _index_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.ts */ "./src/timeline/index.ts"); -/* harmony import */ var _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rational.ts */ "./src/utils/rational.ts"); -/* harmony import */ var _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/range.ts */ "./src/utils/range.ts"); -/* harmony import */ var _utils_rect_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/rect.ts */ "./src/utils/rect.ts"); - - - - - - -let MouseAction = /*#__PURE__*/function (MouseAction) { - MouseAction[MouseAction["None"] = 0] = "None"; - MouseAction[MouseAction["Pan"] = 1] = "Pan"; - MouseAction[MouseAction["DragTime"] = 2] = "DragTime"; - MouseAction[MouseAction["DragRow"] = 3] = "DragRow"; - MouseAction[MouseAction["DragTimeAndRow"] = 4] = "DragTimeAndRow"; - MouseAction[MouseAction["StretchTimeStart"] = 5] = "StretchTimeStart"; - MouseAction[MouseAction["StretchTimeEnd"] = 6] = "StretchTimeEnd"; - MouseAction[MouseAction["SelectCursor"] = 7] = "SelectCursor"; - return MouseAction; -}({}); -function makeNew() { - return { - pixelRatio: 1, - renderRect: new _utils_rect_ts__WEBPACK_IMPORTED_MODULE_4__["default"](0, 0, 0, 0), - trackMeasuresH: 20, - trackControlX: 10, - trackControlY: 25, - trackControlSize: 20, - layout: new _index_ts__WEBPACK_IMPORTED_MODULE_1__.Layout(), - hover: undefined, - yScroll: 0, - timeScroll: -2.5, - timeScale: 100, - timeSnap: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](1, 8), - timeSnapBase: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](1, 16), - noteRowH: 16, - cursor: { - visible: true, - time1: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), - time2: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), - laneIndex1: 0, - laneIndex2: 0, - rectY1: 0, - rectY2: 0 - }, - keysDown: new Set(), - mouse: { - down: false, - downDate: new Date(), - action: MouseAction.None, - point: { - pos: { - x: 0, - y: 0 - }, - time: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), - row: 0, - laneIndex: 0, - trackPos: { - x: 0, - y: 0 - }, - originTrackPos: { - x: 0, - y: 0 - } - }, - pointPrev: { - pos: { - x: 0, - y: 0 - }, - time: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), - row: 0, - laneIndex: 0, - trackPos: { - x: 0, - y: 0 - }, - originTrackPos: { - x: 0, - y: 0 - } - }, - wheelDate: new Date() - }, - drag: { - origin: null, - xLocked: true, - yLocked: true, - posDelta: { - x: 0, - y: 0 - }, - timeDelta: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](0), - rowDelta: 0, - trackDelta: 0, - trackInsertionBefore: -1, - elemId: -1, - notePreviewLast: null - }, - insertion: { - nearMidiPitch: 60, - duration: new _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"](1, 4) - }, - selection: immutable__WEBPACK_IMPORTED_MODULE_5__["default"].Set(), - needsKeyFinish: false, - rangeSelectOriginTrackIndex: -1 - }; -} -function resize(state, pixelRatio, rect) { - state.pixelRatio = pixelRatio; - state.renderRect = rect; -} -function xAtTime(timeline, time) { - return (time.asFloat() - timeline.timeScroll) * timeline.timeScale; -} -function timeAtX(timeline, x, timeSnap) { - timeSnap = timeSnap || timeline.timeSnap; - const time = x / timeline.timeScale + timeline.timeScroll; - return _utils_rational_ts__WEBPACK_IMPORTED_MODULE_2__["default"].fromFloat(time, timeSnap.denominator); -} -function timeRangeAtX(timeline, x1, x2, timeSnap) { - timeSnap = timeSnap || timeline.timeSnap; - return new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](timeAtX(timeline, x1, timeSnap).subtract(timeSnap), timeAtX(timeline, x2, timeSnap).add(timeSnap)); -} -function visibleTimeRange(timeline) { - return new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](timeAtX(timeline, 0).subtract(timeline.timeSnap), timeAtX(timeline, timeline.renderRect.w).add(timeline.timeSnap)); -} -function laneIndexAtY(timeline, y) { - if (y < 0) return -1; - for (let i = 0; i < timeline.layout.lanes.length; i++) { - const lane = timeline.layout.lanes[i]; - if (y < lane.rect.y2) return i; - } - return timeline.layout.lanes.length; -} -function pointAt(timeline, x, y) { - const time = timeAtX(timeline, x); - const row = timeline.layout.laneNotes ? _index_ts__WEBPACK_IMPORTED_MODULE_1__.rowAtY(timeline, timeline.layout.laneNotes, y) : 0; - const laneIndex = laneIndexAtY(timeline, y); - - /*const trackPosY = pos.y - trackY(state, state.mouse.point.trackIndex) - const trackPos = { x: pos.x, y: trackPosY } - let originTrackPos = trackPos - if (state.drag.origin) - { - const originTrackPosY = pos.y - trackY(state, state.drag.origin.point.trackIndex) - originTrackPos = { x: pos.x, y: originTrackPosY } - }*/ - - return { - pos: { - x, - y - }, - time, - laneIndex, - trackPos: { - x: 0, - y: 0 - }, - row, - originTrackPos: { - x: 0, - y: 0 - } - }; -} -function selectionClear(timeline) { - timeline.selection = timeline.selection.clear(); -} -function selectionRange(state, project) { - return _project__WEBPACK_IMPORTED_MODULE_0__.getRangeForElems(project, state.selection); -} -function selectionToggle(timeline, project, element) { - if (element.id === undefined || element.action === undefined) return; - const alreadySelected = timeline.selection.has(element.id); - if (!alreadySelected) timeline.selection = timeline.selection.add(element.id);else timeline.selection = timeline.selection.remove(element.id); -} -function selectionAdd(timeline, id) { - timeline.selection = timeline.selection.add(id); -} -function selectionAddAtCursor(timeline, project, verticalRegion) { - const time1 = timeline.cursor.time1; - const time2 = timeline.cursor.time2; - if (time1.compare(time2) === 0) return; - const range = new _utils_range_ts__WEBPACK_IMPORTED_MODULE_3__["default"](time1, time2, false, false).sorted(); - const laneIndexMin = cursorGetLaneIndexMin(timeline); - const laneIndexMax = cursorGetLaneIndexMax(timeline); - for (let l = laneIndexMin; l <= laneIndexMax; l++) { - const lane = timeline.layout.lanes[l]; - if (lane.iterElementsAtRegion === undefined) continue; - for (const id of lane.iterElementsAtRegion(timeline, project, range, verticalRegion)) selectionAdd(timeline, id); - } -} -function cursorSetTime(timeline, time1, time2) { - timeline.cursor.time1 = time1 ?? timeline.cursor.time1; - timeline.cursor.time2 = time2 ?? timeline.cursor.time2; -} -function cursorSetTrack(timeline, trackIndex1, trackIndex2) { - timeline.cursor.laneIndex1 = Math.max(0, Math.min(timeline.layout.lanes.length - 1, trackIndex1 ?? timeline.cursor.laneIndex1)); - timeline.cursor.laneIndex2 = Math.max(0, Math.min(timeline.layout.lanes.length - 1, trackIndex2 ?? timeline.cursor.laneIndex2)); -} -function cursorGetLaneIndexMin(timeline) { - return Math.max(0, Math.min(timeline.cursor.laneIndex1, timeline.cursor.laneIndex2)); -} -function cursorGetLaneIndexMax(timeline) { - return Math.min(timeline.layout.lanes.length - 1, Math.max(timeline.cursor.laneIndex1, timeline.cursor.laneIndex2)); -} - -/***/ }), - -/***/ "./src/utils/binarySearch.ts": -/*!***********************************!*\ - !*** ./src/utils/binarySearch.ts ***! - \***********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ BinarySearch) -/* harmony export */ }); -class BinarySearch { - static find(array, compareFn) { - /*for (let i = 0; i < array.length; i++) - { - const comparison = compareFn(value, array[i]) - - if (comparison <= 0) - return i - } - - return array.length*/ - - let lo = -1; - let hi = array.length; - while (1 + lo < hi) { - const mi = lo + (hi - lo >> 1); - if (compareFn(array[mi]) <= 0) hi = mi;else lo = mi; - } - return hi; - } - static findExact(array, value, compareFn) { - let i = BinarySearch.find(array, compareFn); - while (i < array.length) { - if (array[i] === value) return i; - i += 1; - } - return null; - } - static findPreviousOrEqual(array, compareFn) { - if (array.length == 0) return null; - const i = BinarySearch.find(array, compareFn); - if (i < array.length && compareFn(array[i]) == 0) return i; - if (i > 0) return i - 1; - return null; - } - static findPreviousNotEqual(array, compareFn) { - if (array.length == 0) return null; - const i = BinarySearch.find(array, compareFn); - if (i > 0) return i - 1; - return null; - } - static findNextNotEqual(array, compareFn) { - if (array.length == 0) return null; - let i = BinarySearch.find(array, compareFn); - while (i < array.length) { - if (compareFn(array[i]) != 0) break; - i += 1; - } - if (i < array.length) return i; - return null; - } - static *iterEqual(array, compareFn) { - let i = BinarySearch.find(array, compareFn); - while (i < array.length) { - if (compareFn(array[i]) != 0) break; - yield i; - i += 1; - } - } -} - -/***/ }), - -/***/ "./src/utils/listOfRanges.ts": -/*!***********************************!*\ - !*** ./src/utils/listOfRanges.ts ***! - \***********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ ListOfRanges) -/* harmony export */ }); -/* harmony import */ var assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! assert */ "?1e65"); -/* harmony import */ var assert__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(assert__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var immutable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! immutable */ "./node_modules/immutable/dist/immutable.es.js"); -/* harmony import */ var _rational_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./rational.ts */ "./src/utils/rational.ts"); -/* harmony import */ var _range_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./range.ts */ "./src/utils/range.ts"); -/* harmony import */ var _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./binarySearch.ts */ "./src/utils/binarySearch.ts"); - - - - - -class Bucket { - constructor(start) { - this.start = start; - this.elems = []; - } -} -class ListOfRanges { - constructor() { - this.idMap = immutable__WEBPACK_IMPORTED_MODULE_4__["default"].Map(); - this.buckets = []; - this.bucketFn = t => t.asFloat(); - } - clone() { - let cloned = new ListOfRanges(); - cloned.idMap = this.idMap; - cloned.buckets = this.buckets; - cloned.bucketFn = this.bucketFn; - return cloned; - } - clear() { - return Object.assign(new ListOfRanges(), { - bucketFn: this.bucketFn - }); - } - _ensureBucketsAtRange(range) { - let newBuckets = [...this.buckets]; - if (this.buckets.length == 0) newBuckets = [new Bucket(0)]; - const start = this.bucketFn(range.start); - while (start < newBuckets[0].start) { - const newBucket = new Bucket(newBuckets[0].start - 1); - newBuckets = [newBucket, ...newBuckets]; - } - const end = this.bucketFn(range.end); - while (end >= newBuckets[newBuckets.length - 1].start + 1) { - const newBucket = new Bucket(newBuckets[newBuckets.length - 1].start + 1); - newBuckets = [...newBuckets, newBucket]; - } - const cloned = this.clone(); - cloned.buckets = newBuckets; - return cloned; - } - *_iterBucketIndicesAtRange(range) { - const start = this.bucketFn(range.start); - const end = this.bucketFn(range.end); - let b = _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].find(this.buckets, bucket => start - bucket.start); - if (b > 0 && start < this.buckets[b - 1].start + 1) b -= 1; - while (true) { - if (b >= this.buckets.length || this.buckets[b].start > end) break; - yield b; - b += 1; - } - } - get size() { - return this.idMap.size; - } - update(elem) { - if (!this.idMap.get(elem.id)) return this; - return this.upsert(elem); - } - upsert(elem) { - //console.log("upsert id", elem.id, "buckets", this.bucketFn(elem.range.start), this.bucketFn(elem.range.end),) - - let newList = this._ensureBucketsAtRange(elem.range); - newList = newList.removeById(elem.id, false); - for (const b of newList._iterBucketIndicesAtRange(elem.range)) { - newList.buckets[b] = Object.assign({}, newList.buckets[b]); - const newElemIndex = _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].find(newList.buckets[b].elems, e => elem.range.start.compare(e.range.start)); - //console.log("- add to bucket", b, "at elem", newElemIndex) - - newList.buckets[b].elems = [...newList.buckets[b].elems.slice(0, newElemIndex), elem, ...newList.buckets[b].elems.slice(newElemIndex)]; - } - newList.idMap = newList.idMap.set(elem.id, elem); - return newList; - } - upsertMany(elems) { - let newList = this; - for (const elem of elems) newList = newList.upsert(elem); - return newList; - } - removeById(id, removeId = true) { - let newList = this; - const elem = this.idMap.get(id); - if (elem) { - newList = this.clone(); - newList.buckets = [...newList.buckets]; - for (const b of newList._iterBucketIndicesAtRange(elem.range)) { - const elemIndex = _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].findExact(newList.buckets[b].elems, elem, b => elem.range.start.compare(b.range.start)); - if (elemIndex === null) continue; - - //console.log("- remove from bucket", b, "at elem", elemIndex) - - newList.buckets[b] = Object.assign({}, newList.buckets[b]); - newList.buckets[b].elems = [...newList.buckets[b].elems.slice(0, elemIndex), ...newList.buckets[b].elems.slice(elemIndex + 1)]; - } - if (removeId) newList.idMap = newList.idMap.delete(id); - } - return newList; - } - findById(id) { - return this.idMap.get(id); - } - *iterAll() { - for (const bucket of this.buckets) for (const elem of bucket.elems) { - const elemStart = this.bucketFn(elem.range.start); - if (elemStart >= bucket.start && elemStart < bucket.start + 1) yield elem; - } - } - *iterAtRange(range) { - let firstBucket = true; - for (const b of this._iterBucketIndicesAtRange(range)) { - const bucket = this.buckets[b]; - for (const elem of bucket.elems) { - const elemStart = this.bucketFn(elem.range.start); - if (range.overlapsRange(elem.range) && (firstBucket || elemStart >= bucket.start && elemStart < bucket.start + 1)) yield elem; - } - firstBucket = false; - } - } - *iterAtPoint(point) { - const range = _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"].fromPoint(point, true, true); - for (const item of this.iterAtRange(range)) yield item; - } - *iterActiveAtRangePairwise(range) { - if (this.idMap.size == 0) { - yield [null, null]; - return; - } - let prevItem = this.findPrevious(range.start); - while (true) { - const nextItem = this.findNextNotEqual(prevItem?.range.end ?? range.start); - yield [prevItem, nextItem]; - if (!nextItem) break; - prevItem = nextItem; - } - } - *iterAllPairwise() { - if (this.idMap.size == 0) { - yield [null, null]; - return; - } - let prevItem = null; - for (const nextItem of this.iterAll()) { - yield [prevItem, nextItem]; - prevItem = nextItem; - } - yield [prevItem, null]; - } - getTotalRange() { - let firstElem = null; - let lastElem = null; - for (const bucket of this.buckets) { - if (bucket.elems.length > 0) { - firstElem = bucket.elems[0]; - break; - } - } - for (let b = this.buckets.length - 1; b >= 0; b--) { - for (const elem of this.buckets[b].elems) { - if (!lastElem || elem.range.end.compare(lastElem.range.end) > 0) lastElem = elem; - } - if (lastElem) break; - } - if (!firstElem || !lastElem) return null; - return firstElem.range.merge(lastElem.range); - } - findFirst() { - for (const elem of this.iterAll()) return elem; - return null; - } - findActiveAt(time) { - let result = null; - for (const elem of this.iterAll()) { - if (elem.range.start.compare(time) > 0) break; - result = elem; - } - return result; - } - findPreviousAnchor(fromPoint) { - let previous = null; - const end = this.bucketFn(fromPoint); - const endB = Math.min(this.buckets.length - 1, _binarySearch_ts__WEBPACK_IMPORTED_MODULE_3__["default"].find(this.buckets, bucket => end - bucket.start)); - for (let b = endB; b >= 0; b--) { - if (previous && this.bucketFn(previous) > this.buckets[b].start + 1) break; - for (const elem of this.buckets[b].elems) { - if (elem.range.start.compare(fromPoint) < 0 && (previous === null || elem.range.start.compare(previous) > 0)) previous = elem.range.start; - if (elem.range.end.compare(fromPoint) < 0 && (previous === null || elem.range.end.compare(previous) > 0)) previous = elem.range.end; - } - } - return previous; - } - findPrevious(fromPoint) { - let nearestItem = null; - let nearestPoint = null; - for (const item of this.iterAll()) { - const itemRange = item.range; - if (itemRange.end.compare(fromPoint) > 0) continue; - if (nearestPoint == null || itemRange.end.compare(nearestPoint) > 0) { - nearestItem = item; - nearestPoint = itemRange.end; - } - } - return nearestItem; - } - findPreviousDeletionAnchor(fromPoint) { - const anchor = this.findPrevious(fromPoint); - if (!anchor) return null; - const anchorRange = anchor.range; - if (anchorRange.end.compare(fromPoint) != 0) return anchorRange.end; - let nearestPoint = anchorRange.start; - for (const item of this.iterAll()) { - const itemRange = item.range; - if (itemRange.end.compare(anchorRange.end) != 0) continue; - if (itemRange.start.compare(nearestPoint) > 0) nearestPoint = itemRange.start; - } - return nearestPoint; - } - findNextNotEqual(fromPoint) { - let nearestItem = null; - let nearestPoint = null; - for (const item of this.iterAll()) { - const itemRange = item.range; - if (itemRange.end.compare(fromPoint) <= 0) continue; - if (nearestPoint == null || itemRange.end.compare(nearestPoint) < 0) { - nearestItem = item; - nearestPoint = itemRange.end; - } - } - return nearestItem; - } - static test() { - let list = new ListOfRanges(); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], []); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), null); - const elem1 = { - id: 1, - range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](2, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](6, 4)) - }; - const elem2 = { - id: 2, - range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](0, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](3, 4)) - }; - const elem3 = { - id: 3, - range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](-3, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](11, 4)) - }; - const elem4 = { - id: 4, - range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](12, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](16, 4)) - }; - const elem5 = { - id: 5, - range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](5, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](13, 4)) - }; - const elem1_2 = { - id: 1, - range: new _range_ts__WEBPACK_IMPORTED_MODULE_2__["default"](new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](6, 4), new _rational_ts__WEBPACK_IMPORTED_MODULE_1__["default"](11, 4)) - }; - list = list.upsert(elem1); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem1.range); - list = list.upsert(elem2); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem2.range.merge(elem1.range)); - list = list.upsert(elem3); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem1.range)); - list = list.upsert(elem4); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem1, elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem4.range)], [elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem4.range)); - list = list.upsert(elem5); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem1, elem5, elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem1, elem5]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2, elem1]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem1, elem5]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem4.range)], [elem5, elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem5.range)], [elem3, elem1, elem5, elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem4.range)); - list = list.upsert(elem1_2); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAll()], [elem3, elem2, elem5, elem1_2, elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1.range)], [elem3, elem2, elem5]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem2.range)], [elem3, elem2]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem3.range)], [elem3, elem2, elem5, elem1_2]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem4.range)], [elem5, elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem5.range)], [elem3, elem5, elem1_2, elem4]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual([...list.iterAtRange(elem1_2.range)], [elem3, elem5, elem1_2]); - assert__WEBPACK_IMPORTED_MODULE_0___default().deepEqual(list.getTotalRange(), elem3.range.merge(elem4.range)); - console.log("ListOfRanges tests passed"); - } -} - -/***/ }), - -/***/ "./src/utils/mathUtils.ts": -/*!********************************!*\ - !*** ./src/utils/mathUtils.ts ***! - \********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ dbToLinearGain: () => (/* binding */ dbToLinearGain), -/* harmony export */ dbToMidiVolume: () => (/* binding */ dbToMidiVolume), -/* harmony export */ linearGainToDb: () => (/* binding */ linearGainToDb), -/* harmony export */ midiToHertz: () => (/* binding */ midiToHertz), -/* harmony export */ midiVolumeToDb: () => (/* binding */ midiVolumeToDb), -/* harmony export */ midiVolumeToLinearGain: () => (/* binding */ midiVolumeToLinearGain), -/* harmony export */ mod: () => (/* binding */ mod), -/* harmony export */ quantize: () => (/* binding */ quantize) -/* harmony export */ }); -function mod(x, m) { - return (x % m + m) % m; -} -function quantize(x, step) { - return Math.floor(x * step) / step; -} -function midiToHertz(midi) { - return Math.pow(2, (midi - 69) / 12) * 440; -} -function dbToLinearGain(db) { - return Math.pow(10, db / 20); -} -function linearGainToDb(linearGain) { - return 20 * Math.log10(linearGain); -} -const minMidiDbLevel = -30; -function dbToMidiVolume(db) { - return Math.max(0, Math.min(1, 1 - db / minMidiDbLevel)); -} -function midiVolumeToDb(midiVol) { - if (midiVol <= 0) return 0; - return minMidiDbLevel * (1 - midiVol); -} -function midiVolumeToLinearGain(midiVol) { - if (midiVol <= 0) return 0; - return dbToLinearGain(midiVolumeToDb(midiVol)); -} - -/***/ }), - -/***/ "./src/utils/range.ts": -/*!****************************!*\ - !*** ./src/utils/range.ts ***! - \****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Range) -/* harmony export */ }); -/* harmony import */ var _rational_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rational.ts */ "./src/utils/rational.ts"); - -class Range { - constructor(start, end, startInclusive = true, endInclusive = false) { - this.start = start; - this.end = end; - this.startInclusive = startInclusive; - this.endInclusive = endInclusive; - } - static fromPoint(p, startInclusive = true, endInclusive = true) { - return new Range(p, p, startInclusive, endInclusive); - } - static fromStartDuration(start, duration) { - return new Range(start, start.add(duration)); - } - static dummy() { - return new Range(new _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0), new _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0)); - } - get duration() { - return this.end.subtract(this.start); - } - setDuration(newDuration) { - return new Range(this.start, this.start.add(newDuration), this.startInclusive, this.endInclusive); - } - sorted() { - const startInclusive = this.start.lessThan(this.end) ? this.startInclusive : this.endInclusive; - const endInclusive = this.end.greaterThan(this.start) ? this.endInclusive : this.startInclusive; - return new Range(this.start.min(this.end), this.start.max(this.end), startInclusive, endInclusive); - } - max() { - return this.start.max(this.end); - } - min() { - return this.start.min(this.end); - } - merge(other) { - return Range.merge(this, other); - } - static merge(r1, r2) { - if (r1 === null && r2 === null) return null; - if (r1 === null) return r2; - if (r2 === null) return r1; - return new Range(r1.start.min(r2.start), r1.end.max(r2.end)); - } - intersect(other) { - return Range.intersect(this, other); - } - static intersect(r1, r2) { - if (r1 === null && r2 === null) return null; - if (r1 === null) return r2; - if (r2 === null) return r1; - return new Range(r1.start.max(r2.start), r1.end.min(r2.end)); - } - atZero() { - return new Range(new _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"](0), this.duration, this.startInclusive, this.endInclusive); - } - stretch(offset, pivot, origin) { - return new Range(this.start.stretch(offset, pivot, origin), this.end.stretch(offset, pivot, origin), this.startInclusive, this.endInclusive); - } - displace(offset) { - return new Range(this.start.add(offset), this.end.add(offset), this.startInclusive, this.endInclusive); - } - subtract(offset) { - return new Range(this.start.subtract(offset), this.end.subtract(offset), this.startInclusive, this.endInclusive); - } - grow(offset) { - return new Range(this.start.subtract(offset), this.end.add(offset), this.startInclusive, this.endInclusive); - } - shrink(offset) { - return new Range(this.start.add(offset), this.end.subtract(offset), this.startInclusive, this.endInclusive); - } - snap(step) { - return new Range(this.start.snap(step), this.end.snap(step), this.startInclusive, this.endInclusive); - } - *iterSlices(slice) { - if (slice.start.compare(this.start) <= 0) { - if (slice.end.compare(this.end) < 0) yield new Range(slice.end.max(this.start), this.end); - } else { - if (slice.end.compare(this.end) >= 0) yield new Range(this.start, slice.start.min(this.end));else { - yield new Range(this.start, slice.start.min(this.end)); - yield new Range(slice.end.max(this.start), this.end); - } - } - } - isPoint() { - return this.start.equalTo(this.end); - } - overlapsPoint(point) { - const compStart = this.start.compare(point); - const compEnd = this.end.compare(point); - const checkStart = this.startInclusive ? compStart <= 0 : compStart < 0; - const checkEnd = this.endInclusive ? compEnd >= 0 : compEnd > 0; - return checkStart && checkEnd; - } - overlapsRange(range) { - const compStart = this.start.compare(range.end); - const compEnd = this.end.compare(range.start); - const checkStart = this.startInclusive && range.endInclusive ? compStart <= 0 : compStart < 0; - const checkEnd = this.endInclusive && range.startInclusive ? compEnd >= 0 : compEnd > 0; - return checkStart && checkEnd; - } - containsRangeCompletely(range) { - const compStart = this.start.compare(range.start); - const compEnd = this.end.compare(range.end); - const checkStart = this.startInclusive ? compStart <= 0 : compStart < 0; - const checkEnd = this.endInclusive ? compEnd >= 0 : compEnd > 0; - return checkStart && checkEnd; - } - quantize(maxDenom) { - return new Range(this.start.quantize(maxDenom), this.end.quantize(maxDenom), this.startInclusive, this.endInclusive); - } - toString() { - return "[" + this.start.toString() + " ~ " + this.end.toString() + "]"; - } - toJson(quantize) { - if (this.start.compare(this.end) == 0) return [this.start.toJson()];else { - if (quantize !== undefined) return [this.start.toJson(), this.duration.quantize(quantize).toJson()];else return [this.start.toJson(), this.duration.toJson()]; - } - } - static fromJson(json) { - if (json.length == 1) return Range.fromPoint(_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromJson(json[0]));else return Range.fromStartDuration(_rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromJson(json[0]), _rational_ts__WEBPACK_IMPORTED_MODULE_0__["default"].fromJson(json[1])); - } -} - -/***/ }), - -/***/ "./src/utils/rational.ts": -/*!*******************************!*\ - !*** ./src/utils/rational.ts ***! - \*******************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Rational) -/* harmony export */ }); -function mod(x, m) { - return (x % m + m) % m; -} -class Rational { - constructor(numerator = 0, denominator = 1) { - if (denominator == 0) throw "denominator zero"; - if (!isFinite(numerator) || !isFinite(denominator)) throw "invalid rational"; - this.numerator = numerator; - this.denominator = denominator; - this.simplifyInPlace(); - } - static fromFloat(floatValue, maxDenominator) { - const integer = Math.floor(floatValue); - const frac = floatValue - integer; - return new Rational(integer * maxDenominator + Math.round(frac * maxDenominator), maxDenominator); - } - static fromIntegerPlusRational(integer, numeratorWithoutInteger, denominator) { - return new Rational(integer * denominator + numeratorWithoutInteger, denominator); - } - asFloat() { - return this.numerator / this.denominator; - } - get n() { - return this.numerator; - } - get d() { - return this.denominator; - } - get integer() { - return Math.floor(this.numerator / this.denominator); - } - get numeratorWithoutInteger() { - return mod(this.numerator, this.denominator); - } - negate() { - return new Rational(-this.numerator, this.denominator); - } - absolute() { - if (this.numerator < 0) return new Rational(-this.numerator, this.denominator);else return this; - } - add(other) { - return new Rational(this.numerator * other.denominator + other.numerator * this.denominator, this.denominator * other.denominator); - } - subtract(other) { - return new Rational(this.numerator * other.denominator - other.numerator * this.denominator, this.denominator * other.denominator); - } - multiply(other) { - return new Rational(this.numerator * other.numerator, this.denominator * other.denominator); - } - multiplyByFloat(x) { - return new Rational(this.numerator * x, this.denominator); - } - divide(other) { - return new Rational(this.numerator * other.denominator, this.denominator * other.numerator); - } - snap(step) { - return Rational.fromFloat(this.asFloat(), step.denominator); - } - quantize(maxDenominator) { - if (this.denominator <= maxDenominator) return this.simplify(); - return new Rational(Math.round(this.numerator / this.denominator * maxDenominator), maxDenominator); - } - stretch(offset, pivot, origin) { - let dist = origin.subtract(pivot); - if (dist.numerator == 0) return this; - let p = this.subtract(pivot).divide(dist); - let move = origin.add(offset).subtract(pivot).divide(dist); - return pivot.add(dist.multiply(p).multiply(move)); - } - isZero() { - return this.numerator == 0; - } - compare(other) { - let thisNumerator = this.numerator * other.denominator; - let otherNumerator = other.numerator * this.denominator; - if (thisNumerator < otherNumerator) return -1;else if (thisNumerator > otherNumerator) return 1;else return 0; - } - equalTo(other) { - return this.compare(other) == 0; - } - notEqualTo(other) { - return this.compare(other) != 0; - } - lessThan(other) { - return this.compare(other) < 0; - } - lessThanOrEqual(other) { - return this.compare(other) <= 0; - } - greaterThan(other) { - return this.compare(other) > 0; - } - greaterThanOrEqual(other) { - return this.compare(other) >= 0; - } - static max(a, b) { - if (a === null && b === null) return null; - if (a === null) return b; - if (b === null) return a; - if (a.compare(b) > 0) return a;else return b; - } - static min(a, b) { - if (a === null && b === null) return null; - if (a === null) return b; - if (b === null) return a; - if (a.compare(b) < 0) return a;else return b; - } - max(other) { - return Rational.max(this, other); - } - min(other) { - return Rational.min(this, other); - } - simplify() { - return new Rational(this.numerator, this.denominator); - } - simplifyInPlace() { - this.trySimplifyInPlaceBy(2); - this.trySimplifyInPlaceBy(3); - this.trySimplifyInPlaceBy(5); - this.trySimplifyInPlaceBy(7); - this.trySimplifyInPlaceBy(11); - this.trySimplifyInPlaceBy(13); - } - trySimplifyInPlaceBy(divider) { - while (this.numerator % divider == 0 && this.denominator % divider == 0) { - this.numerator /= divider; - this.denominator /= divider; - } - } - toString() { - let integer = Math.floor(this.numerator / this.denominator); - let numerator = this.numerator % this.denominator; - if (numerator == 0) return integer.toString();else return integer.toString() + " + " + numerator.toString() + "/" + this.denominator.toString(); - } - toJson() { - return [this.integer, this.numeratorWithoutInteger, this.denominator]; - } - static fromJson(array) { - return new Rational(array[0] * array[2] + array[1], array[2]); - } -} - -/***/ }), - -/***/ "./src/utils/rect.ts": -/*!***************************!*\ - !*** ./src/utils/rect.ts ***! - \***************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Rect) -/* harmony export */ }); -class Rect { - constructor(x, y, w, h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - static fromVertices(x1, y1, x2, y2) { - return new Rect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1)); - } - static fromElement(elem) { - const clientRect = elem.getBoundingClientRect(); - return new Rect(clientRect.left, clientRect.top, clientRect.width, clientRect.height); - } - clone() { - return new Rect(this.x, this.y, this.w, this.h); - } - get x1() { - return this.x; - } - get y1() { - return this.y; - } - get x2() { - return this.x + this.w; - } - get y2() { - return this.y + this.h; - } - get xCenter() { - return (this.x1 + this.x2) / 2; - } - get yCenter() { - return (this.y1 + this.y2) / 2; - } - withX(value) { - return new Rect(value, this.y, this.w, this.h); - } - withY(value) { - return new Rect(this.x, value, this.w, this.h); - } - withW(value) { - return new Rect(this.x, this.y, value, this.h); - } - withH(value) { - return new Rect(this.x, this.y, this.w, value); - } - withX1(value) { - return Rect.fromVertices(value, this.y1, this.x2, this.y2); - } - withY1(value) { - return Rect.fromVertices(this.x1, value, this.x2, this.y2); - } - withX2(value) { - return Rect.fromVertices(this.x1, this.y1, value, this.y2); - } - withY2(value) { - return Rect.fromVertices(this.x1, this.y1, this.x2, value); - } - displace(x, y) { - return new Rect(this.x + x, this.y + y, this.w, this.h); - } - expand(amount) { - return Rect.fromVertices(this.x1 - amount, this.y1 - amount, this.x2 + amount, this.y2 + amount); - } - expandW(amount) { - return Rect.fromVertices(this.x1 - amount, this.y1, this.x2 + amount, this.y2); - } - contains(p) { - return p.x >= this.x && p.x < this.x2 && p.y >= this.y && p.y < this.y2; - } - overlaps(other) { - return this.x2 >= other.x && this.x < other.x2 && this.y2 >= other.y && this.y < other.y2; - } -} - -/***/ }), - -/***/ "./node_modules/immutable/dist/immutable.es.js": -/*!*****************************************************!*\ - !*** ./node_modules/immutable/dist/immutable.es.js ***! - \*****************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Collection: () => (/* binding */ Collection), -/* harmony export */ Iterable: () => (/* binding */ Iterable), -/* harmony export */ List: () => (/* binding */ List), -/* harmony export */ Map: () => (/* binding */ Map), -/* harmony export */ OrderedMap: () => (/* binding */ OrderedMap), -/* harmony export */ OrderedSet: () => (/* binding */ OrderedSet), -/* harmony export */ PairSorting: () => (/* binding */ PairSorting), -/* harmony export */ Range: () => (/* binding */ Range), -/* harmony export */ Record: () => (/* binding */ Record), -/* harmony export */ Repeat: () => (/* binding */ Repeat), -/* harmony export */ Seq: () => (/* binding */ Seq), -/* harmony export */ Set: () => (/* binding */ Set), -/* harmony export */ Stack: () => (/* binding */ Stack), -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), -/* harmony export */ fromJS: () => (/* binding */ fromJS), -/* harmony export */ get: () => (/* binding */ get), -/* harmony export */ getIn: () => (/* binding */ getIn$1), -/* harmony export */ has: () => (/* binding */ has), -/* harmony export */ hasIn: () => (/* binding */ hasIn$1), -/* harmony export */ hash: () => (/* binding */ hash), -/* harmony export */ is: () => (/* binding */ is), -/* harmony export */ isAssociative: () => (/* binding */ isAssociative), -/* harmony export */ isCollection: () => (/* binding */ isCollection), -/* harmony export */ isImmutable: () => (/* binding */ isImmutable), -/* harmony export */ isIndexed: () => (/* binding */ isIndexed), -/* harmony export */ isKeyed: () => (/* binding */ isKeyed), -/* harmony export */ isList: () => (/* binding */ isList), -/* harmony export */ isMap: () => (/* binding */ isMap), -/* harmony export */ isOrdered: () => (/* binding */ isOrdered), -/* harmony export */ isOrderedMap: () => (/* binding */ isOrderedMap), -/* harmony export */ isOrderedSet: () => (/* binding */ isOrderedSet), -/* harmony export */ isPlainObject: () => (/* binding */ isPlainObject), -/* harmony export */ isRecord: () => (/* binding */ isRecord), -/* harmony export */ isSeq: () => (/* binding */ isSeq), -/* harmony export */ isSet: () => (/* binding */ isSet), -/* harmony export */ isStack: () => (/* binding */ isStack), -/* harmony export */ isValueObject: () => (/* binding */ isValueObject), -/* harmony export */ merge: () => (/* binding */ merge), -/* harmony export */ mergeDeep: () => (/* binding */ mergeDeep$1), -/* harmony export */ mergeDeepWith: () => (/* binding */ mergeDeepWith$1), -/* harmony export */ mergeWith: () => (/* binding */ mergeWith), -/* harmony export */ remove: () => (/* binding */ remove), -/* harmony export */ removeIn: () => (/* binding */ removeIn), -/* harmony export */ set: () => (/* binding */ set), -/* harmony export */ setIn: () => (/* binding */ setIn$1), -/* harmony export */ update: () => (/* binding */ update$1), -/* harmony export */ updateIn: () => (/* binding */ updateIn$1), -/* harmony export */ version: () => (/* binding */ version) -/* harmony export */ }); -/** - * MIT License - * - * Copyright (c) 2014-present, Lee Byron and other contributors. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -var DELETE = 'delete'; - -// Constants describing the size of trie nodes. -var SHIFT = 5; // Resulted in best performance after ______? -var SIZE = 1 << SHIFT; -var MASK = SIZE - 1; - -// A consistent shared value representing "not set" which equals nothing other -// than itself, and nothing that could be provided externally. -var NOT_SET = {}; - -// Boolean references, Rough equivalent of `bool &`. -function MakeRef() { - return { value: false }; -} - -function SetRef(ref) { - if (ref) { - ref.value = true; - } -} - -// A function which returns a value representing an "owner" for transient writes -// to tries. The return value will only ever equal itself, and will not equal -// the return of any subsequent call of this function. -function OwnerID() {} - -function ensureSize(iter) { - if (iter.size === undefined) { - iter.size = iter.__iterate(returnTrue); - } - return iter.size; -} - -function wrapIndex(iter, index) { - // This implements "is array index" which the ECMAString spec defines as: - // - // A String property name P is an array index if and only if - // ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal - // to 2^32−1. - // - // http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects - if (typeof index !== 'number') { - var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32 - if ('' + uint32Index !== index || uint32Index === 4294967295) { - return NaN; - } - index = uint32Index; - } - return index < 0 ? ensureSize(iter) + index : index; -} - -function returnTrue() { - return true; -} - -function wholeSlice(begin, end, size) { - return ( - ((begin === 0 && !isNeg(begin)) || - (size !== undefined && begin <= -size)) && - (end === undefined || (size !== undefined && end >= size)) - ); -} - -function resolveBegin(begin, size) { - return resolveIndex(begin, size, 0); -} - -function resolveEnd(end, size) { - return resolveIndex(end, size, size); -} - -function resolveIndex(index, size, defaultIndex) { - // Sanitize indices using this shorthand for ToInt32(argument) - // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 - return index === undefined - ? defaultIndex - : isNeg(index) - ? size === Infinity - ? size - : Math.max(0, size + index) | 0 - : size === undefined || size === index - ? index - : Math.min(size, index) | 0; -} - -function isNeg(value) { - // Account for -0 which is negative, but not less than 0. - return value < 0 || (value === 0 && 1 / value === -Infinity); -} - -var IS_COLLECTION_SYMBOL = '@@__IMMUTABLE_ITERABLE__@@'; - -function isCollection(maybeCollection) { - return Boolean(maybeCollection && maybeCollection[IS_COLLECTION_SYMBOL]); -} - -var IS_KEYED_SYMBOL = '@@__IMMUTABLE_KEYED__@@'; - -function isKeyed(maybeKeyed) { - return Boolean(maybeKeyed && maybeKeyed[IS_KEYED_SYMBOL]); -} - -var IS_INDEXED_SYMBOL = '@@__IMMUTABLE_INDEXED__@@'; - -function isIndexed(maybeIndexed) { - return Boolean(maybeIndexed && maybeIndexed[IS_INDEXED_SYMBOL]); -} - -function isAssociative(maybeAssociative) { - return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); -} - -var Collection = function Collection(value) { - // eslint-disable-next-line no-constructor-return - return isCollection(value) ? value : Seq(value); -}; - -var KeyedCollection = /*@__PURE__*/(function (Collection) { - function KeyedCollection(value) { - // eslint-disable-next-line no-constructor-return - return isKeyed(value) ? value : KeyedSeq(value); - } - - if ( Collection ) KeyedCollection.__proto__ = Collection; - KeyedCollection.prototype = Object.create( Collection && Collection.prototype ); - KeyedCollection.prototype.constructor = KeyedCollection; - - return KeyedCollection; -}(Collection)); - -var IndexedCollection = /*@__PURE__*/(function (Collection) { - function IndexedCollection(value) { - // eslint-disable-next-line no-constructor-return - return isIndexed(value) ? value : IndexedSeq(value); - } - - if ( Collection ) IndexedCollection.__proto__ = Collection; - IndexedCollection.prototype = Object.create( Collection && Collection.prototype ); - IndexedCollection.prototype.constructor = IndexedCollection; - - return IndexedCollection; -}(Collection)); - -var SetCollection = /*@__PURE__*/(function (Collection) { - function SetCollection(value) { - // eslint-disable-next-line no-constructor-return - return isCollection(value) && !isAssociative(value) ? value : SetSeq(value); - } - - if ( Collection ) SetCollection.__proto__ = Collection; - SetCollection.prototype = Object.create( Collection && Collection.prototype ); - SetCollection.prototype.constructor = SetCollection; - - return SetCollection; -}(Collection)); - -Collection.Keyed = KeyedCollection; -Collection.Indexed = IndexedCollection; -Collection.Set = SetCollection; - -var IS_SEQ_SYMBOL = '@@__IMMUTABLE_SEQ__@@'; - -function isSeq(maybeSeq) { - return Boolean(maybeSeq && maybeSeq[IS_SEQ_SYMBOL]); -} - -var IS_RECORD_SYMBOL = '@@__IMMUTABLE_RECORD__@@'; - -function isRecord(maybeRecord) { - return Boolean(maybeRecord && maybeRecord[IS_RECORD_SYMBOL]); -} - -function isImmutable(maybeImmutable) { - return isCollection(maybeImmutable) || isRecord(maybeImmutable); -} - -var IS_ORDERED_SYMBOL = '@@__IMMUTABLE_ORDERED__@@'; - -function isOrdered(maybeOrdered) { - return Boolean(maybeOrdered && maybeOrdered[IS_ORDERED_SYMBOL]); -} - -var ITERATE_KEYS = 0; -var ITERATE_VALUES = 1; -var ITERATE_ENTRIES = 2; - -var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; - -var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; - -var Iterator = function Iterator(next) { - this.next = next; -}; - -Iterator.prototype.toString = function toString () { - return '[Iterator]'; -}; - -Iterator.KEYS = ITERATE_KEYS; -Iterator.VALUES = ITERATE_VALUES; -Iterator.ENTRIES = ITERATE_ENTRIES; - -Iterator.prototype.inspect = Iterator.prototype.toSource = function () { - return this.toString(); -}; -Iterator.prototype[ITERATOR_SYMBOL] = function () { - return this; -}; - -function iteratorValue(type, k, v, iteratorResult) { - var value = type === 0 ? k : type === 1 ? v : [k, v]; - iteratorResult - ? (iteratorResult.value = value) - : (iteratorResult = { - value: value, - done: false, - }); - return iteratorResult; -} - -function iteratorDone() { - return { value: undefined, done: true }; -} - -function hasIterator(maybeIterable) { - if (Array.isArray(maybeIterable)) { - // IE11 trick as it does not support `Symbol.iterator` - return true; - } - - return !!getIteratorFn(maybeIterable); -} - -function isIterator(maybeIterator) { - return maybeIterator && typeof maybeIterator.next === 'function'; -} - -function getIterator(iterable) { - var iteratorFn = getIteratorFn(iterable); - return iteratorFn && iteratorFn.call(iterable); -} - -function getIteratorFn(iterable) { - var iteratorFn = - iterable && - ((REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || - iterable[FAUX_ITERATOR_SYMBOL]); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -function isEntriesIterable(maybeIterable) { - var iteratorFn = getIteratorFn(maybeIterable); - return iteratorFn && iteratorFn === maybeIterable.entries; -} - -function isKeysIterable(maybeIterable) { - var iteratorFn = getIteratorFn(maybeIterable); - return iteratorFn && iteratorFn === maybeIterable.keys; -} - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function isArrayLike(value) { - if (Array.isArray(value) || typeof value === 'string') { - return true; - } - - return ( - value && - typeof value === 'object' && - Number.isInteger(value.length) && - value.length >= 0 && - (value.length === 0 - ? // Only {length: 0} is considered Array-like. - Object.keys(value).length === 1 - : // An object is only Array-like if it has a property where the last value - // in the array-like may be found (which could be undefined). - value.hasOwnProperty(value.length - 1)) - ); -} - -var Seq = /*@__PURE__*/(function (Collection) { - function Seq(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptySequence() - : isImmutable(value) - ? value.toSeq() - : seqFromValue(value); - } - - if ( Collection ) Seq.__proto__ = Collection; - Seq.prototype = Object.create( Collection && Collection.prototype ); - Seq.prototype.constructor = Seq; - - Seq.prototype.toSeq = function toSeq () { - return this; - }; - - Seq.prototype.toString = function toString () { - return this.__toString('Seq {', '}'); - }; - - Seq.prototype.cacheResult = function cacheResult () { - if (!this._cache && this.__iterateUncached) { - this._cache = this.entrySeq().toArray(); - this.size = this._cache.length; - } - return this; - }; - - // abstract __iterateUncached(fn, reverse) - - Seq.prototype.__iterate = function __iterate (fn, reverse) { - var cache = this._cache; - if (cache) { - var size = cache.length; - var i = 0; - while (i !== size) { - var entry = cache[reverse ? size - ++i : i++]; - if (fn(entry[1], entry[0], this) === false) { - break; - } - } - return i; - } - return this.__iterateUncached(fn, reverse); - }; - - // abstract __iteratorUncached(type, reverse) - - Seq.prototype.__iterator = function __iterator (type, reverse) { - var cache = this._cache; - if (cache) { - var size = cache.length; - var i = 0; - return new Iterator(function () { - if (i === size) { - return iteratorDone(); - } - var entry = cache[reverse ? size - ++i : i++]; - return iteratorValue(type, entry[0], entry[1]); - }); - } - return this.__iteratorUncached(type, reverse); - }; - - return Seq; -}(Collection)); - -var KeyedSeq = /*@__PURE__*/(function (Seq) { - function KeyedSeq(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptySequence().toKeyedSeq() - : isCollection(value) - ? isKeyed(value) - ? value.toSeq() - : value.fromEntrySeq() - : isRecord(value) - ? value.toSeq() - : keyedSeqFromValue(value); - } - - if ( Seq ) KeyedSeq.__proto__ = Seq; - KeyedSeq.prototype = Object.create( Seq && Seq.prototype ); - KeyedSeq.prototype.constructor = KeyedSeq; - - KeyedSeq.prototype.toKeyedSeq = function toKeyedSeq () { - return this; - }; - - return KeyedSeq; -}(Seq)); - -var IndexedSeq = /*@__PURE__*/(function (Seq) { - function IndexedSeq(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptySequence() - : isCollection(value) - ? isKeyed(value) - ? value.entrySeq() - : value.toIndexedSeq() - : isRecord(value) - ? value.toSeq().entrySeq() - : indexedSeqFromValue(value); - } - - if ( Seq ) IndexedSeq.__proto__ = Seq; - IndexedSeq.prototype = Object.create( Seq && Seq.prototype ); - IndexedSeq.prototype.constructor = IndexedSeq; - - IndexedSeq.of = function of (/*...values*/) { - return IndexedSeq(arguments); - }; - - IndexedSeq.prototype.toIndexedSeq = function toIndexedSeq () { - return this; - }; - - IndexedSeq.prototype.toString = function toString () { - return this.__toString('Seq [', ']'); - }; - - return IndexedSeq; -}(Seq)); - -var SetSeq = /*@__PURE__*/(function (Seq) { - function SetSeq(value) { - // eslint-disable-next-line no-constructor-return - return ( - isCollection(value) && !isAssociative(value) ? value : IndexedSeq(value) - ).toSetSeq(); - } - - if ( Seq ) SetSeq.__proto__ = Seq; - SetSeq.prototype = Object.create( Seq && Seq.prototype ); - SetSeq.prototype.constructor = SetSeq; - - SetSeq.of = function of (/*...values*/) { - return SetSeq(arguments); - }; - - SetSeq.prototype.toSetSeq = function toSetSeq () { - return this; - }; - - return SetSeq; -}(Seq)); - -Seq.isSeq = isSeq; -Seq.Keyed = KeyedSeq; -Seq.Set = SetSeq; -Seq.Indexed = IndexedSeq; - -Seq.prototype[IS_SEQ_SYMBOL] = true; - -// #pragma Root Sequences - -var ArraySeq = /*@__PURE__*/(function (IndexedSeq) { - function ArraySeq(array) { - this._array = array; - this.size = array.length; - } - - if ( IndexedSeq ) ArraySeq.__proto__ = IndexedSeq; - ArraySeq.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); - ArraySeq.prototype.constructor = ArraySeq; - - ArraySeq.prototype.get = function get (index, notSetValue) { - return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; - }; - - ArraySeq.prototype.__iterate = function __iterate (fn, reverse) { - var array = this._array; - var size = array.length; - var i = 0; - while (i !== size) { - var ii = reverse ? size - ++i : i++; - if (fn(array[ii], ii, this) === false) { - break; - } - } - return i; - }; - - ArraySeq.prototype.__iterator = function __iterator (type, reverse) { - var array = this._array; - var size = array.length; - var i = 0; - return new Iterator(function () { - if (i === size) { - return iteratorDone(); - } - var ii = reverse ? size - ++i : i++; - return iteratorValue(type, ii, array[ii]); - }); - }; - - return ArraySeq; -}(IndexedSeq)); - -var ObjectSeq = /*@__PURE__*/(function (KeyedSeq) { - function ObjectSeq(object) { - var keys = Object.keys(object).concat( - Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : [] - ); - this._object = object; - this._keys = keys; - this.size = keys.length; - } - - if ( KeyedSeq ) ObjectSeq.__proto__ = KeyedSeq; - ObjectSeq.prototype = Object.create( KeyedSeq && KeyedSeq.prototype ); - ObjectSeq.prototype.constructor = ObjectSeq; - - ObjectSeq.prototype.get = function get (key, notSetValue) { - if (notSetValue !== undefined && !this.has(key)) { - return notSetValue; - } - return this._object[key]; - }; - - ObjectSeq.prototype.has = function has (key) { - return hasOwnProperty.call(this._object, key); - }; - - ObjectSeq.prototype.__iterate = function __iterate (fn, reverse) { - var object = this._object; - var keys = this._keys; - var size = keys.length; - var i = 0; - while (i !== size) { - var key = keys[reverse ? size - ++i : i++]; - if (fn(object[key], key, this) === false) { - break; - } - } - return i; - }; - - ObjectSeq.prototype.__iterator = function __iterator (type, reverse) { - var object = this._object; - var keys = this._keys; - var size = keys.length; - var i = 0; - return new Iterator(function () { - if (i === size) { - return iteratorDone(); - } - var key = keys[reverse ? size - ++i : i++]; - return iteratorValue(type, key, object[key]); - }); - }; - - return ObjectSeq; -}(KeyedSeq)); -ObjectSeq.prototype[IS_ORDERED_SYMBOL] = true; - -var CollectionSeq = /*@__PURE__*/(function (IndexedSeq) { - function CollectionSeq(collection) { - this._collection = collection; - this.size = collection.length || collection.size; - } - - if ( IndexedSeq ) CollectionSeq.__proto__ = IndexedSeq; - CollectionSeq.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); - CollectionSeq.prototype.constructor = CollectionSeq; - - CollectionSeq.prototype.__iterateUncached = function __iterateUncached (fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var collection = this._collection; - var iterator = getIterator(collection); - var iterations = 0; - if (isIterator(iterator)) { - var step; - while (!(step = iterator.next()).done) { - if (fn(step.value, iterations++, this) === false) { - break; - } - } - } - return iterations; - }; - - CollectionSeq.prototype.__iteratorUncached = function __iteratorUncached (type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var collection = this._collection; - var iterator = getIterator(collection); - if (!isIterator(iterator)) { - return new Iterator(iteratorDone); - } - var iterations = 0; - return new Iterator(function () { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, iterations++, step.value); - }); - }; - - return CollectionSeq; -}(IndexedSeq)); - -// # pragma Helper functions - -var EMPTY_SEQ; - -function emptySequence() { - return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); -} - -function keyedSeqFromValue(value) { - var seq = maybeIndexedSeqFromValue(value); - if (seq) { - return seq.fromEntrySeq(); - } - if (typeof value === 'object') { - return new ObjectSeq(value); - } - throw new TypeError( - 'Expected Array or collection object of [k, v] entries, or keyed object: ' + - value - ); -} - -function indexedSeqFromValue(value) { - var seq = maybeIndexedSeqFromValue(value); - if (seq) { - return seq; - } - throw new TypeError( - 'Expected Array or collection object of values: ' + value - ); -} - -function seqFromValue(value) { - var seq = maybeIndexedSeqFromValue(value); - if (seq) { - return isEntriesIterable(value) - ? seq.fromEntrySeq() - : isKeysIterable(value) - ? seq.toSetSeq() - : seq; - } - if (typeof value === 'object') { - return new ObjectSeq(value); - } - throw new TypeError( - 'Expected Array or collection object of values, or keyed object: ' + value - ); -} - -function maybeIndexedSeqFromValue(value) { - return isArrayLike(value) - ? new ArraySeq(value) - : hasIterator(value) - ? new CollectionSeq(value) - : undefined; -} - -var IS_MAP_SYMBOL = '@@__IMMUTABLE_MAP__@@'; - -function isMap(maybeMap) { - return Boolean(maybeMap && maybeMap[IS_MAP_SYMBOL]); -} - -function isOrderedMap(maybeOrderedMap) { - return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); -} - -function isValueObject(maybeValue) { - return Boolean( - maybeValue && - typeof maybeValue.equals === 'function' && - typeof maybeValue.hashCode === 'function' - ); -} - -/** - * An extension of the "same-value" algorithm as [described for use by ES6 Map - * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) - * - * NaN is considered the same as NaN, however -0 and 0 are considered the same - * value, which is different from the algorithm described by - * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). - * - * This is extended further to allow Objects to describe the values they - * represent, by way of `valueOf` or `equals` (and `hashCode`). - * - * Note: because of this extension, the key equality of Immutable.Map and the - * value equality of Immutable.Set will differ from ES6 Map and Set. - * - * ### Defining custom values - * - * The easiest way to describe the value an object represents is by implementing - * `valueOf`. For example, `Date` represents a value by returning a unix - * timestamp for `valueOf`: - * - * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... - * var date2 = new Date(1234567890000); - * date1.valueOf(); // 1234567890000 - * assert( date1 !== date2 ); - * assert( Immutable.is( date1, date2 ) ); - * - * Note: overriding `valueOf` may have other implications if you use this object - * where JavaScript expects a primitive, such as implicit string coercion. - * - * For more complex types, especially collections, implementing `valueOf` may - * not be performant. An alternative is to implement `equals` and `hashCode`. - * - * `equals` takes another object, presumably of similar type, and returns true - * if it is equal. Equality is symmetrical, so the same result should be - * returned if this and the argument are flipped. - * - * assert( a.equals(b) === b.equals(a) ); - * - * `hashCode` returns a 32bit integer number representing the object which will - * be used to determine how to store the value object in a Map or Set. You must - * provide both or neither methods, one must not exist without the other. - * - * Also, an important relationship between these methods must be upheld: if two - * values are equal, they *must* return the same hashCode. If the values are not - * equal, they might have the same hashCode; this is called a hash collision, - * and while undesirable for performance reasons, it is acceptable. - * - * if (a.equals(b)) { - * assert( a.hashCode() === b.hashCode() ); - * } - * - * All Immutable collections are Value Objects: they implement `equals()` - * and `hashCode()`. - */ -function is(valueA, valueB) { - if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { - return true; - } - if (!valueA || !valueB) { - return false; - } - if ( - typeof valueA.valueOf === 'function' && - typeof valueB.valueOf === 'function' - ) { - valueA = valueA.valueOf(); - valueB = valueB.valueOf(); - if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { - return true; - } - if (!valueA || !valueB) { - return false; - } - } - return !!( - isValueObject(valueA) && - isValueObject(valueB) && - valueA.equals(valueB) - ); -} - -var imul = - typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 - ? Math.imul - : function imul(a, b) { - a |= 0; // int - b |= 0; // int - var c = a & 0xffff; - var d = b & 0xffff; - // Shift by 0 fixes the sign on the high part. - return (c * d + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0)) | 0; // int - }; - -// v8 has an optimization for storing 31-bit signed numbers. -// Values which have either 00 or 11 as the high order bits qualify. -// This function drops the highest order bit in a signed number, maintaining -// the sign bit. -function smi(i32) { - return ((i32 >>> 1) & 0x40000000) | (i32 & 0xbfffffff); -} - -var defaultValueOf = Object.prototype.valueOf; - -function hash(o) { - if (o == null) { - return hashNullish(o); - } - - if (typeof o.hashCode === 'function') { - // Drop any high bits from accidentally long hash codes. - return smi(o.hashCode(o)); - } - - var v = valueOf(o); - - if (v == null) { - return hashNullish(v); - } - - switch (typeof v) { - case 'boolean': - // The hash values for built-in constants are a 1 value for each 5-byte - // shift region expect for the first, which encodes the value. This - // reduces the odds of a hash collision for these common values. - return v ? 0x42108421 : 0x42108420; - case 'number': - return hashNumber(v); - case 'string': - return v.length > STRING_HASH_CACHE_MIN_STRLEN - ? cachedHashString(v) - : hashString(v); - case 'object': - case 'function': - return hashJSObj(v); - case 'symbol': - return hashSymbol(v); - default: - if (typeof v.toString === 'function') { - return hashString(v.toString()); - } - throw new Error('Value type ' + typeof v + ' cannot be hashed.'); - } -} - -function hashNullish(nullish) { - return nullish === null ? 0x42108422 : /* undefined */ 0x42108423; -} - -// Compress arbitrarily large numbers into smi hashes. -function hashNumber(n) { - if (n !== n || n === Infinity) { - return 0; - } - var hash = n | 0; - if (hash !== n) { - hash ^= n * 0xffffffff; - } - while (n > 0xffffffff) { - n /= 0xffffffff; - hash ^= n; - } - return smi(hash); -} - -function cachedHashString(string) { - var hashed = stringHashCache[string]; - if (hashed === undefined) { - hashed = hashString(string); - if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { - STRING_HASH_CACHE_SIZE = 0; - stringHashCache = {}; - } - STRING_HASH_CACHE_SIZE++; - stringHashCache[string] = hashed; - } - return hashed; -} - -// http://jsperf.com/hashing-strings -function hashString(string) { - // This is the hash from JVM - // The hash code for a string is computed as - // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], - // where s[i] is the ith character of the string and n is the length of - // the string. We "mod" the result to make it between 0 (inclusive) and 2^31 - // (exclusive) by dropping high bits. - var hashed = 0; - for (var ii = 0; ii < string.length; ii++) { - hashed = (31 * hashed + string.charCodeAt(ii)) | 0; - } - return smi(hashed); -} - -function hashSymbol(sym) { - var hashed = symbolMap[sym]; - if (hashed !== undefined) { - return hashed; - } - - hashed = nextHash(); - - symbolMap[sym] = hashed; - - return hashed; -} - -function hashJSObj(obj) { - var hashed; - if (usingWeakMap) { - hashed = weakMap.get(obj); - if (hashed !== undefined) { - return hashed; - } - } - - hashed = obj[UID_HASH_KEY]; - if (hashed !== undefined) { - return hashed; - } - - if (!canDefineProperty) { - hashed = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; - if (hashed !== undefined) { - return hashed; - } - - hashed = getIENodeHash(obj); - if (hashed !== undefined) { - return hashed; - } - } - - hashed = nextHash(); - - if (usingWeakMap) { - weakMap.set(obj, hashed); - } else if (isExtensible !== undefined && isExtensible(obj) === false) { - throw new Error('Non-extensible objects are not allowed as keys.'); - } else if (canDefineProperty) { - Object.defineProperty(obj, UID_HASH_KEY, { - enumerable: false, - configurable: false, - writable: false, - value: hashed, - }); - } else if ( - obj.propertyIsEnumerable !== undefined && - obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable - ) { - // Since we can't define a non-enumerable property on the object - // we'll hijack one of the less-used non-enumerable properties to - // save our hash on it. Since this is a function it will not show up in - // `JSON.stringify` which is what we want. - obj.propertyIsEnumerable = function () { - return this.constructor.prototype.propertyIsEnumerable.apply( - this, - arguments - ); - }; - obj.propertyIsEnumerable[UID_HASH_KEY] = hashed; - } else if (obj.nodeType !== undefined) { - // At this point we couldn't get the IE `uniqueID` to use as a hash - // and we couldn't use a non-enumerable property to exploit the - // dontEnum bug so we simply add the `UID_HASH_KEY` on the node - // itself. - obj[UID_HASH_KEY] = hashed; - } else { - throw new Error('Unable to set a non-enumerable property on object.'); - } - - return hashed; -} - -// Get references to ES5 object methods. -var isExtensible = Object.isExtensible; - -// True if Object.defineProperty works as expected. IE8 fails this test. -var canDefineProperty = (function () { - try { - Object.defineProperty({}, '@', {}); - return true; - } catch (e) { - return false; - } -})(); - -// IE has a `uniqueID` property on DOM nodes. We can construct the hash from it -// and avoid memory leaks from the IE cloneNode bug. -function getIENodeHash(node) { - if (node && node.nodeType > 0) { - switch (node.nodeType) { - case 1: // Element - return node.uniqueID; - case 9: // Document - return node.documentElement && node.documentElement.uniqueID; - } - } -} - -function valueOf(obj) { - return obj.valueOf !== defaultValueOf && typeof obj.valueOf === 'function' - ? obj.valueOf(obj) - : obj; -} - -function nextHash() { - var nextHash = ++_objHashUID; - if (_objHashUID & 0x40000000) { - _objHashUID = 0; - } - return nextHash; -} - -// If possible, use a WeakMap. -var usingWeakMap = typeof WeakMap === 'function'; -var weakMap; -if (usingWeakMap) { - weakMap = new WeakMap(); -} - -var symbolMap = Object.create(null); - -var _objHashUID = 0; - -var UID_HASH_KEY = '__immutablehash__'; -if (typeof Symbol === 'function') { - UID_HASH_KEY = Symbol(UID_HASH_KEY); -} - -var STRING_HASH_CACHE_MIN_STRLEN = 16; -var STRING_HASH_CACHE_MAX_SIZE = 255; -var STRING_HASH_CACHE_SIZE = 0; -var stringHashCache = {}; - -var ToKeyedSequence = /*@__PURE__*/(function (KeyedSeq) { - function ToKeyedSequence(indexed, useKeys) { - this._iter = indexed; - this._useKeys = useKeys; - this.size = indexed.size; - } - - if ( KeyedSeq ) ToKeyedSequence.__proto__ = KeyedSeq; - ToKeyedSequence.prototype = Object.create( KeyedSeq && KeyedSeq.prototype ); - ToKeyedSequence.prototype.constructor = ToKeyedSequence; - - ToKeyedSequence.prototype.get = function get (key, notSetValue) { - return this._iter.get(key, notSetValue); - }; - - ToKeyedSequence.prototype.has = function has (key) { - return this._iter.has(key); - }; - - ToKeyedSequence.prototype.valueSeq = function valueSeq () { - return this._iter.valueSeq(); - }; - - ToKeyedSequence.prototype.reverse = function reverse () { - var this$1$1 = this; - - var reversedSequence = reverseFactory(this, true); - if (!this._useKeys) { - reversedSequence.valueSeq = function () { return this$1$1._iter.toSeq().reverse(); }; - } - return reversedSequence; - }; - - ToKeyedSequence.prototype.map = function map (mapper, context) { - var this$1$1 = this; - - var mappedSequence = mapFactory(this, mapper, context); - if (!this._useKeys) { - mappedSequence.valueSeq = function () { return this$1$1._iter.toSeq().map(mapper, context); }; - } - return mappedSequence; - }; - - ToKeyedSequence.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - return this._iter.__iterate(function (v, k) { return fn(v, k, this$1$1); }, reverse); - }; - - ToKeyedSequence.prototype.__iterator = function __iterator (type, reverse) { - return this._iter.__iterator(type, reverse); - }; - - return ToKeyedSequence; -}(KeyedSeq)); -ToKeyedSequence.prototype[IS_ORDERED_SYMBOL] = true; - -var ToIndexedSequence = /*@__PURE__*/(function (IndexedSeq) { - function ToIndexedSequence(iter) { - this._iter = iter; - this.size = iter.size; - } - - if ( IndexedSeq ) ToIndexedSequence.__proto__ = IndexedSeq; - ToIndexedSequence.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); - ToIndexedSequence.prototype.constructor = ToIndexedSequence; - - ToIndexedSequence.prototype.includes = function includes (value) { - return this._iter.includes(value); - }; - - ToIndexedSequence.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - var i = 0; - reverse && ensureSize(this); - return this._iter.__iterate( - function (v) { return fn(v, reverse ? this$1$1.size - ++i : i++, this$1$1); }, - reverse - ); - }; - - ToIndexedSequence.prototype.__iterator = function __iterator (type, reverse) { - var this$1$1 = this; - - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - var i = 0; - reverse && ensureSize(this); - return new Iterator(function () { - var step = iterator.next(); - return step.done - ? step - : iteratorValue( - type, - reverse ? this$1$1.size - ++i : i++, - step.value, - step - ); - }); - }; - - return ToIndexedSequence; -}(IndexedSeq)); - -var ToSetSequence = /*@__PURE__*/(function (SetSeq) { - function ToSetSequence(iter) { - this._iter = iter; - this.size = iter.size; - } - - if ( SetSeq ) ToSetSequence.__proto__ = SetSeq; - ToSetSequence.prototype = Object.create( SetSeq && SetSeq.prototype ); - ToSetSequence.prototype.constructor = ToSetSequence; - - ToSetSequence.prototype.has = function has (key) { - return this._iter.includes(key); - }; - - ToSetSequence.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - return this._iter.__iterate(function (v) { return fn(v, v, this$1$1); }, reverse); - }; - - ToSetSequence.prototype.__iterator = function __iterator (type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - return new Iterator(function () { - var step = iterator.next(); - return step.done - ? step - : iteratorValue(type, step.value, step.value, step); - }); - }; - - return ToSetSequence; -}(SetSeq)); - -var FromEntriesSequence = /*@__PURE__*/(function (KeyedSeq) { - function FromEntriesSequence(entries) { - this._iter = entries; - this.size = entries.size; - } - - if ( KeyedSeq ) FromEntriesSequence.__proto__ = KeyedSeq; - FromEntriesSequence.prototype = Object.create( KeyedSeq && KeyedSeq.prototype ); - FromEntriesSequence.prototype.constructor = FromEntriesSequence; - - FromEntriesSequence.prototype.entrySeq = function entrySeq () { - return this._iter.toSeq(); - }; - - FromEntriesSequence.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - return this._iter.__iterate(function (entry) { - // Check if entry exists first so array access doesn't throw for holes - // in the parent iteration. - if (entry) { - validateEntry(entry); - var indexedCollection = isCollection(entry); - return fn( - indexedCollection ? entry.get(1) : entry[1], - indexedCollection ? entry.get(0) : entry[0], - this$1$1 - ); - } - }, reverse); - }; - - FromEntriesSequence.prototype.__iterator = function __iterator (type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - return new Iterator(function () { - while (true) { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - // Check if entry exists first so array access doesn't throw for holes - // in the parent iteration. - if (entry) { - validateEntry(entry); - var indexedCollection = isCollection(entry); - return iteratorValue( - type, - indexedCollection ? entry.get(0) : entry[0], - indexedCollection ? entry.get(1) : entry[1], - step - ); - } - } - }); - }; - - return FromEntriesSequence; -}(KeyedSeq)); - -ToIndexedSequence.prototype.cacheResult = - ToKeyedSequence.prototype.cacheResult = - ToSetSequence.prototype.cacheResult = - FromEntriesSequence.prototype.cacheResult = - cacheResultThrough; - -function flipFactory(collection) { - var flipSequence = makeSequence(collection); - flipSequence._iter = collection; - flipSequence.size = collection.size; - flipSequence.flip = function () { return collection; }; - flipSequence.reverse = function () { - var reversedSequence = collection.reverse.apply(this); // super.reverse() - reversedSequence.flip = function () { return collection.reverse(); }; - return reversedSequence; - }; - flipSequence.has = function (key) { return collection.includes(key); }; - flipSequence.includes = function (key) { return collection.has(key); }; - flipSequence.cacheResult = cacheResultThrough; - flipSequence.__iterateUncached = function (fn, reverse) { - var this$1$1 = this; - - return collection.__iterate(function (v, k) { return fn(k, v, this$1$1) !== false; }, reverse); - }; - flipSequence.__iteratorUncached = function (type, reverse) { - if (type === ITERATE_ENTRIES) { - var iterator = collection.__iterator(type, reverse); - return new Iterator(function () { - var step = iterator.next(); - if (!step.done) { - var k = step.value[0]; - step.value[0] = step.value[1]; - step.value[1] = k; - } - return step; - }); - } - return collection.__iterator( - type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, - reverse - ); - }; - return flipSequence; -} - -function mapFactory(collection, mapper, context) { - var mappedSequence = makeSequence(collection); - mappedSequence.size = collection.size; - mappedSequence.has = function (key) { return collection.has(key); }; - mappedSequence.get = function (key, notSetValue) { - var v = collection.get(key, NOT_SET); - return v === NOT_SET - ? notSetValue - : mapper.call(context, v, key, collection); - }; - mappedSequence.__iterateUncached = function (fn, reverse) { - var this$1$1 = this; - - return collection.__iterate( - function (v, k, c) { return fn(mapper.call(context, v, k, c), k, this$1$1) !== false; }, - reverse - ); - }; - mappedSequence.__iteratorUncached = function (type, reverse) { - var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); - return new Iterator(function () { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - return iteratorValue( - type, - key, - mapper.call(context, entry[1], key, collection), - step - ); - }); - }; - return mappedSequence; -} - -function reverseFactory(collection, useKeys) { - var this$1$1 = this; - - var reversedSequence = makeSequence(collection); - reversedSequence._iter = collection; - reversedSequence.size = collection.size; - reversedSequence.reverse = function () { return collection; }; - if (collection.flip) { - reversedSequence.flip = function () { - var flipSequence = flipFactory(collection); - flipSequence.reverse = function () { return collection.flip(); }; - return flipSequence; - }; - } - reversedSequence.get = function (key, notSetValue) { return collection.get(useKeys ? key : -1 - key, notSetValue); }; - reversedSequence.has = function (key) { return collection.has(useKeys ? key : -1 - key); }; - reversedSequence.includes = function (value) { return collection.includes(value); }; - reversedSequence.cacheResult = cacheResultThrough; - reversedSequence.__iterate = function (fn, reverse) { - var this$1$1 = this; - - var i = 0; - reverse && ensureSize(collection); - return collection.__iterate( - function (v, k) { return fn(v, useKeys ? k : reverse ? this$1$1.size - ++i : i++, this$1$1); }, - !reverse - ); - }; - reversedSequence.__iterator = function (type, reverse) { - var i = 0; - reverse && ensureSize(collection); - var iterator = collection.__iterator(ITERATE_ENTRIES, !reverse); - return new Iterator(function () { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - return iteratorValue( - type, - useKeys ? entry[0] : reverse ? this$1$1.size - ++i : i++, - entry[1], - step - ); - }); - }; - return reversedSequence; -} - -function filterFactory(collection, predicate, context, useKeys) { - var filterSequence = makeSequence(collection); - if (useKeys) { - filterSequence.has = function (key) { - var v = collection.get(key, NOT_SET); - return v !== NOT_SET && !!predicate.call(context, v, key, collection); - }; - filterSequence.get = function (key, notSetValue) { - var v = collection.get(key, NOT_SET); - return v !== NOT_SET && predicate.call(context, v, key, collection) - ? v - : notSetValue; - }; - } - filterSequence.__iterateUncached = function (fn, reverse) { - var this$1$1 = this; - - var iterations = 0; - collection.__iterate(function (v, k, c) { - if (predicate.call(context, v, k, c)) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this$1$1); - } - }, reverse); - return iterations; - }; - filterSequence.__iteratorUncached = function (type, reverse) { - var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); - var iterations = 0; - return new Iterator(function () { - while (true) { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - var value = entry[1]; - if (predicate.call(context, value, key, collection)) { - return iteratorValue(type, useKeys ? key : iterations++, value, step); - } - } - }); - }; - return filterSequence; -} - -function countByFactory(collection, grouper, context) { - var groups = Map().asMutable(); - collection.__iterate(function (v, k) { - groups.update(grouper.call(context, v, k, collection), 0, function (a) { return a + 1; }); - }); - return groups.asImmutable(); -} - -function groupByFactory(collection, grouper, context) { - var isKeyedIter = isKeyed(collection); - var groups = (isOrdered(collection) ? OrderedMap() : Map()).asMutable(); - collection.__iterate(function (v, k) { - groups.update( - grouper.call(context, v, k, collection), - function (a) { return ((a = a || []), a.push(isKeyedIter ? [k, v] : v), a); } - ); - }); - var coerce = collectionClass(collection); - return groups.map(function (arr) { return reify(collection, coerce(arr)); }).asImmutable(); -} - -function partitionFactory(collection, predicate, context) { - var isKeyedIter = isKeyed(collection); - var groups = [[], []]; - collection.__iterate(function (v, k) { - groups[predicate.call(context, v, k, collection) ? 1 : 0].push( - isKeyedIter ? [k, v] : v - ); - }); - var coerce = collectionClass(collection); - return groups.map(function (arr) { return reify(collection, coerce(arr)); }); -} - -function sliceFactory(collection, begin, end, useKeys) { - var originalSize = collection.size; - - if (wholeSlice(begin, end, originalSize)) { - return collection; - } - - // begin or end can not be resolved if they were provided as negative numbers and - // this collection's size is unknown. In that case, cache first so there is - // a known size and these do not resolve to NaN. - if (typeof originalSize === 'undefined' && (begin < 0 || end < 0)) { - return sliceFactory(collection.toSeq().cacheResult(), begin, end, useKeys); - } - - var resolvedBegin = resolveBegin(begin, originalSize); - var resolvedEnd = resolveEnd(end, originalSize); - - // Note: resolvedEnd is undefined when the original sequence's length is - // unknown and this slice did not supply an end and should contain all - // elements after resolvedBegin. - // In that case, resolvedSize will be NaN and sliceSize will remain undefined. - var resolvedSize = resolvedEnd - resolvedBegin; - var sliceSize; - if (resolvedSize === resolvedSize) { - sliceSize = resolvedSize < 0 ? 0 : resolvedSize; - } - - var sliceSeq = makeSequence(collection); - - // If collection.size is undefined, the size of the realized sliceSeq is - // unknown at this point unless the number of items to slice is 0 - sliceSeq.size = - sliceSize === 0 ? sliceSize : (collection.size && sliceSize) || undefined; - - if (!useKeys && isSeq(collection) && sliceSize >= 0) { - sliceSeq.get = function (index, notSetValue) { - index = wrapIndex(this, index); - return index >= 0 && index < sliceSize - ? collection.get(index + resolvedBegin, notSetValue) - : notSetValue; - }; - } - - sliceSeq.__iterateUncached = function (fn, reverse) { - var this$1$1 = this; - - if (sliceSize === 0) { - return 0; - } - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var skipped = 0; - var isSkipping = true; - var iterations = 0; - collection.__iterate(function (v, k) { - if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { - iterations++; - return ( - fn(v, useKeys ? k : iterations - 1, this$1$1) !== false && - iterations !== sliceSize - ); - } - }); - return iterations; - }; - - sliceSeq.__iteratorUncached = function (type, reverse) { - if (sliceSize !== 0 && reverse) { - return this.cacheResult().__iterator(type, reverse); - } - // Don't bother instantiating parent iterator if taking 0. - if (sliceSize === 0) { - return new Iterator(iteratorDone); - } - var iterator = collection.__iterator(type, reverse); - var skipped = 0; - var iterations = 0; - return new Iterator(function () { - while (skipped++ < resolvedBegin) { - iterator.next(); - } - if (++iterations > sliceSize) { - return iteratorDone(); - } - var step = iterator.next(); - if (useKeys || type === ITERATE_VALUES || step.done) { - return step; - } - if (type === ITERATE_KEYS) { - return iteratorValue(type, iterations - 1, undefined, step); - } - return iteratorValue(type, iterations - 1, step.value[1], step); - }); - }; - - return sliceSeq; -} - -function takeWhileFactory(collection, predicate, context) { - var takeSequence = makeSequence(collection); - takeSequence.__iterateUncached = function (fn, reverse) { - var this$1$1 = this; - - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - collection.__iterate( - function (v, k, c) { return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$1$1); } - ); - return iterations; - }; - takeSequence.__iteratorUncached = function (type, reverse) { - var this$1$1 = this; - - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); - var iterating = true; - return new Iterator(function () { - if (!iterating) { - return iteratorDone(); - } - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var k = entry[0]; - var v = entry[1]; - if (!predicate.call(context, v, k, this$1$1)) { - iterating = false; - return iteratorDone(); - } - return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); - }); - }; - return takeSequence; -} - -function skipWhileFactory(collection, predicate, context, useKeys) { - var skipSequence = makeSequence(collection); - skipSequence.__iterateUncached = function (fn, reverse) { - var this$1$1 = this; - - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var isSkipping = true; - var iterations = 0; - collection.__iterate(function (v, k, c) { - if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this$1$1); - } - }); - return iterations; - }; - skipSequence.__iteratorUncached = function (type, reverse) { - var this$1$1 = this; - - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = collection.__iterator(ITERATE_ENTRIES, reverse); - var skipping = true; - var iterations = 0; - return new Iterator(function () { - var step; - var k; - var v; - do { - step = iterator.next(); - if (step.done) { - if (useKeys || type === ITERATE_VALUES) { - return step; - } - if (type === ITERATE_KEYS) { - return iteratorValue(type, iterations++, undefined, step); - } - return iteratorValue(type, iterations++, step.value[1], step); - } - var entry = step.value; - k = entry[0]; - v = entry[1]; - skipping && (skipping = predicate.call(context, v, k, this$1$1)); - } while (skipping); - return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); - }); - }; - return skipSequence; -} - -function concatFactory(collection, values) { - var isKeyedCollection = isKeyed(collection); - var iters = [collection] - .concat(values) - .map(function (v) { - if (!isCollection(v)) { - v = isKeyedCollection - ? keyedSeqFromValue(v) - : indexedSeqFromValue(Array.isArray(v) ? v : [v]); - } else if (isKeyedCollection) { - v = KeyedCollection(v); - } - return v; - }) - .filter(function (v) { return v.size !== 0; }); - - if (iters.length === 0) { - return collection; - } - - if (iters.length === 1) { - var singleton = iters[0]; - if ( - singleton === collection || - (isKeyedCollection && isKeyed(singleton)) || - (isIndexed(collection) && isIndexed(singleton)) - ) { - return singleton; - } - } - - var concatSeq = new ArraySeq(iters); - if (isKeyedCollection) { - concatSeq = concatSeq.toKeyedSeq(); - } else if (!isIndexed(collection)) { - concatSeq = concatSeq.toSetSeq(); - } - concatSeq = concatSeq.flatten(true); - concatSeq.size = iters.reduce(function (sum, seq) { - if (sum !== undefined) { - var size = seq.size; - if (size !== undefined) { - return sum + size; - } - } - }, 0); - return concatSeq; -} - -function flattenFactory(collection, depth, useKeys) { - var flatSequence = makeSequence(collection); - flatSequence.__iterateUncached = function (fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - var stopped = false; - function flatDeep(iter, currentDepth) { - iter.__iterate(function (v, k) { - if ((!depth || currentDepth < depth) && isCollection(v)) { - flatDeep(v, currentDepth + 1); - } else { - iterations++; - if (fn(v, useKeys ? k : iterations - 1, flatSequence) === false) { - stopped = true; - } - } - return !stopped; - }, reverse); - } - flatDeep(collection, 0); - return iterations; - }; - flatSequence.__iteratorUncached = function (type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = collection.__iterator(type, reverse); - var stack = []; - var iterations = 0; - return new Iterator(function () { - while (iterator) { - var step = iterator.next(); - if (step.done !== false) { - iterator = stack.pop(); - continue; - } - var v = step.value; - if (type === ITERATE_ENTRIES) { - v = v[1]; - } - if ((!depth || stack.length < depth) && isCollection(v)) { - stack.push(iterator); - iterator = v.__iterator(type, reverse); - } else { - return useKeys ? step : iteratorValue(type, iterations++, v, step); - } - } - return iteratorDone(); - }); - }; - return flatSequence; -} - -function flatMapFactory(collection, mapper, context) { - var coerce = collectionClass(collection); - return collection - .toSeq() - .map(function (v, k) { return coerce(mapper.call(context, v, k, collection)); }) - .flatten(true); -} - -function interposeFactory(collection, separator) { - var interposedSequence = makeSequence(collection); - interposedSequence.size = collection.size && collection.size * 2 - 1; - interposedSequence.__iterateUncached = function (fn, reverse) { - var this$1$1 = this; - - var iterations = 0; - collection.__iterate( - function (v) { return (!iterations || fn(separator, iterations++, this$1$1) !== false) && - fn(v, iterations++, this$1$1) !== false; }, - reverse - ); - return iterations; - }; - interposedSequence.__iteratorUncached = function (type, reverse) { - var iterator = collection.__iterator(ITERATE_VALUES, reverse); - var iterations = 0; - var step; - return new Iterator(function () { - if (!step || iterations % 2) { - step = iterator.next(); - if (step.done) { - return step; - } - } - return iterations % 2 - ? iteratorValue(type, iterations++, separator) - : iteratorValue(type, iterations++, step.value, step); - }); - }; - return interposedSequence; -} - -function sortFactory(collection, comparator, mapper) { - if (!comparator) { - comparator = defaultComparator; - } - var isKeyedCollection = isKeyed(collection); - var index = 0; - var entries = collection - .toSeq() - .map(function (v, k) { return [k, v, index++, mapper ? mapper(v, k, collection) : v]; }) - .valueSeq() - .toArray(); - entries - .sort(function (a, b) { return comparator(a[3], b[3]) || a[2] - b[2]; }) - .forEach( - isKeyedCollection - ? function (v, i) { - entries[i].length = 2; - } - : function (v, i) { - entries[i] = v[1]; - } - ); - return isKeyedCollection - ? KeyedSeq(entries) - : isIndexed(collection) - ? IndexedSeq(entries) - : SetSeq(entries); -} - -function maxFactory(collection, comparator, mapper) { - if (!comparator) { - comparator = defaultComparator; - } - if (mapper) { - var entry = collection - .toSeq() - .map(function (v, k) { return [v, mapper(v, k, collection)]; }) - .reduce(function (a, b) { return (maxCompare(comparator, a[1], b[1]) ? b : a); }); - return entry && entry[0]; - } - return collection.reduce(function (a, b) { return (maxCompare(comparator, a, b) ? b : a); }); -} - -function maxCompare(comparator, a, b) { - var comp = comparator(b, a); - // b is considered the new max if the comparator declares them equal, but - // they are not equal and b is in fact a nullish value. - return ( - (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || - comp > 0 - ); -} - -function zipWithFactory(keyIter, zipper, iters, zipAll) { - var zipSequence = makeSequence(keyIter); - var sizes = new ArraySeq(iters).map(function (i) { return i.size; }); - zipSequence.size = zipAll ? sizes.max() : sizes.min(); - // Note: this a generic base implementation of __iterate in terms of - // __iterator which may be more generically useful in the future. - zipSequence.__iterate = function (fn, reverse) { - /* generic: - var iterator = this.__iterator(ITERATE_ENTRIES, reverse); - var step; - var iterations = 0; - while (!(step = iterator.next()).done) { - iterations++; - if (fn(step.value[1], step.value[0], this) === false) { - break; - } - } - return iterations; - */ - // indexed: - var iterator = this.__iterator(ITERATE_VALUES, reverse); - var step; - var iterations = 0; - while (!(step = iterator.next()).done) { - if (fn(step.value, iterations++, this) === false) { - break; - } - } - return iterations; - }; - zipSequence.__iteratorUncached = function (type, reverse) { - var iterators = iters.map( - function (i) { return ((i = Collection(i)), getIterator(reverse ? i.reverse() : i)); } - ); - var iterations = 0; - var isDone = false; - return new Iterator(function () { - var steps; - if (!isDone) { - steps = iterators.map(function (i) { return i.next(); }); - isDone = zipAll ? steps.every(function (s) { return s.done; }) : steps.some(function (s) { return s.done; }); - } - if (isDone) { - return iteratorDone(); - } - return iteratorValue( - type, - iterations++, - zipper.apply( - null, - steps.map(function (s) { return s.value; }) - ) - ); - }); - }; - return zipSequence; -} - -// #pragma Helper Functions - -function reify(iter, seq) { - return iter === seq ? iter : isSeq(iter) ? seq : iter.constructor(seq); -} - -function validateEntry(entry) { - if (entry !== Object(entry)) { - throw new TypeError('Expected [K, V] tuple: ' + entry); - } -} - -function collectionClass(collection) { - return isKeyed(collection) - ? KeyedCollection - : isIndexed(collection) - ? IndexedCollection - : SetCollection; -} - -function makeSequence(collection) { - return Object.create( - (isKeyed(collection) - ? KeyedSeq - : isIndexed(collection) - ? IndexedSeq - : SetSeq - ).prototype - ); -} - -function cacheResultThrough() { - if (this._iter.cacheResult) { - this._iter.cacheResult(); - this.size = this._iter.size; - return this; - } - return Seq.prototype.cacheResult.call(this); -} - -function defaultComparator(a, b) { - if (a === undefined && b === undefined) { - return 0; - } - - if (a === undefined) { - return 1; - } - - if (b === undefined) { - return -1; - } - - return a > b ? 1 : a < b ? -1 : 0; -} - -function arrCopy(arr, offset) { - offset = offset || 0; - var len = Math.max(0, arr.length - offset); - var newArr = new Array(len); - for (var ii = 0; ii < len; ii++) { - newArr[ii] = arr[ii + offset]; - } - return newArr; -} - -function invariant(condition, error) { - if (!condition) { throw new Error(error); } -} - -function assertNotInfinite(size) { - invariant( - size !== Infinity, - 'Cannot perform this action with an infinite size.' - ); -} - -function coerceKeyPath(keyPath) { - if (isArrayLike(keyPath) && typeof keyPath !== 'string') { - return keyPath; - } - if (isOrdered(keyPath)) { - return keyPath.toArray(); - } - throw new TypeError( - 'Invalid keyPath: expected Ordered Collection or Array: ' + keyPath - ); -} - -var toString = Object.prototype.toString; - -function isPlainObject(value) { - // The base prototype's toString deals with Argument objects and native namespaces like Math - if ( - !value || - typeof value !== 'object' || - toString.call(value) !== '[object Object]' - ) { - return false; - } - - var proto = Object.getPrototypeOf(value); - if (proto === null) { - return true; - } - - // Iteratively going up the prototype chain is needed for cross-realm environments (differing contexts, iframes, etc) - var parentProto = proto; - var nextProto = Object.getPrototypeOf(proto); - while (nextProto !== null) { - parentProto = nextProto; - nextProto = Object.getPrototypeOf(parentProto); - } - return parentProto === proto; -} - -/** - * Returns true if the value is a potentially-persistent data structure, either - * provided by Immutable.js or a plain Array or Object. - */ -function isDataStructure(value) { - return ( - typeof value === 'object' && - (isImmutable(value) || Array.isArray(value) || isPlainObject(value)) - ); -} - -function quoteString(value) { - try { - return typeof value === 'string' ? JSON.stringify(value) : String(value); - } catch (_ignoreError) { - return JSON.stringify(value); - } -} - -function has(collection, key) { - return isImmutable(collection) - ? collection.has(key) - : isDataStructure(collection) && hasOwnProperty.call(collection, key); -} - -function get(collection, key, notSetValue) { - return isImmutable(collection) - ? collection.get(key, notSetValue) - : !has(collection, key) - ? notSetValue - : typeof collection.get === 'function' - ? collection.get(key) - : collection[key]; -} - -function shallowCopy(from) { - if (Array.isArray(from)) { - return arrCopy(from); - } - var to = {}; - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } - return to; -} - -function remove(collection, key) { - if (!isDataStructure(collection)) { - throw new TypeError( - 'Cannot update non-data-structure value: ' + collection - ); - } - if (isImmutable(collection)) { - if (!collection.remove) { - throw new TypeError( - 'Cannot update immutable value without .remove() method: ' + collection - ); - } - return collection.remove(key); - } - if (!hasOwnProperty.call(collection, key)) { - return collection; - } - var collectionCopy = shallowCopy(collection); - if (Array.isArray(collectionCopy)) { - collectionCopy.splice(key, 1); - } else { - delete collectionCopy[key]; - } - return collectionCopy; -} - -function set(collection, key, value) { - if (!isDataStructure(collection)) { - throw new TypeError( - 'Cannot update non-data-structure value: ' + collection - ); - } - if (isImmutable(collection)) { - if (!collection.set) { - throw new TypeError( - 'Cannot update immutable value without .set() method: ' + collection - ); - } - return collection.set(key, value); - } - if (hasOwnProperty.call(collection, key) && value === collection[key]) { - return collection; - } - var collectionCopy = shallowCopy(collection); - collectionCopy[key] = value; - return collectionCopy; -} - -function updateIn$1(collection, keyPath, notSetValue, updater) { - if (!updater) { - updater = notSetValue; - notSetValue = undefined; - } - var updatedValue = updateInDeeply( - isImmutable(collection), - collection, - coerceKeyPath(keyPath), - 0, - notSetValue, - updater - ); - return updatedValue === NOT_SET ? notSetValue : updatedValue; -} - -function updateInDeeply( - inImmutable, - existing, - keyPath, - i, - notSetValue, - updater -) { - var wasNotSet = existing === NOT_SET; - if (i === keyPath.length) { - var existingValue = wasNotSet ? notSetValue : existing; - var newValue = updater(existingValue); - return newValue === existingValue ? existing : newValue; - } - if (!wasNotSet && !isDataStructure(existing)) { - throw new TypeError( - 'Cannot update within non-data-structure value in path [' + - keyPath.slice(0, i).map(quoteString) + - ']: ' + - existing - ); - } - var key = keyPath[i]; - var nextExisting = wasNotSet ? NOT_SET : get(existing, key, NOT_SET); - var nextUpdated = updateInDeeply( - nextExisting === NOT_SET ? inImmutable : isImmutable(nextExisting), - nextExisting, - keyPath, - i + 1, - notSetValue, - updater - ); - return nextUpdated === nextExisting - ? existing - : nextUpdated === NOT_SET - ? remove(existing, key) - : set( - wasNotSet ? (inImmutable ? emptyMap() : {}) : existing, - key, - nextUpdated - ); -} - -function setIn$1(collection, keyPath, value) { - return updateIn$1(collection, keyPath, NOT_SET, function () { return value; }); -} - -function setIn(keyPath, v) { - return setIn$1(this, keyPath, v); -} - -function removeIn(collection, keyPath) { - return updateIn$1(collection, keyPath, function () { return NOT_SET; }); -} - -function deleteIn(keyPath) { - return removeIn(this, keyPath); -} - -function update$1(collection, key, notSetValue, updater) { - return updateIn$1(collection, [key], notSetValue, updater); -} - -function update(key, notSetValue, updater) { - return arguments.length === 1 - ? key(this) - : update$1(this, key, notSetValue, updater); -} - -function updateIn(keyPath, notSetValue, updater) { - return updateIn$1(this, keyPath, notSetValue, updater); -} - -function merge$1() { - var iters = [], len = arguments.length; - while ( len-- ) iters[ len ] = arguments[ len ]; - - return mergeIntoKeyedWith(this, iters); -} - -function mergeWith$1(merger) { - var iters = [], len = arguments.length - 1; - while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; - - if (typeof merger !== 'function') { - throw new TypeError('Invalid merger function: ' + merger); - } - return mergeIntoKeyedWith(this, iters, merger); -} - -function mergeIntoKeyedWith(collection, collections, merger) { - var iters = []; - for (var ii = 0; ii < collections.length; ii++) { - var collection$1 = KeyedCollection(collections[ii]); - if (collection$1.size !== 0) { - iters.push(collection$1); - } - } - if (iters.length === 0) { - return collection; - } - if ( - collection.toSeq().size === 0 && - !collection.__ownerID && - iters.length === 1 - ) { - return collection.constructor(iters[0]); - } - return collection.withMutations(function (collection) { - var mergeIntoCollection = merger - ? function (value, key) { - update$1(collection, key, NOT_SET, function (oldVal) { return oldVal === NOT_SET ? value : merger(oldVal, value, key); } - ); - } - : function (value, key) { - collection.set(key, value); - }; - for (var ii = 0; ii < iters.length; ii++) { - iters[ii].forEach(mergeIntoCollection); - } - }); -} - -function merge(collection) { - var sources = [], len = arguments.length - 1; - while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; - - return mergeWithSources(collection, sources); -} - -function mergeWith(merger, collection) { - var sources = [], len = arguments.length - 2; - while ( len-- > 0 ) sources[ len ] = arguments[ len + 2 ]; - - return mergeWithSources(collection, sources, merger); -} - -function mergeDeep$1(collection) { - var sources = [], len = arguments.length - 1; - while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; - - return mergeDeepWithSources(collection, sources); -} - -function mergeDeepWith$1(merger, collection) { - var sources = [], len = arguments.length - 2; - while ( len-- > 0 ) sources[ len ] = arguments[ len + 2 ]; - - return mergeDeepWithSources(collection, sources, merger); -} - -function mergeDeepWithSources(collection, sources, merger) { - return mergeWithSources(collection, sources, deepMergerWith(merger)); -} - -function mergeWithSources(collection, sources, merger) { - if (!isDataStructure(collection)) { - throw new TypeError( - 'Cannot merge into non-data-structure value: ' + collection - ); - } - if (isImmutable(collection)) { - return typeof merger === 'function' && collection.mergeWith - ? collection.mergeWith.apply(collection, [ merger ].concat( sources )) - : collection.merge - ? collection.merge.apply(collection, sources) - : collection.concat.apply(collection, sources); - } - var isArray = Array.isArray(collection); - var merged = collection; - var Collection = isArray ? IndexedCollection : KeyedCollection; - var mergeItem = isArray - ? function (value) { - // Copy on write - if (merged === collection) { - merged = shallowCopy(merged); - } - merged.push(value); - } - : function (value, key) { - var hasVal = hasOwnProperty.call(merged, key); - var nextVal = - hasVal && merger ? merger(merged[key], value, key) : value; - if (!hasVal || nextVal !== merged[key]) { - // Copy on write - if (merged === collection) { - merged = shallowCopy(merged); - } - merged[key] = nextVal; - } - }; - for (var i = 0; i < sources.length; i++) { - Collection(sources[i]).forEach(mergeItem); - } - return merged; -} - -function deepMergerWith(merger) { - function deepMerger(oldValue, newValue, key) { - return isDataStructure(oldValue) && - isDataStructure(newValue) && - areMergeable(oldValue, newValue) - ? mergeWithSources(oldValue, [newValue], deepMerger) - : merger - ? merger(oldValue, newValue, key) - : newValue; - } - return deepMerger; -} - -/** - * It's unclear what the desired behavior is for merging two collections that - * fall into separate categories between keyed, indexed, or set-like, so we only - * consider them mergeable if they fall into the same category. - */ -function areMergeable(oldDataStructure, newDataStructure) { - var oldSeq = Seq(oldDataStructure); - var newSeq = Seq(newDataStructure); - // This logic assumes that a sequence can only fall into one of the three - // categories mentioned above (since there's no `isSetLike()` method). - return ( - isIndexed(oldSeq) === isIndexed(newSeq) && - isKeyed(oldSeq) === isKeyed(newSeq) - ); -} - -function mergeDeep() { - var iters = [], len = arguments.length; - while ( len-- ) iters[ len ] = arguments[ len ]; - - return mergeDeepWithSources(this, iters); -} - -function mergeDeepWith(merger) { - var iters = [], len = arguments.length - 1; - while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; - - return mergeDeepWithSources(this, iters, merger); -} - -function mergeIn(keyPath) { - var iters = [], len = arguments.length - 1; - while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; - - return updateIn$1(this, keyPath, emptyMap(), function (m) { return mergeWithSources(m, iters); }); -} - -function mergeDeepIn(keyPath) { - var iters = [], len = arguments.length - 1; - while ( len-- > 0 ) iters[ len ] = arguments[ len + 1 ]; - - return updateIn$1(this, keyPath, emptyMap(), function (m) { return mergeDeepWithSources(m, iters); } - ); -} - -function withMutations(fn) { - var mutable = this.asMutable(); - fn(mutable); - return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; -} - -function asMutable() { - return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); -} - -function asImmutable() { - return this.__ensureOwner(); -} - -function wasAltered() { - return this.__altered; -} - -var Map = /*@__PURE__*/(function (KeyedCollection) { - function Map(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptyMap() - : isMap(value) && !isOrdered(value) - ? value - : emptyMap().withMutations(function (map) { - var iter = KeyedCollection(value); - assertNotInfinite(iter.size); - iter.forEach(function (v, k) { return map.set(k, v); }); - }); - } - - if ( KeyedCollection ) Map.__proto__ = KeyedCollection; - Map.prototype = Object.create( KeyedCollection && KeyedCollection.prototype ); - Map.prototype.constructor = Map; - - Map.of = function of () { - var keyValues = [], len = arguments.length; - while ( len-- ) keyValues[ len ] = arguments[ len ]; - - return emptyMap().withMutations(function (map) { - for (var i = 0; i < keyValues.length; i += 2) { - if (i + 1 >= keyValues.length) { - throw new Error('Missing value for key: ' + keyValues[i]); - } - map.set(keyValues[i], keyValues[i + 1]); - } - }); - }; - - Map.prototype.toString = function toString () { - return this.__toString('Map {', '}'); - }; - - // @pragma Access - - Map.prototype.get = function get (k, notSetValue) { - return this._root - ? this._root.get(0, undefined, k, notSetValue) - : notSetValue; - }; - - // @pragma Modification - - Map.prototype.set = function set (k, v) { - return updateMap(this, k, v); - }; - - Map.prototype.remove = function remove (k) { - return updateMap(this, k, NOT_SET); - }; - - Map.prototype.deleteAll = function deleteAll (keys) { - var collection = Collection(keys); - - if (collection.size === 0) { - return this; - } - - return this.withMutations(function (map) { - collection.forEach(function (key) { return map.remove(key); }); - }); - }; - - Map.prototype.clear = function clear () { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = 0; - this._root = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyMap(); - }; - - // @pragma Composition - - Map.prototype.sort = function sort (comparator) { - // Late binding - return OrderedMap(sortFactory(this, comparator)); - }; - - Map.prototype.sortBy = function sortBy (mapper, comparator) { - // Late binding - return OrderedMap(sortFactory(this, comparator, mapper)); - }; - - Map.prototype.map = function map (mapper, context) { - var this$1$1 = this; - - return this.withMutations(function (map) { - map.forEach(function (value, key) { - map.set(key, mapper.call(context, value, key, this$1$1)); - }); - }); - }; - - // @pragma Mutability - - Map.prototype.__iterator = function __iterator (type, reverse) { - return new MapIterator(this, type, reverse); - }; - - Map.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - var iterations = 0; - this._root && - this._root.iterate(function (entry) { - iterations++; - return fn(entry[1], entry[0], this$1$1); - }, reverse); - return iterations; - }; - - Map.prototype.__ensureOwner = function __ensureOwner (ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - if (this.size === 0) { - return emptyMap(); - } - this.__ownerID = ownerID; - this.__altered = false; - return this; - } - return makeMap(this.size, this._root, ownerID, this.__hash); - }; - - return Map; -}(KeyedCollection)); - -Map.isMap = isMap; - -var MapPrototype = Map.prototype; -MapPrototype[IS_MAP_SYMBOL] = true; -MapPrototype[DELETE] = MapPrototype.remove; -MapPrototype.removeAll = MapPrototype.deleteAll; -MapPrototype.setIn = setIn; -MapPrototype.removeIn = MapPrototype.deleteIn = deleteIn; -MapPrototype.update = update; -MapPrototype.updateIn = updateIn; -MapPrototype.merge = MapPrototype.concat = merge$1; -MapPrototype.mergeWith = mergeWith$1; -MapPrototype.mergeDeep = mergeDeep; -MapPrototype.mergeDeepWith = mergeDeepWith; -MapPrototype.mergeIn = mergeIn; -MapPrototype.mergeDeepIn = mergeDeepIn; -MapPrototype.withMutations = withMutations; -MapPrototype.wasAltered = wasAltered; -MapPrototype.asImmutable = asImmutable; -MapPrototype['@@transducer/init'] = MapPrototype.asMutable = asMutable; -MapPrototype['@@transducer/step'] = function (result, arr) { - return result.set(arr[0], arr[1]); -}; -MapPrototype['@@transducer/result'] = function (obj) { - return obj.asImmutable(); -}; - -// #pragma Trie Nodes - -var ArrayMapNode = function ArrayMapNode(ownerID, entries) { - this.ownerID = ownerID; - this.entries = entries; -}; - -ArrayMapNode.prototype.get = function get (shift, keyHash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, len = entries.length; ii < len; ii++) { - if (is(key, entries[ii][0])) { - return entries[ii][1]; - } - } - return notSetValue; -}; - -ArrayMapNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - var removed = value === NOT_SET; - - var entries = this.entries; - var idx = 0; - var len = entries.length; - for (; idx < len; idx++) { - if (is(key, entries[idx][0])) { - break; - } - } - var exists = idx < len; - - if (exists ? entries[idx][1] === value : removed) { - return this; - } - - SetRef(didAlter); - (removed || !exists) && SetRef(didChangeSize); - - if (removed && entries.length === 1) { - return; // undefined - } - - if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { - return createNodes(ownerID, entries, key, value); - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); - - if (exists) { - if (removed) { - idx === len - 1 - ? newEntries.pop() - : (newEntries[idx] = newEntries.pop()); - } else { - newEntries[idx] = [key, value]; - } - } else { - newEntries.push([key, value]); - } - - if (isEditable) { - this.entries = newEntries; - return this; - } - - return new ArrayMapNode(ownerID, newEntries); -}; - -var BitmapIndexedNode = function BitmapIndexedNode(ownerID, bitmap, nodes) { - this.ownerID = ownerID; - this.bitmap = bitmap; - this.nodes = nodes; -}; - -BitmapIndexedNode.prototype.get = function get (shift, keyHash, key, notSetValue) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var bit = 1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK); - var bitmap = this.bitmap; - return (bitmap & bit) === 0 - ? notSetValue - : this.nodes[popCount(bitmap & (bit - 1))].get( - shift + SHIFT, - keyHash, - key, - notSetValue - ); -}; - -BitmapIndexedNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var bit = 1 << keyHashFrag; - var bitmap = this.bitmap; - var exists = (bitmap & bit) !== 0; - - if (!exists && value === NOT_SET) { - return this; - } - - var idx = popCount(bitmap & (bit - 1)); - var nodes = this.nodes; - var node = exists ? nodes[idx] : undefined; - var newNode = updateNode( - node, - ownerID, - shift + SHIFT, - keyHash, - key, - value, - didChangeSize, - didAlter - ); - - if (newNode === node) { - return this; - } - - if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { - return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); - } - - if ( - exists && - !newNode && - nodes.length === 2 && - isLeafNode(nodes[idx ^ 1]) - ) { - return nodes[idx ^ 1]; - } - - if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { - return newNode; - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newBitmap = exists ? (newNode ? bitmap : bitmap ^ bit) : bitmap | bit; - var newNodes = exists - ? newNode - ? setAt(nodes, idx, newNode, isEditable) - : spliceOut(nodes, idx, isEditable) - : spliceIn(nodes, idx, newNode, isEditable); - - if (isEditable) { - this.bitmap = newBitmap; - this.nodes = newNodes; - return this; - } - - return new BitmapIndexedNode(ownerID, newBitmap, newNodes); -}; - -var HashArrayMapNode = function HashArrayMapNode(ownerID, count, nodes) { - this.ownerID = ownerID; - this.count = count; - this.nodes = nodes; -}; - -HashArrayMapNode.prototype.get = function get (shift, keyHash, key, notSetValue) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var node = this.nodes[idx]; - return node - ? node.get(shift + SHIFT, keyHash, key, notSetValue) - : notSetValue; -}; - -HashArrayMapNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var removed = value === NOT_SET; - var nodes = this.nodes; - var node = nodes[idx]; - - if (removed && !node) { - return this; - } - - var newNode = updateNode( - node, - ownerID, - shift + SHIFT, - keyHash, - key, - value, - didChangeSize, - didAlter - ); - if (newNode === node) { - return this; - } - - var newCount = this.count; - if (!node) { - newCount++; - } else if (!newNode) { - newCount--; - if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { - return packNodes(ownerID, nodes, newCount, idx); - } - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newNodes = setAt(nodes, idx, newNode, isEditable); - - if (isEditable) { - this.count = newCount; - this.nodes = newNodes; - return this; - } - - return new HashArrayMapNode(ownerID, newCount, newNodes); -}; - -var HashCollisionNode = function HashCollisionNode(ownerID, keyHash, entries) { - this.ownerID = ownerID; - this.keyHash = keyHash; - this.entries = entries; -}; - -HashCollisionNode.prototype.get = function get (shift, keyHash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, len = entries.length; ii < len; ii++) { - if (is(key, entries[ii][0])) { - return entries[ii][1]; - } - } - return notSetValue; -}; - -HashCollisionNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - - var removed = value === NOT_SET; - - if (keyHash !== this.keyHash) { - if (removed) { - return this; - } - SetRef(didAlter); - SetRef(didChangeSize); - return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); - } - - var entries = this.entries; - var idx = 0; - var len = entries.length; - for (; idx < len; idx++) { - if (is(key, entries[idx][0])) { - break; - } - } - var exists = idx < len; - - if (exists ? entries[idx][1] === value : removed) { - return this; - } - - SetRef(didAlter); - (removed || !exists) && SetRef(didChangeSize); - - if (removed && len === 2) { - return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); - - if (exists) { - if (removed) { - idx === len - 1 - ? newEntries.pop() - : (newEntries[idx] = newEntries.pop()); - } else { - newEntries[idx] = [key, value]; - } - } else { - newEntries.push([key, value]); - } - - if (isEditable) { - this.entries = newEntries; - return this; - } - - return new HashCollisionNode(ownerID, this.keyHash, newEntries); -}; - -var ValueNode = function ValueNode(ownerID, keyHash, entry) { - this.ownerID = ownerID; - this.keyHash = keyHash; - this.entry = entry; -}; - -ValueNode.prototype.get = function get (shift, keyHash, key, notSetValue) { - return is(key, this.entry[0]) ? this.entry[1] : notSetValue; -}; - -ValueNode.prototype.update = function update (ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - var removed = value === NOT_SET; - var keyMatch = is(key, this.entry[0]); - if (keyMatch ? value === this.entry[1] : removed) { - return this; - } - - SetRef(didAlter); - - if (removed) { - SetRef(didChangeSize); - return; // undefined - } - - if (keyMatch) { - if (ownerID && ownerID === this.ownerID) { - this.entry[1] = value; - return this; - } - return new ValueNode(ownerID, this.keyHash, [key, value]); - } - - SetRef(didChangeSize); - return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); -}; - -// #pragma Iterators - -ArrayMapNode.prototype.iterate = HashCollisionNode.prototype.iterate = - function (fn, reverse) { - var entries = this.entries; - for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { - if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { - return false; - } - } - }; - -BitmapIndexedNode.prototype.iterate = HashArrayMapNode.prototype.iterate = - function (fn, reverse) { - var nodes = this.nodes; - for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { - var node = nodes[reverse ? maxIndex - ii : ii]; - if (node && node.iterate(fn, reverse) === false) { - return false; - } - } - }; - -// eslint-disable-next-line no-unused-vars -ValueNode.prototype.iterate = function (fn, reverse) { - return fn(this.entry); -}; - -var MapIterator = /*@__PURE__*/(function (Iterator) { - function MapIterator(map, type, reverse) { - this._type = type; - this._reverse = reverse; - this._stack = map._root && mapIteratorFrame(map._root); - } - - if ( Iterator ) MapIterator.__proto__ = Iterator; - MapIterator.prototype = Object.create( Iterator && Iterator.prototype ); - MapIterator.prototype.constructor = MapIterator; - - MapIterator.prototype.next = function next () { - var type = this._type; - var stack = this._stack; - while (stack) { - var node = stack.node; - var index = stack.index++; - var maxIndex = (void 0); - if (node.entry) { - if (index === 0) { - return mapIteratorValue(type, node.entry); - } - } else if (node.entries) { - maxIndex = node.entries.length - 1; - if (index <= maxIndex) { - return mapIteratorValue( - type, - node.entries[this._reverse ? maxIndex - index : index] - ); - } - } else { - maxIndex = node.nodes.length - 1; - if (index <= maxIndex) { - var subNode = node.nodes[this._reverse ? maxIndex - index : index]; - if (subNode) { - if (subNode.entry) { - return mapIteratorValue(type, subNode.entry); - } - stack = this._stack = mapIteratorFrame(subNode, stack); - } - continue; - } - } - stack = this._stack = this._stack.__prev; - } - return iteratorDone(); - }; - - return MapIterator; -}(Iterator)); - -function mapIteratorValue(type, entry) { - return iteratorValue(type, entry[0], entry[1]); -} - -function mapIteratorFrame(node, prev) { - return { - node: node, - index: 0, - __prev: prev, - }; -} - -function makeMap(size, root, ownerID, hash) { - var map = Object.create(MapPrototype); - map.size = size; - map._root = root; - map.__ownerID = ownerID; - map.__hash = hash; - map.__altered = false; - return map; -} - -var EMPTY_MAP; -function emptyMap() { - return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); -} - -function updateMap(map, k, v) { - var newRoot; - var newSize; - if (!map._root) { - if (v === NOT_SET) { - return map; - } - newSize = 1; - newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); - } else { - var didChangeSize = MakeRef(); - var didAlter = MakeRef(); - newRoot = updateNode( - map._root, - map.__ownerID, - 0, - undefined, - k, - v, - didChangeSize, - didAlter - ); - if (!didAlter.value) { - return map; - } - newSize = map.size + (didChangeSize.value ? (v === NOT_SET ? -1 : 1) : 0); - } - if (map.__ownerID) { - map.size = newSize; - map._root = newRoot; - map.__hash = undefined; - map.__altered = true; - return map; - } - return newRoot ? makeMap(newSize, newRoot) : emptyMap(); -} - -function updateNode( - node, - ownerID, - shift, - keyHash, - key, - value, - didChangeSize, - didAlter -) { - if (!node) { - if (value === NOT_SET) { - return node; - } - SetRef(didAlter); - SetRef(didChangeSize); - return new ValueNode(ownerID, keyHash, [key, value]); - } - return node.update( - ownerID, - shift, - keyHash, - key, - value, - didChangeSize, - didAlter - ); -} - -function isLeafNode(node) { - return ( - node.constructor === ValueNode || node.constructor === HashCollisionNode - ); -} - -function mergeIntoNode(node, ownerID, shift, keyHash, entry) { - if (node.keyHash === keyHash) { - return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); - } - - var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; - var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - - var newNode; - var nodes = - idx1 === idx2 - ? [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] - : ((newNode = new ValueNode(ownerID, keyHash, entry)), - idx1 < idx2 ? [node, newNode] : [newNode, node]); - - return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); -} - -function createNodes(ownerID, entries, key, value) { - if (!ownerID) { - ownerID = new OwnerID(); - } - var node = new ValueNode(ownerID, hash(key), [key, value]); - for (var ii = 0; ii < entries.length; ii++) { - var entry = entries[ii]; - node = node.update(ownerID, 0, undefined, entry[0], entry[1]); - } - return node; -} - -function packNodes(ownerID, nodes, count, excluding) { - var bitmap = 0; - var packedII = 0; - var packedNodes = new Array(count); - for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { - var node = nodes[ii]; - if (node !== undefined && ii !== excluding) { - bitmap |= bit; - packedNodes[packedII++] = node; - } - } - return new BitmapIndexedNode(ownerID, bitmap, packedNodes); -} - -function expandNodes(ownerID, nodes, bitmap, including, node) { - var count = 0; - var expandedNodes = new Array(SIZE); - for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { - expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; - } - expandedNodes[including] = node; - return new HashArrayMapNode(ownerID, count + 1, expandedNodes); -} - -function popCount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} - -function setAt(array, idx, val, canEdit) { - var newArray = canEdit ? array : arrCopy(array); - newArray[idx] = val; - return newArray; -} - -function spliceIn(array, idx, val, canEdit) { - var newLen = array.length + 1; - if (canEdit && idx + 1 === newLen) { - array[idx] = val; - return array; - } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - newArray[ii] = val; - after = -1; - } else { - newArray[ii] = array[ii + after]; - } - } - return newArray; -} - -function spliceOut(array, idx, canEdit) { - var newLen = array.length - 1; - if (canEdit && idx === newLen) { - array.pop(); - return array; - } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - after = 1; - } - newArray[ii] = array[ii + after]; - } - return newArray; -} - -var MAX_ARRAY_MAP_SIZE = SIZE / 4; -var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; -var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; - -var IS_LIST_SYMBOL = '@@__IMMUTABLE_LIST__@@'; - -function isList(maybeList) { - return Boolean(maybeList && maybeList[IS_LIST_SYMBOL]); -} - -var List = /*@__PURE__*/(function (IndexedCollection) { - function List(value) { - var empty = emptyList(); - if (value === undefined || value === null) { - // eslint-disable-next-line no-constructor-return - return empty; - } - if (isList(value)) { - // eslint-disable-next-line no-constructor-return - return value; - } - var iter = IndexedCollection(value); - var size = iter.size; - if (size === 0) { - // eslint-disable-next-line no-constructor-return - return empty; - } - assertNotInfinite(size); - if (size > 0 && size < SIZE) { - // eslint-disable-next-line no-constructor-return - return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); - } - // eslint-disable-next-line no-constructor-return - return empty.withMutations(function (list) { - list.setSize(size); - iter.forEach(function (v, i) { return list.set(i, v); }); - }); - } - - if ( IndexedCollection ) List.__proto__ = IndexedCollection; - List.prototype = Object.create( IndexedCollection && IndexedCollection.prototype ); - List.prototype.constructor = List; - - List.of = function of (/*...values*/) { - return this(arguments); - }; - - List.prototype.toString = function toString () { - return this.__toString('List [', ']'); - }; - - // @pragma Access - - List.prototype.get = function get (index, notSetValue) { - index = wrapIndex(this, index); - if (index >= 0 && index < this.size) { - index += this._origin; - var node = listNodeFor(this, index); - return node && node.array[index & MASK]; - } - return notSetValue; - }; - - // @pragma Modification - - List.prototype.set = function set (index, value) { - return updateList(this, index, value); - }; - - List.prototype.remove = function remove (index) { - return !this.has(index) - ? this - : index === 0 - ? this.shift() - : index === this.size - 1 - ? this.pop() - : this.splice(index, 1); - }; - - List.prototype.insert = function insert (index, value) { - return this.splice(index, 0, value); - }; - - List.prototype.clear = function clear () { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = this._origin = this._capacity = 0; - this._level = SHIFT; - this._root = this._tail = this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyList(); - }; - - List.prototype.push = function push (/*...values*/) { - var values = arguments; - var oldSize = this.size; - return this.withMutations(function (list) { - setListBounds(list, 0, oldSize + values.length); - for (var ii = 0; ii < values.length; ii++) { - list.set(oldSize + ii, values[ii]); - } - }); - }; - - List.prototype.pop = function pop () { - return setListBounds(this, 0, -1); - }; - - List.prototype.unshift = function unshift (/*...values*/) { - var values = arguments; - return this.withMutations(function (list) { - setListBounds(list, -values.length); - for (var ii = 0; ii < values.length; ii++) { - list.set(ii, values[ii]); - } - }); - }; - - List.prototype.shift = function shift () { - return setListBounds(this, 1); - }; - - // @pragma Composition - - List.prototype.concat = function concat (/*...collections*/) { - var arguments$1 = arguments; - - var seqs = []; - for (var i = 0; i < arguments.length; i++) { - var argument = arguments$1[i]; - var seq = IndexedCollection( - typeof argument !== 'string' && hasIterator(argument) - ? argument - : [argument] - ); - if (seq.size !== 0) { - seqs.push(seq); - } - } - if (seqs.length === 0) { - return this; - } - if (this.size === 0 && !this.__ownerID && seqs.length === 1) { - return this.constructor(seqs[0]); - } - return this.withMutations(function (list) { - seqs.forEach(function (seq) { return seq.forEach(function (value) { return list.push(value); }); }); - }); - }; - - List.prototype.setSize = function setSize (size) { - return setListBounds(this, 0, size); - }; - - List.prototype.map = function map (mapper, context) { - var this$1$1 = this; - - return this.withMutations(function (list) { - for (var i = 0; i < this$1$1.size; i++) { - list.set(i, mapper.call(context, list.get(i), i, this$1$1)); - } - }); - }; - - // @pragma Iteration - - List.prototype.slice = function slice (begin, end) { - var size = this.size; - if (wholeSlice(begin, end, size)) { - return this; - } - return setListBounds( - this, - resolveBegin(begin, size), - resolveEnd(end, size) - ); - }; - - List.prototype.__iterator = function __iterator (type, reverse) { - var index = reverse ? this.size : 0; - var values = iterateList(this, reverse); - return new Iterator(function () { - var value = values(); - return value === DONE - ? iteratorDone() - : iteratorValue(type, reverse ? --index : index++, value); - }); - }; - - List.prototype.__iterate = function __iterate (fn, reverse) { - var index = reverse ? this.size : 0; - var values = iterateList(this, reverse); - var value; - while ((value = values()) !== DONE) { - if (fn(value, reverse ? --index : index++, this) === false) { - break; - } - } - return index; - }; - - List.prototype.__ensureOwner = function __ensureOwner (ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - if (this.size === 0) { - return emptyList(); - } - this.__ownerID = ownerID; - this.__altered = false; - return this; - } - return makeList( - this._origin, - this._capacity, - this._level, - this._root, - this._tail, - ownerID, - this.__hash - ); - }; - - return List; -}(IndexedCollection)); - -List.isList = isList; - -var ListPrototype = List.prototype; -ListPrototype[IS_LIST_SYMBOL] = true; -ListPrototype[DELETE] = ListPrototype.remove; -ListPrototype.merge = ListPrototype.concat; -ListPrototype.setIn = setIn; -ListPrototype.deleteIn = ListPrototype.removeIn = deleteIn; -ListPrototype.update = update; -ListPrototype.updateIn = updateIn; -ListPrototype.mergeIn = mergeIn; -ListPrototype.mergeDeepIn = mergeDeepIn; -ListPrototype.withMutations = withMutations; -ListPrototype.wasAltered = wasAltered; -ListPrototype.asImmutable = asImmutable; -ListPrototype['@@transducer/init'] = ListPrototype.asMutable = asMutable; -ListPrototype['@@transducer/step'] = function (result, arr) { - return result.push(arr); -}; -ListPrototype['@@transducer/result'] = function (obj) { - return obj.asImmutable(); -}; - -var VNode = function VNode(array, ownerID) { - this.array = array; - this.ownerID = ownerID; -}; - -// TODO: seems like these methods are very similar - -VNode.prototype.removeBefore = function removeBefore (ownerID, level, index) { - if (index === level ? 1 << level : this.array.length === 0) { - return this; - } - var originIndex = (index >>> level) & MASK; - if (originIndex >= this.array.length) { - return new VNode([], ownerID); - } - var removingFirst = originIndex === 0; - var newChild; - if (level > 0) { - var oldChild = this.array[originIndex]; - newChild = - oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingFirst) { - return this; - } - } - if (removingFirst && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingFirst) { - for (var ii = 0; ii < originIndex; ii++) { - editable.array[ii] = undefined; - } - } - if (newChild) { - editable.array[originIndex] = newChild; - } - return editable; -}; - -VNode.prototype.removeAfter = function removeAfter (ownerID, level, index) { - if (index === (level ? 1 << level : 0) || this.array.length === 0) { - return this; - } - var sizeIndex = ((index - 1) >>> level) & MASK; - if (sizeIndex >= this.array.length) { - return this; - } - - var newChild; - if (level > 0) { - var oldChild = this.array[sizeIndex]; - newChild = - oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); - if (newChild === oldChild && sizeIndex === this.array.length - 1) { - return this; - } - } - - var editable = editableVNode(this, ownerID); - editable.array.splice(sizeIndex + 1); - if (newChild) { - editable.array[sizeIndex] = newChild; - } - return editable; -}; - -var DONE = {}; - -function iterateList(list, reverse) { - var left = list._origin; - var right = list._capacity; - var tailPos = getTailOffset(right); - var tail = list._tail; - - return iterateNodeOrLeaf(list._root, list._level, 0); - - function iterateNodeOrLeaf(node, level, offset) { - return level === 0 - ? iterateLeaf(node, offset) - : iterateNode(node, level, offset); - } - - function iterateLeaf(node, offset) { - var array = offset === tailPos ? tail && tail.array : node && node.array; - var from = offset > left ? 0 : left - offset; - var to = right - offset; - if (to > SIZE) { - to = SIZE; - } - return function () { - if (from === to) { - return DONE; - } - var idx = reverse ? --to : from++; - return array && array[idx]; - }; - } - - function iterateNode(node, level, offset) { - var values; - var array = node && node.array; - var from = offset > left ? 0 : (left - offset) >> level; - var to = ((right - offset) >> level) + 1; - if (to > SIZE) { - to = SIZE; - } - return function () { - while (true) { - if (values) { - var value = values(); - if (value !== DONE) { - return value; - } - values = null; - } - if (from === to) { - return DONE; - } - var idx = reverse ? --to : from++; - values = iterateNodeOrLeaf( - array && array[idx], - level - SHIFT, - offset + (idx << level) - ); - } - }; - } -} - -function makeList(origin, capacity, level, root, tail, ownerID, hash) { - var list = Object.create(ListPrototype); - list.size = capacity - origin; - list._origin = origin; - list._capacity = capacity; - list._level = level; - list._root = root; - list._tail = tail; - list.__ownerID = ownerID; - list.__hash = hash; - list.__altered = false; - return list; -} - -var EMPTY_LIST; -function emptyList() { - return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); -} - -function updateList(list, index, value) { - index = wrapIndex(list, index); - - if (index !== index) { - return list; - } - - if (index >= list.size || index < 0) { - return list.withMutations(function (list) { - index < 0 - ? setListBounds(list, index).set(0, value) - : setListBounds(list, 0, index + 1).set(index, value); - }); - } - - index += list._origin; - - var newTail = list._tail; - var newRoot = list._root; - var didAlter = MakeRef(); - if (index >= getTailOffset(list._capacity)) { - newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); - } else { - newRoot = updateVNode( - newRoot, - list.__ownerID, - list._level, - index, - value, - didAlter - ); - } - - if (!didAlter.value) { - return list; - } - - if (list.__ownerID) { - list._root = newRoot; - list._tail = newTail; - list.__hash = undefined; - list.__altered = true; - return list; - } - return makeList(list._origin, list._capacity, list._level, newRoot, newTail); -} - -function updateVNode(node, ownerID, level, index, value, didAlter) { - var idx = (index >>> level) & MASK; - var nodeHas = node && idx < node.array.length; - if (!nodeHas && value === undefined) { - return node; - } - - var newNode; - - if (level > 0) { - var lowerNode = node && node.array[idx]; - var newLowerNode = updateVNode( - lowerNode, - ownerID, - level - SHIFT, - index, - value, - didAlter - ); - if (newLowerNode === lowerNode) { - return node; - } - newNode = editableVNode(node, ownerID); - newNode.array[idx] = newLowerNode; - return newNode; - } - - if (nodeHas && node.array[idx] === value) { - return node; - } - - if (didAlter) { - SetRef(didAlter); - } - - newNode = editableVNode(node, ownerID); - if (value === undefined && idx === newNode.array.length - 1) { - newNode.array.pop(); - } else { - newNode.array[idx] = value; - } - return newNode; -} - -function editableVNode(node, ownerID) { - if (ownerID && node && ownerID === node.ownerID) { - return node; - } - return new VNode(node ? node.array.slice() : [], ownerID); -} - -function listNodeFor(list, rawIndex) { - if (rawIndex >= getTailOffset(list._capacity)) { - return list._tail; - } - if (rawIndex < 1 << (list._level + SHIFT)) { - var node = list._root; - var level = list._level; - while (node && level > 0) { - node = node.array[(rawIndex >>> level) & MASK]; - level -= SHIFT; - } - return node; - } -} - -function setListBounds(list, begin, end) { - // Sanitize begin & end using this shorthand for ToInt32(argument) - // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 - if (begin !== undefined) { - begin |= 0; - } - if (end !== undefined) { - end |= 0; - } - var owner = list.__ownerID || new OwnerID(); - var oldOrigin = list._origin; - var oldCapacity = list._capacity; - var newOrigin = oldOrigin + begin; - var newCapacity = - end === undefined - ? oldCapacity - : end < 0 - ? oldCapacity + end - : oldOrigin + end; - if (newOrigin === oldOrigin && newCapacity === oldCapacity) { - return list; - } - - // If it's going to end after it starts, it's empty. - if (newOrigin >= newCapacity) { - return list.clear(); - } - - var newLevel = list._level; - var newRoot = list._root; - - // New origin might need creating a higher root. - var offsetShift = 0; - while (newOrigin + offsetShift < 0) { - newRoot = new VNode( - newRoot && newRoot.array.length ? [undefined, newRoot] : [], - owner - ); - newLevel += SHIFT; - offsetShift += 1 << newLevel; - } - if (offsetShift) { - newOrigin += offsetShift; - oldOrigin += offsetShift; - newCapacity += offsetShift; - oldCapacity += offsetShift; - } - - var oldTailOffset = getTailOffset(oldCapacity); - var newTailOffset = getTailOffset(newCapacity); - - // New size might need creating a higher root. - while (newTailOffset >= 1 << (newLevel + SHIFT)) { - newRoot = new VNode( - newRoot && newRoot.array.length ? [newRoot] : [], - owner - ); - newLevel += SHIFT; - } - - // Locate or create the new tail. - var oldTail = list._tail; - var newTail = - newTailOffset < oldTailOffset - ? listNodeFor(list, newCapacity - 1) - : newTailOffset > oldTailOffset - ? new VNode([], owner) - : oldTail; - - // Merge Tail into tree. - if ( - oldTail && - newTailOffset > oldTailOffset && - newOrigin < oldCapacity && - oldTail.array.length - ) { - newRoot = editableVNode(newRoot, owner); - var node = newRoot; - for (var level = newLevel; level > SHIFT; level -= SHIFT) { - var idx = (oldTailOffset >>> level) & MASK; - node = node.array[idx] = editableVNode(node.array[idx], owner); - } - node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; - } - - // If the size has been reduced, there's a chance the tail needs to be trimmed. - if (newCapacity < oldCapacity) { - newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); - } - - // If the new origin is within the tail, then we do not need a root. - if (newOrigin >= newTailOffset) { - newOrigin -= newTailOffset; - newCapacity -= newTailOffset; - newLevel = SHIFT; - newRoot = null; - newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); - - // Otherwise, if the root has been trimmed, garbage collect. - } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { - offsetShift = 0; - - // Identify the new top root node of the subtree of the old root. - while (newRoot) { - var beginIndex = (newOrigin >>> newLevel) & MASK; - if ((beginIndex !== newTailOffset >>> newLevel) & MASK) { - break; - } - if (beginIndex) { - offsetShift += (1 << newLevel) * beginIndex; - } - newLevel -= SHIFT; - newRoot = newRoot.array[beginIndex]; - } - - // Trim the new sides of the new root. - if (newRoot && newOrigin > oldOrigin) { - newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); - } - if (newRoot && newTailOffset < oldTailOffset) { - newRoot = newRoot.removeAfter( - owner, - newLevel, - newTailOffset - offsetShift - ); - } - if (offsetShift) { - newOrigin -= offsetShift; - newCapacity -= offsetShift; - } - } - - if (list.__ownerID) { - list.size = newCapacity - newOrigin; - list._origin = newOrigin; - list._capacity = newCapacity; - list._level = newLevel; - list._root = newRoot; - list._tail = newTail; - list.__hash = undefined; - list.__altered = true; - return list; - } - return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); -} - -function getTailOffset(size) { - return size < SIZE ? 0 : ((size - 1) >>> SHIFT) << SHIFT; -} - -var OrderedMap = /*@__PURE__*/(function (Map) { - function OrderedMap(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptyOrderedMap() - : isOrderedMap(value) - ? value - : emptyOrderedMap().withMutations(function (map) { - var iter = KeyedCollection(value); - assertNotInfinite(iter.size); - iter.forEach(function (v, k) { return map.set(k, v); }); - }); - } - - if ( Map ) OrderedMap.__proto__ = Map; - OrderedMap.prototype = Object.create( Map && Map.prototype ); - OrderedMap.prototype.constructor = OrderedMap; - - OrderedMap.of = function of (/*...values*/) { - return this(arguments); - }; - - OrderedMap.prototype.toString = function toString () { - return this.__toString('OrderedMap {', '}'); - }; - - // @pragma Access - - OrderedMap.prototype.get = function get (k, notSetValue) { - var index = this._map.get(k); - return index !== undefined ? this._list.get(index)[1] : notSetValue; - }; - - // @pragma Modification - - OrderedMap.prototype.clear = function clear () { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = 0; - this._map.clear(); - this._list.clear(); - this.__altered = true; - return this; - } - return emptyOrderedMap(); - }; - - OrderedMap.prototype.set = function set (k, v) { - return updateOrderedMap(this, k, v); - }; - - OrderedMap.prototype.remove = function remove (k) { - return updateOrderedMap(this, k, NOT_SET); - }; - - OrderedMap.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - return this._list.__iterate( - function (entry) { return entry && fn(entry[1], entry[0], this$1$1); }, - reverse - ); - }; - - OrderedMap.prototype.__iterator = function __iterator (type, reverse) { - return this._list.fromEntrySeq().__iterator(type, reverse); - }; - - OrderedMap.prototype.__ensureOwner = function __ensureOwner (ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map.__ensureOwner(ownerID); - var newList = this._list.__ensureOwner(ownerID); - if (!ownerID) { - if (this.size === 0) { - return emptyOrderedMap(); - } - this.__ownerID = ownerID; - this.__altered = false; - this._map = newMap; - this._list = newList; - return this; - } - return makeOrderedMap(newMap, newList, ownerID, this.__hash); - }; - - return OrderedMap; -}(Map)); - -OrderedMap.isOrderedMap = isOrderedMap; - -OrderedMap.prototype[IS_ORDERED_SYMBOL] = true; -OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; - -function makeOrderedMap(map, list, ownerID, hash) { - var omap = Object.create(OrderedMap.prototype); - omap.size = map ? map.size : 0; - omap._map = map; - omap._list = list; - omap.__ownerID = ownerID; - omap.__hash = hash; - omap.__altered = false; - return omap; -} - -var EMPTY_ORDERED_MAP; -function emptyOrderedMap() { - return ( - EMPTY_ORDERED_MAP || - (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())) - ); -} - -function updateOrderedMap(omap, k, v) { - var map = omap._map; - var list = omap._list; - var i = map.get(k); - var has = i !== undefined; - var newMap; - var newList; - if (v === NOT_SET) { - // removed - if (!has) { - return omap; - } - if (list.size >= SIZE && list.size >= map.size * 2) { - newList = list.filter(function (entry, idx) { return entry !== undefined && i !== idx; }); - newMap = newList - .toKeyedSeq() - .map(function (entry) { return entry[0]; }) - .flip() - .toMap(); - if (omap.__ownerID) { - newMap.__ownerID = newList.__ownerID = omap.__ownerID; - } - } else { - newMap = map.remove(k); - newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); - } - } else if (has) { - if (v === list.get(i)[1]) { - return omap; - } - newMap = map; - newList = list.set(i, [k, v]); - } else { - newMap = map.set(k, list.size); - newList = list.set(list.size, [k, v]); - } - if (omap.__ownerID) { - omap.size = newMap.size; - omap._map = newMap; - omap._list = newList; - omap.__hash = undefined; - omap.__altered = true; - return omap; - } - return makeOrderedMap(newMap, newList); -} - -var IS_STACK_SYMBOL = '@@__IMMUTABLE_STACK__@@'; - -function isStack(maybeStack) { - return Boolean(maybeStack && maybeStack[IS_STACK_SYMBOL]); -} - -var Stack = /*@__PURE__*/(function (IndexedCollection) { - function Stack(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptyStack() - : isStack(value) - ? value - : emptyStack().pushAll(value); - } - - if ( IndexedCollection ) Stack.__proto__ = IndexedCollection; - Stack.prototype = Object.create( IndexedCollection && IndexedCollection.prototype ); - Stack.prototype.constructor = Stack; - - Stack.of = function of (/*...values*/) { - return this(arguments); - }; - - Stack.prototype.toString = function toString () { - return this.__toString('Stack [', ']'); - }; - - // @pragma Access - - Stack.prototype.get = function get (index, notSetValue) { - var head = this._head; - index = wrapIndex(this, index); - while (head && index--) { - head = head.next; - } - return head ? head.value : notSetValue; - }; - - Stack.prototype.peek = function peek () { - return this._head && this._head.value; - }; - - // @pragma Modification - - Stack.prototype.push = function push (/*...values*/) { - var arguments$1 = arguments; - - if (arguments.length === 0) { - return this; - } - var newSize = this.size + arguments.length; - var head = this._head; - for (var ii = arguments.length - 1; ii >= 0; ii--) { - head = { - value: arguments$1[ii], - next: head, - }; - } - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; - } - return makeStack(newSize, head); - }; - - Stack.prototype.pushAll = function pushAll (iter) { - iter = IndexedCollection(iter); - if (iter.size === 0) { - return this; - } - if (this.size === 0 && isStack(iter)) { - return iter; - } - assertNotInfinite(iter.size); - var newSize = this.size; - var head = this._head; - iter.__iterate(function (value) { - newSize++; - head = { - value: value, - next: head, - }; - }, /* reverse */ true); - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; - } - return makeStack(newSize, head); - }; - - Stack.prototype.pop = function pop () { - return this.slice(1); - }; - - Stack.prototype.clear = function clear () { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = 0; - this._head = undefined; - this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyStack(); - }; - - Stack.prototype.slice = function slice (begin, end) { - if (wholeSlice(begin, end, this.size)) { - return this; - } - var resolvedBegin = resolveBegin(begin, this.size); - var resolvedEnd = resolveEnd(end, this.size); - if (resolvedEnd !== this.size) { - // super.slice(begin, end); - return IndexedCollection.prototype.slice.call(this, begin, end); - } - var newSize = this.size - resolvedBegin; - var head = this._head; - while (resolvedBegin--) { - head = head.next; - } - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; - } - return makeStack(newSize, head); - }; - - // @pragma Mutability - - Stack.prototype.__ensureOwner = function __ensureOwner (ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - if (this.size === 0) { - return emptyStack(); - } - this.__ownerID = ownerID; - this.__altered = false; - return this; - } - return makeStack(this.size, this._head, ownerID, this.__hash); - }; - - // @pragma Iteration - - Stack.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - if (reverse) { - return new ArraySeq(this.toArray()).__iterate( - function (v, k) { return fn(v, k, this$1$1); }, - reverse - ); - } - var iterations = 0; - var node = this._head; - while (node) { - if (fn(node.value, iterations++, this) === false) { - break; - } - node = node.next; - } - return iterations; - }; - - Stack.prototype.__iterator = function __iterator (type, reverse) { - if (reverse) { - return new ArraySeq(this.toArray()).__iterator(type, reverse); - } - var iterations = 0; - var node = this._head; - return new Iterator(function () { - if (node) { - var value = node.value; - node = node.next; - return iteratorValue(type, iterations++, value); - } - return iteratorDone(); - }); - }; - - return Stack; -}(IndexedCollection)); - -Stack.isStack = isStack; - -var StackPrototype = Stack.prototype; -StackPrototype[IS_STACK_SYMBOL] = true; -StackPrototype.shift = StackPrototype.pop; -StackPrototype.unshift = StackPrototype.push; -StackPrototype.unshiftAll = StackPrototype.pushAll; -StackPrototype.withMutations = withMutations; -StackPrototype.wasAltered = wasAltered; -StackPrototype.asImmutable = asImmutable; -StackPrototype['@@transducer/init'] = StackPrototype.asMutable = asMutable; -StackPrototype['@@transducer/step'] = function (result, arr) { - return result.unshift(arr); -}; -StackPrototype['@@transducer/result'] = function (obj) { - return obj.asImmutable(); -}; - -function makeStack(size, head, ownerID, hash) { - var map = Object.create(StackPrototype); - map.size = size; - map._head = head; - map.__ownerID = ownerID; - map.__hash = hash; - map.__altered = false; - return map; -} - -var EMPTY_STACK; -function emptyStack() { - return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); -} - -var IS_SET_SYMBOL = '@@__IMMUTABLE_SET__@@'; - -function isSet(maybeSet) { - return Boolean(maybeSet && maybeSet[IS_SET_SYMBOL]); -} - -function isOrderedSet(maybeOrderedSet) { - return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); -} - -function deepEqual(a, b) { - if (a === b) { - return true; - } - - if ( - !isCollection(b) || - (a.size !== undefined && b.size !== undefined && a.size !== b.size) || - (a.__hash !== undefined && - b.__hash !== undefined && - a.__hash !== b.__hash) || - isKeyed(a) !== isKeyed(b) || - isIndexed(a) !== isIndexed(b) || - isOrdered(a) !== isOrdered(b) - ) { - return false; - } - - if (a.size === 0 && b.size === 0) { - return true; - } - - var notAssociative = !isAssociative(a); - - if (isOrdered(a)) { - var entries = a.entries(); - return ( - b.every(function (v, k) { - var entry = entries.next().value; - return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); - }) && entries.next().done - ); - } - - var flipped = false; - - if (a.size === undefined) { - if (b.size === undefined) { - if (typeof a.cacheResult === 'function') { - a.cacheResult(); - } - } else { - flipped = true; - var _ = a; - a = b; - b = _; - } - } - - var allEqual = true; - var bSize = b.__iterate(function (v, k) { - if ( - notAssociative - ? !a.has(v) - : flipped - ? !is(v, a.get(k, NOT_SET)) - : !is(a.get(k, NOT_SET), v) - ) { - allEqual = false; - return false; - } - }); - - return allEqual && a.size === bSize; -} - -function mixin(ctor, methods) { - var keyCopier = function (key) { - ctor.prototype[key] = methods[key]; - }; - Object.keys(methods).forEach(keyCopier); - Object.getOwnPropertySymbols && - Object.getOwnPropertySymbols(methods).forEach(keyCopier); - return ctor; -} - -function toJS(value) { - if (!value || typeof value !== 'object') { - return value; - } - if (!isCollection(value)) { - if (!isDataStructure(value)) { - return value; - } - value = Seq(value); - } - if (isKeyed(value)) { - var result$1 = {}; - value.__iterate(function (v, k) { - result$1[k] = toJS(v); - }); - return result$1; - } - var result = []; - value.__iterate(function (v) { - result.push(toJS(v)); - }); - return result; -} - -var Set = /*@__PURE__*/(function (SetCollection) { - function Set(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptySet() - : isSet(value) && !isOrdered(value) - ? value - : emptySet().withMutations(function (set) { - var iter = SetCollection(value); - assertNotInfinite(iter.size); - iter.forEach(function (v) { return set.add(v); }); - }); - } - - if ( SetCollection ) Set.__proto__ = SetCollection; - Set.prototype = Object.create( SetCollection && SetCollection.prototype ); - Set.prototype.constructor = Set; - - Set.of = function of (/*...values*/) { - return this(arguments); - }; - - Set.fromKeys = function fromKeys (value) { - return this(KeyedCollection(value).keySeq()); - }; - - Set.intersect = function intersect (sets) { - sets = Collection(sets).toArray(); - return sets.length - ? SetPrototype.intersect.apply(Set(sets.pop()), sets) - : emptySet(); - }; - - Set.union = function union (sets) { - sets = Collection(sets).toArray(); - return sets.length - ? SetPrototype.union.apply(Set(sets.pop()), sets) - : emptySet(); - }; - - Set.prototype.toString = function toString () { - return this.__toString('Set {', '}'); - }; - - // @pragma Access - - Set.prototype.has = function has (value) { - return this._map.has(value); - }; - - // @pragma Modification - - Set.prototype.add = function add (value) { - return updateSet(this, this._map.set(value, value)); - }; - - Set.prototype.remove = function remove (value) { - return updateSet(this, this._map.remove(value)); - }; - - Set.prototype.clear = function clear () { - return updateSet(this, this._map.clear()); - }; - - // @pragma Composition - - Set.prototype.map = function map (mapper, context) { - var this$1$1 = this; - - // keep track if the set is altered by the map function - var didChanges = false; - - var newMap = updateSet( - this, - this._map.mapEntries(function (ref) { - var v = ref[1]; - - var mapped = mapper.call(context, v, v, this$1$1); - - if (mapped !== v) { - didChanges = true; - } - - return [mapped, mapped]; - }, context) - ); - - return didChanges ? newMap : this; - }; - - Set.prototype.union = function union () { - var iters = [], len = arguments.length; - while ( len-- ) iters[ len ] = arguments[ len ]; - - iters = iters.filter(function (x) { return x.size !== 0; }); - if (iters.length === 0) { - return this; - } - if (this.size === 0 && !this.__ownerID && iters.length === 1) { - return this.constructor(iters[0]); - } - return this.withMutations(function (set) { - for (var ii = 0; ii < iters.length; ii++) { - if (typeof iters[ii] === 'string') { - set.add(iters[ii]); - } else { - SetCollection(iters[ii]).forEach(function (value) { return set.add(value); }); - } - } - }); - }; - - Set.prototype.intersect = function intersect () { - var iters = [], len = arguments.length; - while ( len-- ) iters[ len ] = arguments[ len ]; - - if (iters.length === 0) { - return this; - } - iters = iters.map(function (iter) { return SetCollection(iter); }); - var toRemove = []; - this.forEach(function (value) { - if (!iters.every(function (iter) { return iter.includes(value); })) { - toRemove.push(value); - } - }); - return this.withMutations(function (set) { - toRemove.forEach(function (value) { - set.remove(value); - }); - }); - }; - - Set.prototype.subtract = function subtract () { - var iters = [], len = arguments.length; - while ( len-- ) iters[ len ] = arguments[ len ]; - - if (iters.length === 0) { - return this; - } - iters = iters.map(function (iter) { return SetCollection(iter); }); - var toRemove = []; - this.forEach(function (value) { - if (iters.some(function (iter) { return iter.includes(value); })) { - toRemove.push(value); - } - }); - return this.withMutations(function (set) { - toRemove.forEach(function (value) { - set.remove(value); - }); - }); - }; - - Set.prototype.sort = function sort (comparator) { - // Late binding - return OrderedSet(sortFactory(this, comparator)); - }; - - Set.prototype.sortBy = function sortBy (mapper, comparator) { - // Late binding - return OrderedSet(sortFactory(this, comparator, mapper)); - }; - - Set.prototype.wasAltered = function wasAltered () { - return this._map.wasAltered(); - }; - - Set.prototype.__iterate = function __iterate (fn, reverse) { - var this$1$1 = this; - - return this._map.__iterate(function (k) { return fn(k, k, this$1$1); }, reverse); - }; - - Set.prototype.__iterator = function __iterator (type, reverse) { - return this._map.__iterator(type, reverse); - }; - - Set.prototype.__ensureOwner = function __ensureOwner (ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map.__ensureOwner(ownerID); - if (!ownerID) { - if (this.size === 0) { - return this.__empty(); - } - this.__ownerID = ownerID; - this._map = newMap; - return this; - } - return this.__make(newMap, ownerID); - }; - - return Set; -}(SetCollection)); - -Set.isSet = isSet; - -var SetPrototype = Set.prototype; -SetPrototype[IS_SET_SYMBOL] = true; -SetPrototype[DELETE] = SetPrototype.remove; -SetPrototype.merge = SetPrototype.concat = SetPrototype.union; -SetPrototype.withMutations = withMutations; -SetPrototype.asImmutable = asImmutable; -SetPrototype['@@transducer/init'] = SetPrototype.asMutable = asMutable; -SetPrototype['@@transducer/step'] = function (result, arr) { - return result.add(arr); -}; -SetPrototype['@@transducer/result'] = function (obj) { - return obj.asImmutable(); -}; - -SetPrototype.__empty = emptySet; -SetPrototype.__make = makeSet; - -function updateSet(set, newMap) { - if (set.__ownerID) { - set.size = newMap.size; - set._map = newMap; - return set; - } - return newMap === set._map - ? set - : newMap.size === 0 - ? set.__empty() - : set.__make(newMap); -} - -function makeSet(map, ownerID) { - var set = Object.create(SetPrototype); - set.size = map ? map.size : 0; - set._map = map; - set.__ownerID = ownerID; - return set; -} - -var EMPTY_SET; -function emptySet() { - return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); -} - -/** - * Returns a lazy seq of nums from start (inclusive) to end - * (exclusive), by step, where start defaults to 0, step to 1, and end to - * infinity. When start is equal to end, returns empty list. - */ -var Range = /*@__PURE__*/(function (IndexedSeq) { - function Range(start, end, step) { - if (!(this instanceof Range)) { - // eslint-disable-next-line no-constructor-return - return new Range(start, end, step); - } - invariant(step !== 0, 'Cannot step a Range by 0'); - start = start || 0; - if (end === undefined) { - end = Infinity; - } - step = step === undefined ? 1 : Math.abs(step); - if (end < start) { - step = -step; - } - this._start = start; - this._end = end; - this._step = step; - this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); - if (this.size === 0) { - if (EMPTY_RANGE) { - // eslint-disable-next-line no-constructor-return - return EMPTY_RANGE; - } - EMPTY_RANGE = this; - } - } - - if ( IndexedSeq ) Range.__proto__ = IndexedSeq; - Range.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); - Range.prototype.constructor = Range; - - Range.prototype.toString = function toString () { - if (this.size === 0) { - return 'Range []'; - } - return ( - 'Range [ ' + - this._start + - '...' + - this._end + - (this._step !== 1 ? ' by ' + this._step : '') + - ' ]' - ); - }; - - Range.prototype.get = function get (index, notSetValue) { - return this.has(index) - ? this._start + wrapIndex(this, index) * this._step - : notSetValue; - }; - - Range.prototype.includes = function includes (searchValue) { - var possibleIndex = (searchValue - this._start) / this._step; - return ( - possibleIndex >= 0 && - possibleIndex < this.size && - possibleIndex === Math.floor(possibleIndex) - ); - }; - - Range.prototype.slice = function slice (begin, end) { - if (wholeSlice(begin, end, this.size)) { - return this; - } - begin = resolveBegin(begin, this.size); - end = resolveEnd(end, this.size); - if (end <= begin) { - return new Range(0, 0); - } - return new Range( - this.get(begin, this._end), - this.get(end, this._end), - this._step - ); - }; - - Range.prototype.indexOf = function indexOf (searchValue) { - var offsetValue = searchValue - this._start; - if (offsetValue % this._step === 0) { - var index = offsetValue / this._step; - if (index >= 0 && index < this.size) { - return index; - } - } - return -1; - }; - - Range.prototype.lastIndexOf = function lastIndexOf (searchValue) { - return this.indexOf(searchValue); - }; - - Range.prototype.__iterate = function __iterate (fn, reverse) { - var size = this.size; - var step = this._step; - var value = reverse ? this._start + (size - 1) * step : this._start; - var i = 0; - while (i !== size) { - if (fn(value, reverse ? size - ++i : i++, this) === false) { - break; - } - value += reverse ? -step : step; - } - return i; - }; - - Range.prototype.__iterator = function __iterator (type, reverse) { - var size = this.size; - var step = this._step; - var value = reverse ? this._start + (size - 1) * step : this._start; - var i = 0; - return new Iterator(function () { - if (i === size) { - return iteratorDone(); - } - var v = value; - value += reverse ? -step : step; - return iteratorValue(type, reverse ? size - ++i : i++, v); - }); - }; - - Range.prototype.equals = function equals (other) { - return other instanceof Range - ? this._start === other._start && - this._end === other._end && - this._step === other._step - : deepEqual(this, other); - }; - - return Range; -}(IndexedSeq)); - -var EMPTY_RANGE; - -function getIn$1(collection, searchKeyPath, notSetValue) { - var keyPath = coerceKeyPath(searchKeyPath); - var i = 0; - while (i !== keyPath.length) { - collection = get(collection, keyPath[i++], NOT_SET); - if (collection === NOT_SET) { - return notSetValue; - } - } - return collection; -} - -function getIn(searchKeyPath, notSetValue) { - return getIn$1(this, searchKeyPath, notSetValue); -} - -function hasIn$1(collection, keyPath) { - return getIn$1(collection, keyPath, NOT_SET) !== NOT_SET; -} - -function hasIn(searchKeyPath) { - return hasIn$1(this, searchKeyPath); -} - -function toObject() { - assertNotInfinite(this.size); - var object = {}; - this.__iterate(function (v, k) { - object[k] = v; - }); - return object; -} - -// Note: all of these methods are deprecated. -Collection.isIterable = isCollection; -Collection.isKeyed = isKeyed; -Collection.isIndexed = isIndexed; -Collection.isAssociative = isAssociative; -Collection.isOrdered = isOrdered; - -Collection.Iterator = Iterator; - -mixin(Collection, { - // ### Conversion to other types - - toArray: function toArray() { - assertNotInfinite(this.size); - var array = new Array(this.size || 0); - var useTuples = isKeyed(this); - var i = 0; - this.__iterate(function (v, k) { - // Keyed collections produce an array of tuples. - array[i++] = useTuples ? [k, v] : v; - }); - return array; - }, - - toIndexedSeq: function toIndexedSeq() { - return new ToIndexedSequence(this); - }, - - toJS: function toJS$1() { - return toJS(this); - }, - - toKeyedSeq: function toKeyedSeq() { - return new ToKeyedSequence(this, true); - }, - - toMap: function toMap() { - // Use Late Binding here to solve the circular dependency. - return Map(this.toKeyedSeq()); - }, - - toObject: toObject, - - toOrderedMap: function toOrderedMap() { - // Use Late Binding here to solve the circular dependency. - return OrderedMap(this.toKeyedSeq()); - }, - - toOrderedSet: function toOrderedSet() { - // Use Late Binding here to solve the circular dependency. - return OrderedSet(isKeyed(this) ? this.valueSeq() : this); - }, - - toSet: function toSet() { - // Use Late Binding here to solve the circular dependency. - return Set(isKeyed(this) ? this.valueSeq() : this); - }, - - toSetSeq: function toSetSeq() { - return new ToSetSequence(this); - }, - - toSeq: function toSeq() { - return isIndexed(this) - ? this.toIndexedSeq() - : isKeyed(this) - ? this.toKeyedSeq() - : this.toSetSeq(); - }, - - toStack: function toStack() { - // Use Late Binding here to solve the circular dependency. - return Stack(isKeyed(this) ? this.valueSeq() : this); - }, - - toList: function toList() { - // Use Late Binding here to solve the circular dependency. - return List(isKeyed(this) ? this.valueSeq() : this); - }, - - // ### Common JavaScript methods and properties - - toString: function toString() { - return '[Collection]'; - }, - - __toString: function __toString(head, tail) { - if (this.size === 0) { - return head + tail; - } - return ( - head + - ' ' + - this.toSeq().map(this.__toStringMapper).join(', ') + - ' ' + - tail - ); - }, - - // ### ES6 Collection methods (ES6 Array and Map) - - concat: function concat() { - var values = [], len = arguments.length; - while ( len-- ) values[ len ] = arguments[ len ]; - - return reify(this, concatFactory(this, values)); - }, - - includes: function includes(searchValue) { - return this.some(function (value) { return is(value, searchValue); }); - }, - - entries: function entries() { - return this.__iterator(ITERATE_ENTRIES); - }, - - every: function every(predicate, context) { - assertNotInfinite(this.size); - var returnValue = true; - this.__iterate(function (v, k, c) { - if (!predicate.call(context, v, k, c)) { - returnValue = false; - return false; - } - }); - return returnValue; - }, - - filter: function filter(predicate, context) { - return reify(this, filterFactory(this, predicate, context, true)); - }, - - partition: function partition(predicate, context) { - return partitionFactory(this, predicate, context); - }, - - find: function find(predicate, context, notSetValue) { - var entry = this.findEntry(predicate, context); - return entry ? entry[1] : notSetValue; - }, - - forEach: function forEach(sideEffect, context) { - assertNotInfinite(this.size); - return this.__iterate(context ? sideEffect.bind(context) : sideEffect); - }, - - join: function join(separator) { - assertNotInfinite(this.size); - separator = separator !== undefined ? '' + separator : ','; - var joined = ''; - var isFirst = true; - this.__iterate(function (v) { - isFirst ? (isFirst = false) : (joined += separator); - joined += v !== null && v !== undefined ? v.toString() : ''; - }); - return joined; - }, - - keys: function keys() { - return this.__iterator(ITERATE_KEYS); - }, - - map: function map(mapper, context) { - return reify(this, mapFactory(this, mapper, context)); - }, - - reduce: function reduce$1(reducer, initialReduction, context) { - return reduce( - this, - reducer, - initialReduction, - context, - arguments.length < 2, - false - ); - }, - - reduceRight: function reduceRight(reducer, initialReduction, context) { - return reduce( - this, - reducer, - initialReduction, - context, - arguments.length < 2, - true - ); - }, - - reverse: function reverse() { - return reify(this, reverseFactory(this, true)); - }, - - slice: function slice(begin, end) { - return reify(this, sliceFactory(this, begin, end, true)); - }, - - some: function some(predicate, context) { - assertNotInfinite(this.size); - var returnValue = false; - this.__iterate(function (v, k, c) { - if (predicate.call(context, v, k, c)) { - returnValue = true; - return false; - } - }); - return returnValue; - }, - - sort: function sort(comparator) { - return reify(this, sortFactory(this, comparator)); - }, - - values: function values() { - return this.__iterator(ITERATE_VALUES); - }, - - // ### More sequential methods - - butLast: function butLast() { - return this.slice(0, -1); - }, - - isEmpty: function isEmpty() { - return this.size !== undefined ? this.size === 0 : !this.some(function () { return true; }); - }, - - count: function count(predicate, context) { - return ensureSize( - predicate ? this.toSeq().filter(predicate, context) : this - ); - }, - - countBy: function countBy(grouper, context) { - return countByFactory(this, grouper, context); - }, - - equals: function equals(other) { - return deepEqual(this, other); - }, - - entrySeq: function entrySeq() { - var collection = this; - if (collection._cache) { - // We cache as an entries array, so we can just return the cache! - return new ArraySeq(collection._cache); - } - var entriesSequence = collection.toSeq().map(entryMapper).toIndexedSeq(); - entriesSequence.fromEntrySeq = function () { return collection.toSeq(); }; - return entriesSequence; - }, - - filterNot: function filterNot(predicate, context) { - return this.filter(not(predicate), context); - }, - - findEntry: function findEntry(predicate, context, notSetValue) { - var found = notSetValue; - this.__iterate(function (v, k, c) { - if (predicate.call(context, v, k, c)) { - found = [k, v]; - return false; - } - }); - return found; - }, - - findKey: function findKey(predicate, context) { - var entry = this.findEntry(predicate, context); - return entry && entry[0]; - }, - - findLast: function findLast(predicate, context, notSetValue) { - return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); - }, - - findLastEntry: function findLastEntry(predicate, context, notSetValue) { - return this.toKeyedSeq() - .reverse() - .findEntry(predicate, context, notSetValue); - }, - - findLastKey: function findLastKey(predicate, context) { - return this.toKeyedSeq().reverse().findKey(predicate, context); - }, - - first: function first(notSetValue) { - return this.find(returnTrue, null, notSetValue); - }, - - flatMap: function flatMap(mapper, context) { - return reify(this, flatMapFactory(this, mapper, context)); - }, - - flatten: function flatten(depth) { - return reify(this, flattenFactory(this, depth, true)); - }, - - fromEntrySeq: function fromEntrySeq() { - return new FromEntriesSequence(this); - }, - - get: function get(searchKey, notSetValue) { - return this.find(function (_, key) { return is(key, searchKey); }, undefined, notSetValue); - }, - - getIn: getIn, - - groupBy: function groupBy(grouper, context) { - return groupByFactory(this, grouper, context); - }, - - has: function has(searchKey) { - return this.get(searchKey, NOT_SET) !== NOT_SET; - }, - - hasIn: hasIn, - - isSubset: function isSubset(iter) { - iter = typeof iter.includes === 'function' ? iter : Collection(iter); - return this.every(function (value) { return iter.includes(value); }); - }, - - isSuperset: function isSuperset(iter) { - iter = typeof iter.isSubset === 'function' ? iter : Collection(iter); - return iter.isSubset(this); - }, - - keyOf: function keyOf(searchValue) { - return this.findKey(function (value) { return is(value, searchValue); }); - }, - - keySeq: function keySeq() { - return this.toSeq().map(keyMapper).toIndexedSeq(); - }, - - last: function last(notSetValue) { - return this.toSeq().reverse().first(notSetValue); - }, - - lastKeyOf: function lastKeyOf(searchValue) { - return this.toKeyedSeq().reverse().keyOf(searchValue); - }, - - max: function max(comparator) { - return maxFactory(this, comparator); - }, - - maxBy: function maxBy(mapper, comparator) { - return maxFactory(this, comparator, mapper); - }, - - min: function min(comparator) { - return maxFactory( - this, - comparator ? neg(comparator) : defaultNegComparator - ); - }, - - minBy: function minBy(mapper, comparator) { - return maxFactory( - this, - comparator ? neg(comparator) : defaultNegComparator, - mapper - ); - }, - - rest: function rest() { - return this.slice(1); - }, - - skip: function skip(amount) { - return amount === 0 ? this : this.slice(Math.max(0, amount)); - }, - - skipLast: function skipLast(amount) { - return amount === 0 ? this : this.slice(0, -Math.max(0, amount)); - }, - - skipWhile: function skipWhile(predicate, context) { - return reify(this, skipWhileFactory(this, predicate, context, true)); - }, - - skipUntil: function skipUntil(predicate, context) { - return this.skipWhile(not(predicate), context); - }, - - sortBy: function sortBy(mapper, comparator) { - return reify(this, sortFactory(this, comparator, mapper)); - }, - - take: function take(amount) { - return this.slice(0, Math.max(0, amount)); - }, - - takeLast: function takeLast(amount) { - return this.slice(-Math.max(0, amount)); - }, - - takeWhile: function takeWhile(predicate, context) { - return reify(this, takeWhileFactory(this, predicate, context)); - }, - - takeUntil: function takeUntil(predicate, context) { - return this.takeWhile(not(predicate), context); - }, - - update: function update(fn) { - return fn(this); - }, - - valueSeq: function valueSeq() { - return this.toIndexedSeq(); - }, - - // ### Hashable Object - - hashCode: function hashCode() { - return this.__hash || (this.__hash = hashCollection(this)); - }, - - // ### Internal - - // abstract __iterate(fn, reverse) - - // abstract __iterator(type, reverse) -}); - -var CollectionPrototype = Collection.prototype; -CollectionPrototype[IS_COLLECTION_SYMBOL] = true; -CollectionPrototype[ITERATOR_SYMBOL] = CollectionPrototype.values; -CollectionPrototype.toJSON = CollectionPrototype.toArray; -CollectionPrototype.__toStringMapper = quoteString; -CollectionPrototype.inspect = CollectionPrototype.toSource = function () { - return this.toString(); -}; -CollectionPrototype.chain = CollectionPrototype.flatMap; -CollectionPrototype.contains = CollectionPrototype.includes; - -mixin(KeyedCollection, { - // ### More sequential methods - - flip: function flip() { - return reify(this, flipFactory(this)); - }, - - mapEntries: function mapEntries(mapper, context) { - var this$1$1 = this; - - var iterations = 0; - return reify( - this, - this.toSeq() - .map(function (v, k) { return mapper.call(context, [k, v], iterations++, this$1$1); }) - .fromEntrySeq() - ); - }, - - mapKeys: function mapKeys(mapper, context) { - var this$1$1 = this; - - return reify( - this, - this.toSeq() - .flip() - .map(function (k, v) { return mapper.call(context, k, v, this$1$1); }) - .flip() - ); - }, -}); - -var KeyedCollectionPrototype = KeyedCollection.prototype; -KeyedCollectionPrototype[IS_KEYED_SYMBOL] = true; -KeyedCollectionPrototype[ITERATOR_SYMBOL] = CollectionPrototype.entries; -KeyedCollectionPrototype.toJSON = toObject; -KeyedCollectionPrototype.__toStringMapper = function (v, k) { return quoteString(k) + ': ' + quoteString(v); }; - -mixin(IndexedCollection, { - // ### Conversion to other types - - toKeyedSeq: function toKeyedSeq() { - return new ToKeyedSequence(this, false); - }, - - // ### ES6 Collection methods (ES6 Array and Map) - - filter: function filter(predicate, context) { - return reify(this, filterFactory(this, predicate, context, false)); - }, - - findIndex: function findIndex(predicate, context) { - var entry = this.findEntry(predicate, context); - return entry ? entry[0] : -1; - }, - - indexOf: function indexOf(searchValue) { - var key = this.keyOf(searchValue); - return key === undefined ? -1 : key; - }, - - lastIndexOf: function lastIndexOf(searchValue) { - var key = this.lastKeyOf(searchValue); - return key === undefined ? -1 : key; - }, - - reverse: function reverse() { - return reify(this, reverseFactory(this, false)); - }, - - slice: function slice(begin, end) { - return reify(this, sliceFactory(this, begin, end, false)); - }, - - splice: function splice(index, removeNum /*, ...values*/) { - var numArgs = arguments.length; - removeNum = Math.max(removeNum || 0, 0); - if (numArgs === 0 || (numArgs === 2 && !removeNum)) { - return this; - } - // If index is negative, it should resolve relative to the size of the - // collection. However size may be expensive to compute if not cached, so - // only call count() if the number is in fact negative. - index = resolveBegin(index, index < 0 ? this.count() : this.size); - var spliced = this.slice(0, index); - return reify( - this, - numArgs === 1 - ? spliced - : spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) - ); - }, - - // ### More collection methods - - findLastIndex: function findLastIndex(predicate, context) { - var entry = this.findLastEntry(predicate, context); - return entry ? entry[0] : -1; - }, - - first: function first(notSetValue) { - return this.get(0, notSetValue); - }, - - flatten: function flatten(depth) { - return reify(this, flattenFactory(this, depth, false)); - }, - - get: function get(index, notSetValue) { - index = wrapIndex(this, index); - return index < 0 || - this.size === Infinity || - (this.size !== undefined && index > this.size) - ? notSetValue - : this.find(function (_, key) { return key === index; }, undefined, notSetValue); - }, - - has: function has(index) { - index = wrapIndex(this, index); - return ( - index >= 0 && - (this.size !== undefined - ? this.size === Infinity || index < this.size - : this.indexOf(index) !== -1) - ); - }, - - interpose: function interpose(separator) { - return reify(this, interposeFactory(this, separator)); - }, - - interleave: function interleave(/*...collections*/) { - var collections = [this].concat(arrCopy(arguments)); - var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, collections); - var interleaved = zipped.flatten(true); - if (zipped.size) { - interleaved.size = zipped.size * collections.length; - } - return reify(this, interleaved); - }, - - keySeq: function keySeq() { - return Range(0, this.size); - }, - - last: function last(notSetValue) { - return this.get(-1, notSetValue); - }, - - skipWhile: function skipWhile(predicate, context) { - return reify(this, skipWhileFactory(this, predicate, context, false)); - }, - - zip: function zip(/*, ...collections */) { - var collections = [this].concat(arrCopy(arguments)); - return reify(this, zipWithFactory(this, defaultZipper, collections)); - }, - - zipAll: function zipAll(/*, ...collections */) { - var collections = [this].concat(arrCopy(arguments)); - return reify(this, zipWithFactory(this, defaultZipper, collections, true)); - }, - - zipWith: function zipWith(zipper /*, ...collections */) { - var collections = arrCopy(arguments); - collections[0] = this; - return reify(this, zipWithFactory(this, zipper, collections)); - }, -}); - -var IndexedCollectionPrototype = IndexedCollection.prototype; -IndexedCollectionPrototype[IS_INDEXED_SYMBOL] = true; -IndexedCollectionPrototype[IS_ORDERED_SYMBOL] = true; - -mixin(SetCollection, { - // ### ES6 Collection methods (ES6 Array and Map) - - get: function get(value, notSetValue) { - return this.has(value) ? value : notSetValue; - }, - - includes: function includes(value) { - return this.has(value); - }, - - // ### More sequential methods - - keySeq: function keySeq() { - return this.valueSeq(); - }, -}); - -var SetCollectionPrototype = SetCollection.prototype; -SetCollectionPrototype.has = CollectionPrototype.includes; -SetCollectionPrototype.contains = SetCollectionPrototype.includes; -SetCollectionPrototype.keys = SetCollectionPrototype.values; - -// Mixin subclasses - -mixin(KeyedSeq, KeyedCollectionPrototype); -mixin(IndexedSeq, IndexedCollectionPrototype); -mixin(SetSeq, SetCollectionPrototype); - -// #pragma Helper functions - -function reduce(collection, reducer, reduction, context, useFirst, reverse) { - assertNotInfinite(collection.size); - collection.__iterate(function (v, k, c) { - if (useFirst) { - useFirst = false; - reduction = v; - } else { - reduction = reducer.call(context, reduction, v, k, c); - } - }, reverse); - return reduction; -} - -function keyMapper(v, k) { - return k; -} - -function entryMapper(v, k) { - return [k, v]; -} - -function not(predicate) { - return function () { - return !predicate.apply(this, arguments); - }; -} - -function neg(predicate) { - return function () { - return -predicate.apply(this, arguments); - }; -} - -function defaultZipper() { - return arrCopy(arguments); -} - -function defaultNegComparator(a, b) { - return a < b ? 1 : a > b ? -1 : 0; -} - -function hashCollection(collection) { - if (collection.size === Infinity) { - return 0; - } - var ordered = isOrdered(collection); - var keyed = isKeyed(collection); - var h = ordered ? 1 : 0; - var size = collection.__iterate( - keyed - ? ordered - ? function (v, k) { - h = (31 * h + hashMerge(hash(v), hash(k))) | 0; - } - : function (v, k) { - h = (h + hashMerge(hash(v), hash(k))) | 0; - } - : ordered - ? function (v) { - h = (31 * h + hash(v)) | 0; - } - : function (v) { - h = (h + hash(v)) | 0; - } - ); - return murmurHashOfSize(size, h); -} - -function murmurHashOfSize(size, h) { - h = imul(h, 0xcc9e2d51); - h = imul((h << 15) | (h >>> -15), 0x1b873593); - h = imul((h << 13) | (h >>> -13), 5); - h = ((h + 0xe6546b64) | 0) ^ size; - h = imul(h ^ (h >>> 16), 0x85ebca6b); - h = imul(h ^ (h >>> 13), 0xc2b2ae35); - h = smi(h ^ (h >>> 16)); - return h; -} - -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; // int -} - -var OrderedSet = /*@__PURE__*/(function (Set) { - function OrderedSet(value) { - // eslint-disable-next-line no-constructor-return - return value === undefined || value === null - ? emptyOrderedSet() - : isOrderedSet(value) - ? value - : emptyOrderedSet().withMutations(function (set) { - var iter = SetCollection(value); - assertNotInfinite(iter.size); - iter.forEach(function (v) { return set.add(v); }); - }); - } - - if ( Set ) OrderedSet.__proto__ = Set; - OrderedSet.prototype = Object.create( Set && Set.prototype ); - OrderedSet.prototype.constructor = OrderedSet; - - OrderedSet.of = function of (/*...values*/) { - return this(arguments); - }; - - OrderedSet.fromKeys = function fromKeys (value) { - return this(KeyedCollection(value).keySeq()); - }; - - OrderedSet.prototype.toString = function toString () { - return this.__toString('OrderedSet {', '}'); - }; - - return OrderedSet; -}(Set)); - -OrderedSet.isOrderedSet = isOrderedSet; - -var OrderedSetPrototype = OrderedSet.prototype; -OrderedSetPrototype[IS_ORDERED_SYMBOL] = true; -OrderedSetPrototype.zip = IndexedCollectionPrototype.zip; -OrderedSetPrototype.zipWith = IndexedCollectionPrototype.zipWith; -OrderedSetPrototype.zipAll = IndexedCollectionPrototype.zipAll; - -OrderedSetPrototype.__empty = emptyOrderedSet; -OrderedSetPrototype.__make = makeOrderedSet; - -function makeOrderedSet(map, ownerID) { - var set = Object.create(OrderedSetPrototype); - set.size = map ? map.size : 0; - set._map = map; - set.__ownerID = ownerID; - return set; -} - -var EMPTY_ORDERED_SET; -function emptyOrderedSet() { - return ( - EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())) - ); -} - -var PairSorting = { - LeftThenRight: -1, - RightThenLeft: +1, -}; - -function throwOnInvalidDefaultValues(defaultValues) { - if (isRecord(defaultValues)) { - throw new Error( - 'Can not call `Record` with an immutable Record as default values. Use a plain javascript object instead.' - ); - } - - if (isImmutable(defaultValues)) { - throw new Error( - 'Can not call `Record` with an immutable Collection as default values. Use a plain javascript object instead.' - ); - } - - if (defaultValues === null || typeof defaultValues !== 'object') { - throw new Error( - 'Can not call `Record` with a non-object as default values. Use a plain javascript object instead.' - ); - } -} - -var Record = function Record(defaultValues, name) { - var hasInitialized; - - throwOnInvalidDefaultValues(defaultValues); - - var RecordType = function Record(values) { - var this$1$1 = this; - - if (values instanceof RecordType) { - return values; - } - if (!(this instanceof RecordType)) { - return new RecordType(values); - } - if (!hasInitialized) { - hasInitialized = true; - var keys = Object.keys(defaultValues); - var indices = (RecordTypePrototype._indices = {}); - // Deprecated: left to attempt not to break any external code which - // relies on a ._name property existing on record instances. - // Use Record.getDescriptiveName() instead - RecordTypePrototype._name = name; - RecordTypePrototype._keys = keys; - RecordTypePrototype._defaultValues = defaultValues; - for (var i = 0; i < keys.length; i++) { - var propName = keys[i]; - indices[propName] = i; - if (RecordTypePrototype[propName]) { - /* eslint-disable no-console */ - typeof console === 'object' && - console.warn && - console.warn( - 'Cannot define ' + - recordName(this) + - ' with property "' + - propName + - '" since that property name is part of the Record API.' - ); - /* eslint-enable no-console */ - } else { - setProp(RecordTypePrototype, propName); - } - } - } - this.__ownerID = undefined; - this._values = List().withMutations(function (l) { - l.setSize(this$1$1._keys.length); - KeyedCollection(values).forEach(function (v, k) { - l.set(this$1$1._indices[k], v === this$1$1._defaultValues[k] ? undefined : v); - }); - }); - return this; - }; - - var RecordTypePrototype = (RecordType.prototype = - Object.create(RecordPrototype)); - RecordTypePrototype.constructor = RecordType; - - if (name) { - RecordType.displayName = name; - } - - // eslint-disable-next-line no-constructor-return - return RecordType; -}; - -Record.prototype.toString = function toString () { - var str = recordName(this) + ' { '; - var keys = this._keys; - var k; - for (var i = 0, l = keys.length; i !== l; i++) { - k = keys[i]; - str += (i ? ', ' : '') + k + ': ' + quoteString(this.get(k)); - } - return str + ' }'; -}; - -Record.prototype.equals = function equals (other) { - return ( - this === other || - (isRecord(other) && recordSeq(this).equals(recordSeq(other))) - ); -}; - -Record.prototype.hashCode = function hashCode () { - return recordSeq(this).hashCode(); -}; - -// @pragma Access - -Record.prototype.has = function has (k) { - return this._indices.hasOwnProperty(k); -}; - -Record.prototype.get = function get (k, notSetValue) { - if (!this.has(k)) { - return notSetValue; - } - var index = this._indices[k]; - var value = this._values.get(index); - return value === undefined ? this._defaultValues[k] : value; -}; - -// @pragma Modification - -Record.prototype.set = function set (k, v) { - if (this.has(k)) { - var newValues = this._values.set( - this._indices[k], - v === this._defaultValues[k] ? undefined : v - ); - if (newValues !== this._values && !this.__ownerID) { - return makeRecord(this, newValues); - } - } - return this; -}; - -Record.prototype.remove = function remove (k) { - return this.set(k); -}; - -Record.prototype.clear = function clear () { - var newValues = this._values.clear().setSize(this._keys.length); - - return this.__ownerID ? this : makeRecord(this, newValues); -}; - -Record.prototype.wasAltered = function wasAltered () { - return this._values.wasAltered(); -}; - -Record.prototype.toSeq = function toSeq () { - return recordSeq(this); -}; - -Record.prototype.toJS = function toJS$1 () { - return toJS(this); -}; - -Record.prototype.entries = function entries () { - return this.__iterator(ITERATE_ENTRIES); -}; - -Record.prototype.__iterator = function __iterator (type, reverse) { - return recordSeq(this).__iterator(type, reverse); -}; - -Record.prototype.__iterate = function __iterate (fn, reverse) { - return recordSeq(this).__iterate(fn, reverse); -}; - -Record.prototype.__ensureOwner = function __ensureOwner (ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newValues = this._values.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._values = newValues; - return this; - } - return makeRecord(this, newValues, ownerID); -}; - -Record.isRecord = isRecord; -Record.getDescriptiveName = recordName; -var RecordPrototype = Record.prototype; -RecordPrototype[IS_RECORD_SYMBOL] = true; -RecordPrototype[DELETE] = RecordPrototype.remove; -RecordPrototype.deleteIn = RecordPrototype.removeIn = deleteIn; -RecordPrototype.getIn = getIn; -RecordPrototype.hasIn = CollectionPrototype.hasIn; -RecordPrototype.merge = merge$1; -RecordPrototype.mergeWith = mergeWith$1; -RecordPrototype.mergeIn = mergeIn; -RecordPrototype.mergeDeep = mergeDeep; -RecordPrototype.mergeDeepWith = mergeDeepWith; -RecordPrototype.mergeDeepIn = mergeDeepIn; -RecordPrototype.setIn = setIn; -RecordPrototype.update = update; -RecordPrototype.updateIn = updateIn; -RecordPrototype.withMutations = withMutations; -RecordPrototype.asMutable = asMutable; -RecordPrototype.asImmutable = asImmutable; -RecordPrototype[ITERATOR_SYMBOL] = RecordPrototype.entries; -RecordPrototype.toJSON = RecordPrototype.toObject = - CollectionPrototype.toObject; -RecordPrototype.inspect = RecordPrototype.toSource = function () { - return this.toString(); -}; - -function makeRecord(likeRecord, values, ownerID) { - var record = Object.create(Object.getPrototypeOf(likeRecord)); - record._values = values; - record.__ownerID = ownerID; - return record; -} - -function recordName(record) { - return record.constructor.displayName || record.constructor.name || 'Record'; -} - -function recordSeq(record) { - return keyedSeqFromValue(record._keys.map(function (k) { return [k, record.get(k)]; })); -} - -function setProp(prototype, name) { - try { - Object.defineProperty(prototype, name, { - get: function () { - return this.get(name); - }, - set: function (value) { - invariant(this.__ownerID, 'Cannot set on an immutable record.'); - this.set(name, value); - }, - }); - } catch (error) { - // Object.defineProperty failed. Probably IE8. - } -} - -/** - * Returns a lazy Seq of `value` repeated `times` times. When `times` is - * undefined, returns an infinite sequence of `value`. - */ -var Repeat = /*@__PURE__*/(function (IndexedSeq) { - function Repeat(value, times) { - if (!(this instanceof Repeat)) { - // eslint-disable-next-line no-constructor-return - return new Repeat(value, times); - } - this._value = value; - this.size = times === undefined ? Infinity : Math.max(0, times); - if (this.size === 0) { - if (EMPTY_REPEAT) { - // eslint-disable-next-line no-constructor-return - return EMPTY_REPEAT; - } - EMPTY_REPEAT = this; - } - } - - if ( IndexedSeq ) Repeat.__proto__ = IndexedSeq; - Repeat.prototype = Object.create( IndexedSeq && IndexedSeq.prototype ); - Repeat.prototype.constructor = Repeat; - - Repeat.prototype.toString = function toString () { - if (this.size === 0) { - return 'Repeat []'; - } - return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; - }; - - Repeat.prototype.get = function get (index, notSetValue) { - return this.has(index) ? this._value : notSetValue; - }; - - Repeat.prototype.includes = function includes (searchValue) { - return is(this._value, searchValue); - }; - - Repeat.prototype.slice = function slice (begin, end) { - var size = this.size; - return wholeSlice(begin, end, size) - ? this - : new Repeat( - this._value, - resolveEnd(end, size) - resolveBegin(begin, size) - ); - }; - - Repeat.prototype.reverse = function reverse () { - return this; - }; - - Repeat.prototype.indexOf = function indexOf (searchValue) { - if (is(this._value, searchValue)) { - return 0; - } - return -1; - }; - - Repeat.prototype.lastIndexOf = function lastIndexOf (searchValue) { - if (is(this._value, searchValue)) { - return this.size; - } - return -1; - }; - - Repeat.prototype.__iterate = function __iterate (fn, reverse) { - var size = this.size; - var i = 0; - while (i !== size) { - if (fn(this._value, reverse ? size - ++i : i++, this) === false) { - break; - } - } - return i; - }; - - Repeat.prototype.__iterator = function __iterator (type, reverse) { - var this$1$1 = this; - - var size = this.size; - var i = 0; - return new Iterator(function () { return i === size - ? iteratorDone() - : iteratorValue(type, reverse ? size - ++i : i++, this$1$1._value); } - ); - }; - - Repeat.prototype.equals = function equals (other) { - return other instanceof Repeat - ? is(this._value, other._value) - : deepEqual(this, other); - }; - - return Repeat; -}(IndexedSeq)); - -var EMPTY_REPEAT; - -function fromJS(value, converter) { - return fromJSWith( - [], - converter || defaultConverter, - value, - '', - converter && converter.length > 2 ? [] : undefined, - { '': value } - ); -} - -function fromJSWith(stack, converter, value, key, keyPath, parentValue) { - if ( - typeof value !== 'string' && - !isImmutable(value) && - (isArrayLike(value) || hasIterator(value) || isPlainObject(value)) - ) { - if (~stack.indexOf(value)) { - throw new TypeError('Cannot convert circular structure to Immutable'); - } - stack.push(value); - keyPath && key !== '' && keyPath.push(key); - var converted = converter.call( - parentValue, - key, - Seq(value).map(function (v, k) { return fromJSWith(stack, converter, v, k, keyPath, value); } - ), - keyPath && keyPath.slice() - ); - stack.pop(); - keyPath && keyPath.pop(); - return converted; - } - return value; -} - -function defaultConverter(k, v) { - // Effectively the opposite of "Collection.toSeq()" - return isIndexed(v) ? v.toList() : isKeyed(v) ? v.toMap() : v.toSet(); -} - -var version = "4.3.7"; - -var Immutable = { - version: version, - - Collection: Collection, - // Note: Iterable is deprecated - Iterable: Collection, - - Seq: Seq, - Map: Map, - OrderedMap: OrderedMap, - List: List, - Stack: Stack, - Set: Set, - OrderedSet: OrderedSet, - PairSorting: PairSorting, - - Record: Record, - Range: Range, - Repeat: Repeat, - - is: is, - fromJS: fromJS, - hash: hash, - - isImmutable: isImmutable, - isCollection: isCollection, - isKeyed: isKeyed, - isIndexed: isIndexed, - isAssociative: isAssociative, - isOrdered: isOrdered, - isValueObject: isValueObject, - isPlainObject: isPlainObject, - isSeq: isSeq, - isList: isList, - isMap: isMap, - isOrderedMap: isOrderedMap, - isStack: isStack, - isSet: isSet, - isOrderedSet: isOrderedSet, - isRecord: isRecord, - - get: get, - getIn: getIn$1, - has: has, - hasIn: hasIn$1, - merge: merge, - mergeDeep: mergeDeep$1, - mergeWith: mergeWith, - mergeDeepWith: mergeDeepWith$1, - remove: remove, - removeIn: removeIn, - set: set, - setIn: setIn$1, - update: update$1, - updateIn: updateIn$1, -}; - -// Note: Iterable is deprecated -var Iterable = Collection; - -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Immutable); - - - -/***/ }), - -/***/ "?1e65": -/*!************************!*\ - !*** assert (ignored) ***! - \************************/ -/***/ (() => { - -/* (ignored) */ - -/***/ }), - -/***/ "./node_modules/goober/dist/goober.modern.js": -/*!***************************************************!*\ - !*** ./node_modules/goober/dist/goober.modern.js ***! - \***************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ css: () => (/* binding */ u), -/* harmony export */ extractCss: () => (/* binding */ r), -/* harmony export */ glob: () => (/* binding */ b), -/* harmony export */ keyframes: () => (/* binding */ h), -/* harmony export */ setup: () => (/* binding */ m), -/* harmony export */ styled: () => (/* binding */ j) -/* harmony export */ }); -let e={data:""},t=t=>"object"==typeof window?((t?t.querySelector("#_goober"):window._goober)||Object.assign((t||document.head).appendChild(document.createElement("style")),{innerHTML:" ",id:"_goober"})).firstChild:t||e,r=e=>{let r=t(e),l=r.data;return r.data="",l},l=/(?:([\u0080-\uFFFF\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\s*)/g,a=/\/\*[^]*?\*\/| +/g,n=/\n+/g,o=(e,t)=>{let r="",l="",a="";for(let n in e){let c=e[n];"@"==n[0]?"i"==n[1]?r=n+" "+c+";":l+="f"==n[1]?o(c,n):n+"{"+o(c,"k"==n[1]?"":t)+"}":"object"==typeof c?l+=o(c,t?t.replace(/([^,])+/g,e=>n.replace(/(^:.*)|([^,])+/g,t=>/&/.test(t)?t.replace(/&/g,e):e?e+" "+t:t)):n):null!=c&&(n=/^--/.test(n)?n:n.replace(/[A-Z]/g,"-$&").toLowerCase(),a+=o.p?o.p(n,c):n+":"+c+";")}return r+(t&&a?t+"{"+a+"}":a)+l},c={},s=e=>{if("object"==typeof e){let t="";for(let r in e)t+=r+s(e[r]);return t}return e},i=(e,t,r,i,p)=>{let u=s(e),d=c[u]||(c[u]=(e=>{let t=0,r=11;for(;t>>0;return"go"+r})(u));if(!c[d]){let t=u!==e?e:(e=>{let t,r,o=[{}];for(;t=l.exec(e.replace(a,""));)t[4]?o.shift():t[3]?(r=t[3].replace(n," ").trim(),o.unshift(o[0][r]=o[0][r]||{})):o[0][t[1]]=t[2].replace(n," ").trim();return o[0]})(e);c[d]=o(p?{["@keyframes "+d]:t}:t,r?"":"."+d)}let f=r&&c.g?c.g:null;return r&&(c.g=c[d]),((e,t,r,l)=>{l?t.data=t.data.replace(l,e):-1===t.data.indexOf(e)&&(t.data=r?e+t.data:t.data+e)})(c[d],t,i,f),d},p=(e,t,r)=>e.reduce((e,l,a)=>{let n=t[a];if(n&&n.call){let e=n(r),t=e&&e.props&&e.props.className||/^go/.test(e)&&e;n=t?"."+t:e&&"object"==typeof e?e.props?"":o(e,""):!1===e?"":e}return e+l+(null==n?"":n)},"");function u(e){let r=this||{},l=e.call?e(r.p):e;return i(l.unshift?l.raw?p(l,[].slice.call(arguments,1),r.p):l.reduce((e,t)=>Object.assign(e,t&&t.call?t(r.p):t),{}):l,t(r.target),r.g,r.o,r.k)}let d,f,g,b=u.bind({g:1}),h=u.bind({k:1});function m(e,t,r,l){o.p=t,d=e,f=r,g=l}function j(e,t){let r=this||{};return function(){let l=arguments;function a(n,o){let c=Object.assign({},n),s=c.className||a.className;r.p=Object.assign({theme:f&&f()},c),r.o=/ *go\d+/.test(s),c.className=u.apply(r,l)+(s?" "+s:""),t&&(c.ref=o);let i=e;return e[0]&&(i=c.as||e,delete c.as),g&&i[0]&&g(c),d(i,c)}return t?t(a):a}} - - -/***/ }), - -/***/ "./node_modules/solid-js/dist/dev.js": -/*!*******************************************!*\ - !*** ./node_modules/solid-js/dist/dev.js ***! - \*******************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ $DEVCOMP: () => (/* binding */ $DEVCOMP), -/* harmony export */ $PROXY: () => (/* binding */ $PROXY), -/* harmony export */ $TRACK: () => (/* binding */ $TRACK), -/* harmony export */ DEV: () => (/* binding */ DEV), -/* harmony export */ ErrorBoundary: () => (/* binding */ ErrorBoundary), -/* harmony export */ For: () => (/* binding */ For), -/* harmony export */ Index: () => (/* binding */ Index), -/* harmony export */ Match: () => (/* binding */ Match), -/* harmony export */ Show: () => (/* binding */ Show), -/* harmony export */ Suspense: () => (/* binding */ Suspense), -/* harmony export */ SuspenseList: () => (/* binding */ SuspenseList), -/* harmony export */ Switch: () => (/* binding */ Switch), -/* harmony export */ batch: () => (/* binding */ batch), -/* harmony export */ cancelCallback: () => (/* binding */ cancelCallback), -/* harmony export */ catchError: () => (/* binding */ catchError), -/* harmony export */ children: () => (/* binding */ children), -/* harmony export */ createComponent: () => (/* binding */ createComponent), -/* harmony export */ createComputed: () => (/* binding */ createComputed), -/* harmony export */ createContext: () => (/* binding */ createContext), -/* harmony export */ createDeferred: () => (/* binding */ createDeferred), -/* harmony export */ createEffect: () => (/* binding */ createEffect), -/* harmony export */ createMemo: () => (/* binding */ createMemo), -/* harmony export */ createReaction: () => (/* binding */ createReaction), -/* harmony export */ createRenderEffect: () => (/* binding */ createRenderEffect), -/* harmony export */ createResource: () => (/* binding */ createResource), -/* harmony export */ createRoot: () => (/* binding */ createRoot), -/* harmony export */ createSelector: () => (/* binding */ createSelector), -/* harmony export */ createSignal: () => (/* binding */ createSignal), -/* harmony export */ createUniqueId: () => (/* binding */ createUniqueId), -/* harmony export */ enableExternalSource: () => (/* binding */ enableExternalSource), -/* harmony export */ enableHydration: () => (/* binding */ enableHydration), -/* harmony export */ enableScheduling: () => (/* binding */ enableScheduling), -/* harmony export */ equalFn: () => (/* binding */ equalFn), -/* harmony export */ from: () => (/* binding */ from), -/* harmony export */ getListener: () => (/* binding */ getListener), -/* harmony export */ getOwner: () => (/* binding */ getOwner), -/* harmony export */ indexArray: () => (/* binding */ indexArray), -/* harmony export */ lazy: () => (/* binding */ lazy), -/* harmony export */ mapArray: () => (/* binding */ mapArray), -/* harmony export */ mergeProps: () => (/* binding */ mergeProps), -/* harmony export */ observable: () => (/* binding */ observable), -/* harmony export */ on: () => (/* binding */ on), -/* harmony export */ onCleanup: () => (/* binding */ onCleanup), -/* harmony export */ onError: () => (/* binding */ onError), -/* harmony export */ onMount: () => (/* binding */ onMount), -/* harmony export */ requestCallback: () => (/* binding */ requestCallback), -/* harmony export */ resetErrorBoundaries: () => (/* binding */ resetErrorBoundaries), -/* harmony export */ runWithOwner: () => (/* binding */ runWithOwner), -/* harmony export */ sharedConfig: () => (/* binding */ sharedConfig), -/* harmony export */ splitProps: () => (/* binding */ splitProps), -/* harmony export */ startTransition: () => (/* binding */ startTransition), -/* harmony export */ untrack: () => (/* binding */ untrack), -/* harmony export */ useContext: () => (/* binding */ useContext), -/* harmony export */ useTransition: () => (/* binding */ useTransition) -/* harmony export */ }); -let taskIdCounter = 1, - isCallbackScheduled = false, - isPerformingWork = false, - taskQueue = [], - currentTask = null, - shouldYieldToHost = null, - yieldInterval = 5, - deadline = 0, - maxYieldInterval = 300, - scheduleCallback = null, - scheduledCallback = null; -const maxSigned31BitInt = 1073741823; -function setupScheduler() { - const channel = new MessageChannel(), - port = channel.port2; - scheduleCallback = () => port.postMessage(null); - channel.port1.onmessage = () => { - if (scheduledCallback !== null) { - const currentTime = performance.now(); - deadline = currentTime + yieldInterval; - const hasTimeRemaining = true; - try { - const hasMoreWork = scheduledCallback(hasTimeRemaining, currentTime); - if (!hasMoreWork) { - scheduledCallback = null; - } else port.postMessage(null); - } catch (error) { - port.postMessage(null); - throw error; - } - } - }; - if (navigator && navigator.scheduling && navigator.scheduling.isInputPending) { - const scheduling = navigator.scheduling; - shouldYieldToHost = () => { - const currentTime = performance.now(); - if (currentTime >= deadline) { - if (scheduling.isInputPending()) { - return true; - } - return currentTime >= maxYieldInterval; - } else { - return false; - } - }; - } else { - shouldYieldToHost = () => performance.now() >= deadline; - } -} -function enqueue(taskQueue, task) { - function findIndex() { - let m = 0; - let n = taskQueue.length - 1; - while (m <= n) { - const k = n + m >> 1; - const cmp = task.expirationTime - taskQueue[k].expirationTime; - if (cmp > 0) m = k + 1;else if (cmp < 0) n = k - 1;else return k; - } - return m; - } - taskQueue.splice(findIndex(), 0, task); -} -function requestCallback(fn, options) { - if (!scheduleCallback) setupScheduler(); - let startTime = performance.now(), - timeout = maxSigned31BitInt; - if (options && options.timeout) timeout = options.timeout; - const newTask = { - id: taskIdCounter++, - fn, - startTime, - expirationTime: startTime + timeout - }; - enqueue(taskQueue, newTask); - if (!isCallbackScheduled && !isPerformingWork) { - isCallbackScheduled = true; - scheduledCallback = flushWork; - scheduleCallback(); - } - return newTask; -} -function cancelCallback(task) { - task.fn = null; -} -function flushWork(hasTimeRemaining, initialTime) { - isCallbackScheduled = false; - isPerformingWork = true; - try { - return workLoop(hasTimeRemaining, initialTime); - } finally { - currentTask = null; - isPerformingWork = false; - } -} -function workLoop(hasTimeRemaining, initialTime) { - let currentTime = initialTime; - currentTask = taskQueue[0] || null; - while (currentTask !== null) { - if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) { - break; - } - const callback = currentTask.fn; - if (callback !== null) { - currentTask.fn = null; - const didUserCallbackTimeout = currentTask.expirationTime <= currentTime; - callback(didUserCallbackTimeout); - currentTime = performance.now(); - if (currentTask === taskQueue[0]) { - taskQueue.shift(); - } - } else taskQueue.shift(); - currentTask = taskQueue[0] || null; - } - return currentTask !== null; -} - -const sharedConfig = { - context: undefined, - registry: undefined, - effects: undefined, - done: false, - getContextId() { - return getContextId(this.context.count); - }, - getNextContextId() { - return getContextId(this.context.count++); - } -}; -function getContextId(count) { - const num = String(count), - len = num.length - 1; - return sharedConfig.context.id + (len ? String.fromCharCode(96 + len) : "") + num; -} -function setHydrateContext(context) { - sharedConfig.context = context; -} -function nextHydrateContext() { - return { - ...sharedConfig.context, - id: sharedConfig.getNextContextId(), - count: 0 - }; -} - -const equalFn = (a, b) => a === b; -const $PROXY = Symbol("solid-proxy"); -const $TRACK = Symbol("solid-track"); -const $DEVCOMP = Symbol("solid-dev-component"); -const signalOptions = { - equals: equalFn -}; -let ERROR = null; -let runEffects = runQueue; -const STALE = 1; -const PENDING = 2; -const UNOWNED = { - owned: null, - cleanups: null, - context: null, - owner: null -}; -const NO_INIT = {}; -var Owner = null; -let Transition = null; -let Scheduler = null; -let ExternalSourceConfig = null; -let Listener = null; -let Updates = null; -let Effects = null; -let ExecCount = 0; -const DevHooks = { - afterUpdate: null, - afterCreateOwner: null, - afterCreateSignal: null -}; -function createRoot(fn, detachedOwner) { - const listener = Listener, - owner = Owner, - unowned = fn.length === 0, - current = detachedOwner === undefined ? owner : detachedOwner, - root = unowned ? { - owned: null, - cleanups: null, - context: null, - owner: null - } : { - owned: null, - cleanups: null, - context: current ? current.context : null, - owner: current - }, - updateFn = unowned ? () => fn(() => { - throw new Error("Dispose method must be an explicit argument to createRoot function"); - }) : () => fn(() => untrack(() => cleanNode(root))); - DevHooks.afterCreateOwner && DevHooks.afterCreateOwner(root); - Owner = root; - Listener = null; - try { - return runUpdates(updateFn, true); - } finally { - Listener = listener; - Owner = owner; - } -} -function createSignal(value, options) { - options = options ? Object.assign({}, signalOptions, options) : signalOptions; - const s = { - value, - observers: null, - observerSlots: null, - comparator: options.equals || undefined - }; - { - if (options.name) s.name = options.name; - if (DevHooks.afterCreateSignal) DevHooks.afterCreateSignal(s); - if (!options.internal) registerGraph(s); - } - const setter = value => { - if (typeof value === "function") { - if (Transition && Transition.running && Transition.sources.has(s)) value = value(s.tValue);else value = value(s.value); - } - return writeSignal(s, value); - }; - return [readSignal.bind(s), setter]; -} -function createComputed(fn, value, options) { - const c = createComputation(fn, value, true, STALE, options ); - if (Scheduler && Transition && Transition.running) Updates.push(c);else updateComputation(c); -} -function createRenderEffect(fn, value, options) { - const c = createComputation(fn, value, false, STALE, options ); - if (Scheduler && Transition && Transition.running) Updates.push(c);else updateComputation(c); -} -function createEffect(fn, value, options) { - runEffects = runUserEffects; - const c = createComputation(fn, value, false, STALE, options ), - s = SuspenseContext && useContext(SuspenseContext); - if (s) c.suspense = s; - if (!options || !options.render) c.user = true; - Effects ? Effects.push(c) : updateComputation(c); -} -function createReaction(onInvalidate, options) { - let fn; - const c = createComputation(() => { - fn ? fn() : untrack(onInvalidate); - fn = undefined; - }, undefined, false, 0, options ), - s = SuspenseContext && useContext(SuspenseContext); - if (s) c.suspense = s; - c.user = true; - return tracking => { - fn = tracking; - updateComputation(c); - }; -} -function createMemo(fn, value, options) { - options = options ? Object.assign({}, signalOptions, options) : signalOptions; - const c = createComputation(fn, value, true, 0, options ); - c.observers = null; - c.observerSlots = null; - c.comparator = options.equals || undefined; - if (Scheduler && Transition && Transition.running) { - c.tState = STALE; - Updates.push(c); - } else updateComputation(c); - return readSignal.bind(c); -} -function isPromise(v) { - return v && typeof v === "object" && "then" in v; -} -function createResource(pSource, pFetcher, pOptions) { - let source; - let fetcher; - let options; - if (arguments.length === 2 && typeof pFetcher === "object" || arguments.length === 1) { - source = true; - fetcher = pSource; - options = pFetcher || {}; - } else { - source = pSource; - fetcher = pFetcher; - options = pOptions || {}; - } - let pr = null, - initP = NO_INIT, - id = null, - loadedUnderTransition = false, - scheduled = false, - resolved = ("initialValue" in options), - dynamic = typeof source === "function" && createMemo(source); - const contexts = new Set(), - [value, setValue] = (options.storage || createSignal)(options.initialValue), - [error, setError] = createSignal(undefined), - [track, trigger] = createSignal(undefined, { - equals: false - }), - [state, setState] = createSignal(resolved ? "ready" : "unresolved"); - if (sharedConfig.context) { - id = sharedConfig.getNextContextId(); - if (options.ssrLoadFrom === "initial") initP = options.initialValue;else if (sharedConfig.load && sharedConfig.has(id)) initP = sharedConfig.load(id); - } - function loadEnd(p, v, error, key) { - if (pr === p) { - pr = null; - key !== undefined && (resolved = true); - if ((p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, { - value: v - })); - initP = NO_INIT; - if (Transition && p && loadedUnderTransition) { - Transition.promises.delete(p); - loadedUnderTransition = false; - runUpdates(() => { - Transition.running = true; - completeLoad(v, error); - }, false); - } else completeLoad(v, error); - } - return v; - } - function completeLoad(v, err) { - runUpdates(() => { - if (err === undefined) setValue(() => v); - setState(err !== undefined ? "errored" : resolved ? "ready" : "unresolved"); - setError(err); - for (const c of contexts.keys()) c.decrement(); - contexts.clear(); - }, false); - } - function read() { - const c = SuspenseContext && useContext(SuspenseContext), - v = value(), - err = error(); - if (err !== undefined && !pr) throw err; - if (Listener && !Listener.user && c) { - createComputed(() => { - track(); - if (pr) { - if (c.resolved && Transition && loadedUnderTransition) Transition.promises.add(pr);else if (!contexts.has(c)) { - c.increment(); - contexts.add(c); - } - } - }); - } - return v; - } - function load(refetching = true) { - if (refetching !== false && scheduled) return; - scheduled = false; - const lookup = dynamic ? dynamic() : source; - loadedUnderTransition = Transition && Transition.running; - if (lookup == null || lookup === false) { - loadEnd(pr, untrack(value)); - return; - } - if (Transition && pr) Transition.promises.delete(pr); - const p = initP !== NO_INIT ? initP : untrack(() => fetcher(lookup, { - value: value(), - refetching - })); - if (!isPromise(p)) { - loadEnd(pr, p, undefined, lookup); - return p; - } - pr = p; - if ("value" in p) { - if (p.status === "success") loadEnd(pr, p.value, undefined, lookup);else loadEnd(pr, undefined, castError(p.value), lookup); - return p; - } - scheduled = true; - queueMicrotask(() => scheduled = false); - runUpdates(() => { - setState(resolved ? "refreshing" : "pending"); - trigger(); - }, false); - return p.then(v => loadEnd(p, v, undefined, lookup), e => loadEnd(p, undefined, castError(e), lookup)); - } - Object.defineProperties(read, { - state: { - get: () => state() - }, - error: { - get: () => error() - }, - loading: { - get() { - const s = state(); - return s === "pending" || s === "refreshing"; - } - }, - latest: { - get() { - if (!resolved) return read(); - const err = error(); - if (err && !pr) throw err; - return value(); - } - } - }); - if (dynamic) createComputed(() => load(false));else load(false); - return [read, { - refetch: load, - mutate: setValue - }]; -} -function createDeferred(source, options) { - let t, - timeout = options ? options.timeoutMs : undefined; - const node = createComputation(() => { - if (!t || !t.fn) t = requestCallback(() => setDeferred(() => node.value), timeout !== undefined ? { - timeout - } : undefined); - return source(); - }, undefined, true); - const [deferred, setDeferred] = createSignal(Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value, options); - updateComputation(node); - setDeferred(() => Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value); - return deferred; -} -function createSelector(source, fn = equalFn, options) { - const subs = new Map(); - const node = createComputation(p => { - const v = source(); - for (const [key, val] of subs.entries()) if (fn(key, v) !== fn(key, p)) { - for (const c of val.values()) { - c.state = STALE; - if (c.pure) Updates.push(c);else Effects.push(c); - } - } - return v; - }, undefined, true, STALE, options ); - updateComputation(node); - return key => { - const listener = Listener; - if (listener) { - let l; - if (l = subs.get(key)) l.add(listener);else subs.set(key, l = new Set([listener])); - onCleanup(() => { - l.delete(listener); - !l.size && subs.delete(key); - }); - } - return fn(key, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value); - }; -} -function batch(fn) { - return runUpdates(fn, false); -} -function untrack(fn) { - if (!ExternalSourceConfig && Listener === null) return fn(); - const listener = Listener; - Listener = null; - try { - if (ExternalSourceConfig) return ExternalSourceConfig.untrack(fn); - return fn(); - } finally { - Listener = listener; - } -} -function on(deps, fn, options) { - const isArray = Array.isArray(deps); - let prevInput; - let defer = options && options.defer; - return prevValue => { - let input; - if (isArray) { - input = Array(deps.length); - for (let i = 0; i < deps.length; i++) input[i] = deps[i](); - } else input = deps(); - if (defer) { - defer = false; - return prevValue; - } - const result = untrack(() => fn(input, prevInput, prevValue)); - prevInput = input; - return result; - }; -} -function onMount(fn) { - createEffect(() => untrack(fn)); -} -function onCleanup(fn) { - if (Owner === null) console.warn("cleanups created outside a `createRoot` or `render` will never be run");else if (Owner.cleanups === null) Owner.cleanups = [fn];else Owner.cleanups.push(fn); - return fn; -} -function catchError(fn, handler) { - ERROR || (ERROR = Symbol("error")); - Owner = createComputation(undefined, undefined, true); - Owner.context = { - ...Owner.context, - [ERROR]: [handler] - }; - if (Transition && Transition.running) Transition.sources.add(Owner); - try { - return fn(); - } catch (err) { - handleError(err); - } finally { - Owner = Owner.owner; - } -} -function getListener() { - return Listener; -} -function getOwner() { - return Owner; -} -function runWithOwner(o, fn) { - const prev = Owner; - const prevListener = Listener; - Owner = o; - Listener = null; - try { - return runUpdates(fn, true); - } catch (err) { - handleError(err); - } finally { - Owner = prev; - Listener = prevListener; - } -} -function enableScheduling(scheduler = requestCallback) { - Scheduler = scheduler; -} -function startTransition(fn) { - if (Transition && Transition.running) { - fn(); - return Transition.done; - } - const l = Listener; - const o = Owner; - return Promise.resolve().then(() => { - Listener = l; - Owner = o; - let t; - if (Scheduler || SuspenseContext) { - t = Transition || (Transition = { - sources: new Set(), - effects: [], - promises: new Set(), - disposed: new Set(), - queue: new Set(), - running: true - }); - t.done || (t.done = new Promise(res => t.resolve = res)); - t.running = true; - } - runUpdates(fn, false); - Listener = Owner = null; - return t ? t.done : undefined; - }); -} -const [transPending, setTransPending] = /*@__PURE__*/createSignal(false); -function useTransition() { - return [transPending, startTransition]; -} -function resumeEffects(e) { - Effects.push.apply(Effects, e); - e.length = 0; -} -function devComponent(Comp, props) { - const c = createComputation(() => untrack(() => { - Object.assign(Comp, { - [$DEVCOMP]: true - }); - return Comp(props); - }), undefined, true, 0); - c.props = props; - c.observers = null; - c.observerSlots = null; - c.name = Comp.name; - c.component = Comp; - updateComputation(c); - return c.tValue !== undefined ? c.tValue : c.value; -} -function registerGraph(value) { - if (!Owner) return; - if (Owner.sourceMap) Owner.sourceMap.push(value);else Owner.sourceMap = [value]; - value.graph = Owner; -} -function createContext(defaultValue, options) { - const id = Symbol("context"); - return { - id, - Provider: createProvider(id, options), - defaultValue - }; -} -function useContext(context) { - let value; - return Owner && Owner.context && (value = Owner.context[context.id]) !== undefined ? value : context.defaultValue; -} -function children(fn) { - const children = createMemo(fn); - const memo = createMemo(() => resolveChildren(children()), undefined, { - name: "children" - }) ; - memo.toArray = () => { - const c = memo(); - return Array.isArray(c) ? c : c != null ? [c] : []; - }; - return memo; -} -let SuspenseContext; -function getSuspenseContext() { - return SuspenseContext || (SuspenseContext = createContext()); -} -function enableExternalSource(factory, untrack = fn => fn()) { - if (ExternalSourceConfig) { - const { - factory: oldFactory, - untrack: oldUntrack - } = ExternalSourceConfig; - ExternalSourceConfig = { - factory: (fn, trigger) => { - const oldSource = oldFactory(fn, trigger); - const source = factory(x => oldSource.track(x), trigger); - return { - track: x => source.track(x), - dispose() { - source.dispose(); - oldSource.dispose(); - } - }; - }, - untrack: fn => oldUntrack(() => untrack(fn)) - }; - } else { - ExternalSourceConfig = { - factory, - untrack - }; - } -} -function readSignal() { - const runningTransition = Transition && Transition.running; - if (this.sources && (runningTransition ? this.tState : this.state)) { - if ((runningTransition ? this.tState : this.state) === STALE) updateComputation(this);else { - const updates = Updates; - Updates = null; - runUpdates(() => lookUpstream(this), false); - Updates = updates; - } - } - if (Listener) { - const sSlot = this.observers ? this.observers.length : 0; - if (!Listener.sources) { - Listener.sources = [this]; - Listener.sourceSlots = [sSlot]; - } else { - Listener.sources.push(this); - Listener.sourceSlots.push(sSlot); - } - if (!this.observers) { - this.observers = [Listener]; - this.observerSlots = [Listener.sources.length - 1]; - } else { - this.observers.push(Listener); - this.observerSlots.push(Listener.sources.length - 1); - } - } - if (runningTransition && Transition.sources.has(this)) return this.tValue; - return this.value; -} -function writeSignal(node, value, isComp) { - let current = Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value; - if (!node.comparator || !node.comparator(current, value)) { - if (Transition) { - const TransitionRunning = Transition.running; - if (TransitionRunning || !isComp && Transition.sources.has(node)) { - Transition.sources.add(node); - node.tValue = value; - } - if (!TransitionRunning) node.value = value; - } else node.value = value; - if (node.observers && node.observers.length) { - runUpdates(() => { - for (let i = 0; i < node.observers.length; i += 1) { - const o = node.observers[i]; - const TransitionRunning = Transition && Transition.running; - if (TransitionRunning && Transition.disposed.has(o)) continue; - if (TransitionRunning ? !o.tState : !o.state) { - if (o.pure) Updates.push(o);else Effects.push(o); - if (o.observers) markDownstream(o); - } - if (!TransitionRunning) o.state = STALE;else o.tState = STALE; - } - if (Updates.length > 10e5) { - Updates = []; - if (true) throw new Error("Potential Infinite Loop Detected."); - throw new Error(); - } - }, false); - } - } - return value; -} -function updateComputation(node) { - if (!node.fn) return; - cleanNode(node); - const time = ExecCount; - runComputation(node, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value, time); - if (Transition && !Transition.running && Transition.sources.has(node)) { - queueMicrotask(() => { - runUpdates(() => { - Transition && (Transition.running = true); - Listener = Owner = node; - runComputation(node, node.tValue, time); - Listener = Owner = null; - }, false); - }); - } -} -function runComputation(node, value, time) { - let nextValue; - const owner = Owner, - listener = Listener; - Listener = Owner = node; - try { - nextValue = node.fn(value); - } catch (err) { - if (node.pure) { - if (Transition && Transition.running) { - node.tState = STALE; - node.tOwned && node.tOwned.forEach(cleanNode); - node.tOwned = undefined; - } else { - node.state = STALE; - node.owned && node.owned.forEach(cleanNode); - node.owned = null; - } - } - node.updatedAt = time + 1; - return handleError(err); - } finally { - Listener = listener; - Owner = owner; - } - if (!node.updatedAt || node.updatedAt <= time) { - if (node.updatedAt != null && "observers" in node) { - writeSignal(node, nextValue, true); - } else if (Transition && Transition.running && node.pure) { - Transition.sources.add(node); - node.tValue = nextValue; - } else node.value = nextValue; - node.updatedAt = time; - } -} -function createComputation(fn, init, pure, state = STALE, options) { - const c = { - fn, - state: state, - updatedAt: null, - owned: null, - sources: null, - sourceSlots: null, - cleanups: null, - value: init, - owner: Owner, - context: Owner ? Owner.context : null, - pure - }; - if (Transition && Transition.running) { - c.state = 0; - c.tState = state; - } - if (Owner === null) console.warn("computations created outside a `createRoot` or `render` will never be disposed");else if (Owner !== UNOWNED) { - if (Transition && Transition.running && Owner.pure) { - if (!Owner.tOwned) Owner.tOwned = [c];else Owner.tOwned.push(c); - } else { - if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c); - } - } - if (options && options.name) c.name = options.name; - if (ExternalSourceConfig && c.fn) { - const [track, trigger] = createSignal(undefined, { - equals: false - }); - const ordinary = ExternalSourceConfig.factory(c.fn, trigger); - onCleanup(() => ordinary.dispose()); - const triggerInTransition = () => startTransition(trigger).then(() => inTransition.dispose()); - const inTransition = ExternalSourceConfig.factory(c.fn, triggerInTransition); - c.fn = x => { - track(); - return Transition && Transition.running ? inTransition.track(x) : ordinary.track(x); - }; - } - DevHooks.afterCreateOwner && DevHooks.afterCreateOwner(c); - return c; -} -function runTop(node) { - const runningTransition = Transition && Transition.running; - if ((runningTransition ? node.tState : node.state) === 0) return; - if ((runningTransition ? node.tState : node.state) === PENDING) return lookUpstream(node); - if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node); - const ancestors = [node]; - while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) { - if (runningTransition && Transition.disposed.has(node)) return; - if (runningTransition ? node.tState : node.state) ancestors.push(node); - } - for (let i = ancestors.length - 1; i >= 0; i--) { - node = ancestors[i]; - if (runningTransition) { - let top = node, - prev = ancestors[i + 1]; - while ((top = top.owner) && top !== prev) { - if (Transition.disposed.has(top)) return; - } - } - if ((runningTransition ? node.tState : node.state) === STALE) { - updateComputation(node); - } else if ((runningTransition ? node.tState : node.state) === PENDING) { - const updates = Updates; - Updates = null; - runUpdates(() => lookUpstream(node, ancestors[0]), false); - Updates = updates; - } - } -} -function runUpdates(fn, init) { - if (Updates) return fn(); - let wait = false; - if (!init) Updates = []; - if (Effects) wait = true;else Effects = []; - ExecCount++; - try { - const res = fn(); - completeUpdates(wait); - return res; - } catch (err) { - if (!wait) Effects = null; - Updates = null; - handleError(err); - } -} -function completeUpdates(wait) { - if (Updates) { - if (Scheduler && Transition && Transition.running) scheduleQueue(Updates);else runQueue(Updates); - Updates = null; - } - if (wait) return; - let res; - if (Transition) { - if (!Transition.promises.size && !Transition.queue.size) { - const sources = Transition.sources; - const disposed = Transition.disposed; - Effects.push.apply(Effects, Transition.effects); - res = Transition.resolve; - for (const e of Effects) { - "tState" in e && (e.state = e.tState); - delete e.tState; - } - Transition = null; - runUpdates(() => { - for (const d of disposed) cleanNode(d); - for (const v of sources) { - v.value = v.tValue; - if (v.owned) { - for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]); - } - if (v.tOwned) v.owned = v.tOwned; - delete v.tValue; - delete v.tOwned; - v.tState = 0; - } - setTransPending(false); - }, false); - } else if (Transition.running) { - Transition.running = false; - Transition.effects.push.apply(Transition.effects, Effects); - Effects = null; - setTransPending(true); - return; - } - } - const e = Effects; - Effects = null; - if (e.length) runUpdates(() => runEffects(e), false);else DevHooks.afterUpdate && DevHooks.afterUpdate(); - if (res) res(); -} -function runQueue(queue) { - for (let i = 0; i < queue.length; i++) runTop(queue[i]); -} -function scheduleQueue(queue) { - for (let i = 0; i < queue.length; i++) { - const item = queue[i]; - const tasks = Transition.queue; - if (!tasks.has(item)) { - tasks.add(item); - Scheduler(() => { - tasks.delete(item); - runUpdates(() => { - Transition.running = true; - runTop(item); - }, false); - Transition && (Transition.running = false); - }); - } - } -} -function runUserEffects(queue) { - let i, - userLength = 0; - for (i = 0; i < queue.length; i++) { - const e = queue[i]; - if (!e.user) runTop(e);else queue[userLength++] = e; - } - if (sharedConfig.context) { - if (sharedConfig.count) { - sharedConfig.effects || (sharedConfig.effects = []); - sharedConfig.effects.push(...queue.slice(0, userLength)); - return; - } - setHydrateContext(); - } - if (sharedConfig.effects && (sharedConfig.done || !sharedConfig.count)) { - queue = [...sharedConfig.effects, ...queue]; - userLength += sharedConfig.effects.length; - delete sharedConfig.effects; - } - for (i = 0; i < userLength; i++) runTop(queue[i]); -} -function lookUpstream(node, ignore) { - const runningTransition = Transition && Transition.running; - if (runningTransition) node.tState = 0;else node.state = 0; - for (let i = 0; i < node.sources.length; i += 1) { - const source = node.sources[i]; - if (source.sources) { - const state = runningTransition ? source.tState : source.state; - if (state === STALE) { - if (source !== ignore && (!source.updatedAt || source.updatedAt < ExecCount)) runTop(source); - } else if (state === PENDING) lookUpstream(source, ignore); - } - } -} -function markDownstream(node) { - const runningTransition = Transition && Transition.running; - for (let i = 0; i < node.observers.length; i += 1) { - const o = node.observers[i]; - if (runningTransition ? !o.tState : !o.state) { - if (runningTransition) o.tState = PENDING;else o.state = PENDING; - if (o.pure) Updates.push(o);else Effects.push(o); - o.observers && markDownstream(o); - } - } -} -function cleanNode(node) { - let i; - if (node.sources) { - while (node.sources.length) { - const source = node.sources.pop(), - index = node.sourceSlots.pop(), - obs = source.observers; - if (obs && obs.length) { - const n = obs.pop(), - s = source.observerSlots.pop(); - if (index < obs.length) { - n.sourceSlots[s] = index; - obs[index] = n; - source.observerSlots[index] = s; - } - } - } - } - if (Transition && Transition.running && node.pure) { - if (node.tOwned) { - for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]); - delete node.tOwned; - } - reset(node, true); - } else if (node.owned) { - for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]); - node.owned = null; - } - if (node.cleanups) { - for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i](); - node.cleanups = null; - } - if (Transition && Transition.running) node.tState = 0;else node.state = 0; - delete node.sourceMap; -} -function reset(node, top) { - if (!top) { - node.tState = 0; - Transition.disposed.add(node); - } - if (node.owned) { - for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]); - } -} -function castError(err) { - if (err instanceof Error) return err; - return new Error(typeof err === "string" ? err : "Unknown error", { - cause: err - }); -} -function runErrors(err, fns, owner) { - try { - for (const f of fns) f(err); - } catch (e) { - handleError(e, owner && owner.owner || null); - } -} -function handleError(err, owner = Owner) { - const fns = ERROR && owner && owner.context && owner.context[ERROR]; - const error = castError(err); - if (!fns) throw error; - if (Effects) Effects.push({ - fn() { - runErrors(error, fns, owner); - }, - state: STALE - });else runErrors(error, fns, owner); -} -function resolveChildren(children) { - if (typeof children === "function" && !children.length) return resolveChildren(children()); - if (Array.isArray(children)) { - const results = []; - for (let i = 0; i < children.length; i++) { - const result = resolveChildren(children[i]); - Array.isArray(result) ? results.push.apply(results, result) : results.push(result); - } - return results; - } - return children; -} -function createProvider(id, options) { - return function provider(props) { - let res; - createRenderEffect(() => res = untrack(() => { - Owner.context = { - ...Owner.context, - [id]: props.value - }; - return children(() => props.children); - }), undefined, options); - return res; - }; -} -function onError(fn) { - ERROR || (ERROR = Symbol("error")); - if (Owner === null) console.warn("error handlers created outside a `createRoot` or `render` will never be run");else if (Owner.context === null || !Owner.context[ERROR]) { - Owner.context = { - ...Owner.context, - [ERROR]: [fn] - }; - mutateContext(Owner, ERROR, [fn]); - } else Owner.context[ERROR].push(fn); -} -function mutateContext(o, key, value) { - if (o.owned) { - for (let i = 0; i < o.owned.length; i++) { - if (o.owned[i].context === o.context) mutateContext(o.owned[i], key, value); - if (!o.owned[i].context) { - o.owned[i].context = o.context; - mutateContext(o.owned[i], key, value); - } else if (!o.owned[i].context[key]) { - o.owned[i].context[key] = value; - mutateContext(o.owned[i], key, value); - } - } - } -} - -function observable(input) { - return { - subscribe(observer) { - if (!(observer instanceof Object) || observer == null) { - throw new TypeError("Expected the observer to be an object."); - } - const handler = typeof observer === "function" ? observer : observer.next && observer.next.bind(observer); - if (!handler) { - return { - unsubscribe() {} - }; - } - const dispose = createRoot(disposer => { - createEffect(() => { - const v = input(); - untrack(() => handler(v)); - }); - return disposer; - }); - if (getOwner()) onCleanup(dispose); - return { - unsubscribe() { - dispose(); - } - }; - }, - [Symbol.observable || "@@observable"]() { - return this; - } - }; -} -function from(producer) { - const [s, set] = createSignal(undefined, { - equals: false - }); - if ("subscribe" in producer) { - const unsub = producer.subscribe(v => set(() => v)); - onCleanup(() => "unsubscribe" in unsub ? unsub.unsubscribe() : unsub()); - } else { - const clean = producer(set); - onCleanup(clean); - } - return s; -} - -const FALLBACK = Symbol("fallback"); -function dispose(d) { - for (let i = 0; i < d.length; i++) d[i](); -} -function mapArray(list, mapFn, options = {}) { - let items = [], - mapped = [], - disposers = [], - len = 0, - indexes = mapFn.length > 1 ? [] : null; - onCleanup(() => dispose(disposers)); - return () => { - let newItems = list() || [], - newLen = newItems.length, - i, - j; - newItems[$TRACK]; - return untrack(() => { - let newIndices, newIndicesNext, temp, tempdisposers, tempIndexes, start, end, newEnd, item; - if (newLen === 0) { - if (len !== 0) { - dispose(disposers); - disposers = []; - items = []; - mapped = []; - len = 0; - indexes && (indexes = []); - } - if (options.fallback) { - items = [FALLBACK]; - mapped[0] = createRoot(disposer => { - disposers[0] = disposer; - return options.fallback(); - }); - len = 1; - } - } - else if (len === 0) { - mapped = new Array(newLen); - for (j = 0; j < newLen; j++) { - items[j] = newItems[j]; - mapped[j] = createRoot(mapper); - } - len = newLen; - } else { - temp = new Array(newLen); - tempdisposers = new Array(newLen); - indexes && (tempIndexes = new Array(newLen)); - for (start = 0, end = Math.min(len, newLen); start < end && items[start] === newItems[start]; start++); - for (end = len - 1, newEnd = newLen - 1; end >= start && newEnd >= start && items[end] === newItems[newEnd]; end--, newEnd--) { - temp[newEnd] = mapped[end]; - tempdisposers[newEnd] = disposers[end]; - indexes && (tempIndexes[newEnd] = indexes[end]); - } - newIndices = new Map(); - newIndicesNext = new Array(newEnd + 1); - for (j = newEnd; j >= start; j--) { - item = newItems[j]; - i = newIndices.get(item); - newIndicesNext[j] = i === undefined ? -1 : i; - newIndices.set(item, j); - } - for (i = start; i <= end; i++) { - item = items[i]; - j = newIndices.get(item); - if (j !== undefined && j !== -1) { - temp[j] = mapped[i]; - tempdisposers[j] = disposers[i]; - indexes && (tempIndexes[j] = indexes[i]); - j = newIndicesNext[j]; - newIndices.set(item, j); - } else disposers[i](); - } - for (j = start; j < newLen; j++) { - if (j in temp) { - mapped[j] = temp[j]; - disposers[j] = tempdisposers[j]; - if (indexes) { - indexes[j] = tempIndexes[j]; - indexes[j](j); - } - } else mapped[j] = createRoot(mapper); - } - mapped = mapped.slice(0, len = newLen); - items = newItems.slice(0); - } - return mapped; - }); - function mapper(disposer) { - disposers[j] = disposer; - if (indexes) { - const [s, set] = createSignal(j, { - name: "index" - }) ; - indexes[j] = set; - return mapFn(newItems[j], s); - } - return mapFn(newItems[j]); - } - }; -} -function indexArray(list, mapFn, options = {}) { - let items = [], - mapped = [], - disposers = [], - signals = [], - len = 0, - i; - onCleanup(() => dispose(disposers)); - return () => { - const newItems = list() || [], - newLen = newItems.length; - newItems[$TRACK]; - return untrack(() => { - if (newLen === 0) { - if (len !== 0) { - dispose(disposers); - disposers = []; - items = []; - mapped = []; - len = 0; - signals = []; - } - if (options.fallback) { - items = [FALLBACK]; - mapped[0] = createRoot(disposer => { - disposers[0] = disposer; - return options.fallback(); - }); - len = 1; - } - return mapped; - } - if (items[0] === FALLBACK) { - disposers[0](); - disposers = []; - items = []; - mapped = []; - len = 0; - } - for (i = 0; i < newLen; i++) { - if (i < items.length && items[i] !== newItems[i]) { - signals[i](() => newItems[i]); - } else if (i >= items.length) { - mapped[i] = createRoot(mapper); - } - } - for (; i < items.length; i++) { - disposers[i](); - } - len = signals.length = disposers.length = newLen; - items = newItems.slice(0); - return mapped = mapped.slice(0, len); - }); - function mapper(disposer) { - disposers[i] = disposer; - const [s, set] = createSignal(newItems[i], { - name: "value" - }) ; - signals[i] = set; - return mapFn(s, i); - } - }; -} - -let hydrationEnabled = false; -function enableHydration() { - hydrationEnabled = true; -} -function createComponent(Comp, props) { - if (hydrationEnabled) { - if (sharedConfig.context) { - const c = sharedConfig.context; - setHydrateContext(nextHydrateContext()); - const r = devComponent(Comp, props || {}) ; - setHydrateContext(c); - return r; - } - } - return devComponent(Comp, props || {}); -} -function trueFn() { - return true; -} -const propTraps = { - get(_, property, receiver) { - if (property === $PROXY) return receiver; - return _.get(property); - }, - has(_, property) { - if (property === $PROXY) return true; - return _.has(property); - }, - set: trueFn, - deleteProperty: trueFn, - getOwnPropertyDescriptor(_, property) { - return { - configurable: true, - enumerable: true, - get() { - return _.get(property); - }, - set: trueFn, - deleteProperty: trueFn - }; - }, - ownKeys(_) { - return _.keys(); - } -}; -function resolveSource(s) { - return !(s = typeof s === "function" ? s() : s) ? {} : s; -} -function resolveSources() { - for (let i = 0, length = this.length; i < length; ++i) { - const v = this[i](); - if (v !== undefined) return v; - } -} -function mergeProps(...sources) { - let proxy = false; - for (let i = 0; i < sources.length; i++) { - const s = sources[i]; - proxy = proxy || !!s && $PROXY in s; - sources[i] = typeof s === "function" ? (proxy = true, createMemo(s)) : s; - } - if (proxy) { - return new Proxy({ - get(property) { - for (let i = sources.length - 1; i >= 0; i--) { - const v = resolveSource(sources[i])[property]; - if (v !== undefined) return v; - } - }, - has(property) { - for (let i = sources.length - 1; i >= 0; i--) { - if (property in resolveSource(sources[i])) return true; - } - return false; - }, - keys() { - const keys = []; - for (let i = 0; i < sources.length; i++) keys.push(...Object.keys(resolveSource(sources[i]))); - return [...new Set(keys)]; - } - }, propTraps); - } - const sourcesMap = {}; - const defined = Object.create(null); - for (let i = sources.length - 1; i >= 0; i--) { - const source = sources[i]; - if (!source) continue; - const sourceKeys = Object.getOwnPropertyNames(source); - for (let i = sourceKeys.length - 1; i >= 0; i--) { - const key = sourceKeys[i]; - if (key === "__proto__" || key === "constructor") continue; - const desc = Object.getOwnPropertyDescriptor(source, key); - if (!defined[key]) { - defined[key] = desc.get ? { - enumerable: true, - configurable: true, - get: resolveSources.bind(sourcesMap[key] = [desc.get.bind(source)]) - } : desc.value !== undefined ? desc : undefined; - } else { - const sources = sourcesMap[key]; - if (sources) { - if (desc.get) sources.push(desc.get.bind(source));else if (desc.value !== undefined) sources.push(() => desc.value); - } - } - } - } - const target = {}; - const definedKeys = Object.keys(defined); - for (let i = definedKeys.length - 1; i >= 0; i--) { - const key = definedKeys[i], - desc = defined[key]; - if (desc && desc.get) Object.defineProperty(target, key, desc);else target[key] = desc ? desc.value : undefined; - } - return target; -} -function splitProps(props, ...keys) { - if ($PROXY in props) { - const blocked = new Set(keys.length > 1 ? keys.flat() : keys[0]); - const res = keys.map(k => { - return new Proxy({ - get(property) { - return k.includes(property) ? props[property] : undefined; - }, - has(property) { - return k.includes(property) && property in props; - }, - keys() { - return k.filter(property => property in props); - } - }, propTraps); - }); - res.push(new Proxy({ - get(property) { - return blocked.has(property) ? undefined : props[property]; - }, - has(property) { - return blocked.has(property) ? false : property in props; - }, - keys() { - return Object.keys(props).filter(k => !blocked.has(k)); - } - }, propTraps)); - return res; - } - const otherObject = {}; - const objects = keys.map(() => ({})); - for (const propName of Object.getOwnPropertyNames(props)) { - const desc = Object.getOwnPropertyDescriptor(props, propName); - const isDefaultDesc = !desc.get && !desc.set && desc.enumerable && desc.writable && desc.configurable; - let blocked = false; - let objectIndex = 0; - for (const k of keys) { - if (k.includes(propName)) { - blocked = true; - isDefaultDesc ? objects[objectIndex][propName] = desc.value : Object.defineProperty(objects[objectIndex], propName, desc); - } - ++objectIndex; - } - if (!blocked) { - isDefaultDesc ? otherObject[propName] = desc.value : Object.defineProperty(otherObject, propName, desc); - } - } - return [...objects, otherObject]; -} -function lazy(fn) { - let comp; - let p; - const wrap = props => { - const ctx = sharedConfig.context; - if (ctx) { - const [s, set] = createSignal(); - sharedConfig.count || (sharedConfig.count = 0); - sharedConfig.count++; - (p || (p = fn())).then(mod => { - !sharedConfig.done && setHydrateContext(ctx); - sharedConfig.count--; - set(() => mod.default); - setHydrateContext(); - }); - comp = s; - } else if (!comp) { - const [s] = createResource(() => (p || (p = fn())).then(mod => mod.default)); - comp = s; - } - let Comp; - return createMemo(() => (Comp = comp()) ? untrack(() => { - if (true) Object.assign(Comp, { - [$DEVCOMP]: true - }); - if (!ctx || sharedConfig.done) return Comp(props); - const c = sharedConfig.context; - setHydrateContext(ctx); - const r = Comp(props); - setHydrateContext(c); - return r; - }) : ""); - }; - wrap.preload = () => p || ((p = fn()).then(mod => comp = () => mod.default), p); - return wrap; -} -let counter = 0; -function createUniqueId() { - const ctx = sharedConfig.context; - return ctx ? sharedConfig.getNextContextId() : `cl-${counter++}`; -} - -const narrowedError = name => `Attempting to access a stale value from <${name}> that could possibly be undefined. This may occur because you are reading the accessor returned from the component at a time where it has already been unmounted. We recommend cleaning up any stale timers or async, or reading from the initial condition.` ; -function For(props) { - const fallback = "fallback" in props && { - fallback: () => props.fallback - }; - return createMemo(mapArray(() => props.each, props.children, fallback || undefined), undefined, { - name: "value" - }) ; -} -function Index(props) { - const fallback = "fallback" in props && { - fallback: () => props.fallback - }; - return createMemo(indexArray(() => props.each, props.children, fallback || undefined), undefined, { - name: "value" - }) ; -} -function Show(props) { - const keyed = props.keyed; - const condition = createMemo(() => props.when, undefined, { - equals: (a, b) => keyed ? a === b : !a === !b, - name: "condition" - } ); - return createMemo(() => { - const c = condition(); - if (c) { - const child = props.children; - const fn = typeof child === "function" && child.length > 0; - return fn ? untrack(() => child(keyed ? c : () => { - if (!untrack(condition)) throw narrowedError("Show"); - return props.when; - })) : child; - } - return props.fallback; - }, undefined, { - name: "value" - } ); -} -function Switch(props) { - let keyed = false; - const equals = (a, b) => (keyed ? a[1] === b[1] : !a[1] === !b[1]) && a[2] === b[2]; - const conditions = children(() => props.children), - evalConditions = createMemo(() => { - let conds = conditions(); - if (!Array.isArray(conds)) conds = [conds]; - for (let i = 0; i < conds.length; i++) { - const c = conds[i].when; - if (c) { - keyed = !!conds[i].keyed; - return [i, c, conds[i]]; - } - } - return [-1]; - }, undefined, { - equals, - name: "eval conditions" - } ); - return createMemo(() => { - const [index, when, cond] = evalConditions(); - if (index < 0) return props.fallback; - const c = cond.children; - const fn = typeof c === "function" && c.length > 0; - return fn ? untrack(() => c(keyed ? when : () => { - if (untrack(evalConditions)[0] !== index) throw narrowedError("Match"); - return cond.when; - })) : c; - }, undefined, { - name: "value" - } ); -} -function Match(props) { - return props; -} -let Errors; -function resetErrorBoundaries() { - Errors && [...Errors].forEach(fn => fn()); -} -function ErrorBoundary(props) { - let err; - if (sharedConfig.context && sharedConfig.load) err = sharedConfig.load(sharedConfig.getContextId()); - const [errored, setErrored] = createSignal(err, { - name: "errored" - } ); - Errors || (Errors = new Set()); - Errors.add(setErrored); - onCleanup(() => Errors.delete(setErrored)); - return createMemo(() => { - let e; - if (e = errored()) { - const f = props.fallback; - if ((typeof f !== "function" || f.length == 0)) console.error(e); - return typeof f === "function" && f.length ? untrack(() => f(e, () => setErrored())) : f; - } - return catchError(() => props.children, setErrored); - }, undefined, { - name: "value" - } ); -} - -const suspenseListEquals = (a, b) => a.showContent === b.showContent && a.showFallback === b.showFallback; -const SuspenseListContext = /* #__PURE__ */createContext(); -function SuspenseList(props) { - let [wrapper, setWrapper] = createSignal(() => ({ - inFallback: false - })), - show; - const listContext = useContext(SuspenseListContext); - const [registry, setRegistry] = createSignal([]); - if (listContext) { - show = listContext.register(createMemo(() => wrapper()().inFallback)); - } - const resolved = createMemo(prev => { - const reveal = props.revealOrder, - tail = props.tail, - { - showContent = true, - showFallback = true - } = show ? show() : {}, - reg = registry(), - reverse = reveal === "backwards"; - if (reveal === "together") { - const all = reg.every(inFallback => !inFallback()); - const res = reg.map(() => ({ - showContent: all && showContent, - showFallback - })); - res.inFallback = !all; - return res; - } - let stop = false; - let inFallback = prev.inFallback; - const res = []; - for (let i = 0, len = reg.length; i < len; i++) { - const n = reverse ? len - i - 1 : i, - s = reg[n](); - if (!stop && !s) { - res[n] = { - showContent, - showFallback - }; - } else { - const next = !stop; - if (next) inFallback = true; - res[n] = { - showContent: next, - showFallback: !tail || next && tail === "collapsed" ? showFallback : false - }; - stop = true; - } - } - if (!stop) inFallback = false; - res.inFallback = inFallback; - return res; - }, { - inFallback: false - }); - setWrapper(() => resolved); - return createComponent(SuspenseListContext.Provider, { - value: { - register: inFallback => { - let index; - setRegistry(registry => { - index = registry.length; - return [...registry, inFallback]; - }); - return createMemo(() => resolved()[index], undefined, { - equals: suspenseListEquals - }); - } - }, - get children() { - return props.children; - } - }); -} -function Suspense(props) { - let counter = 0, - show, - ctx, - p, - flicker, - error; - const [inFallback, setFallback] = createSignal(false), - SuspenseContext = getSuspenseContext(), - store = { - increment: () => { - if (++counter === 1) setFallback(true); - }, - decrement: () => { - if (--counter === 0) setFallback(false); - }, - inFallback, - effects: [], - resolved: false - }, - owner = getOwner(); - if (sharedConfig.context && sharedConfig.load) { - const key = sharedConfig.getContextId(); - let ref = sharedConfig.load(key); - if (ref) { - if (typeof ref !== "object" || ref.status !== "success") p = ref;else sharedConfig.gather(key); - } - if (p && p !== "$$f") { - const [s, set] = createSignal(undefined, { - equals: false - }); - flicker = s; - p.then(() => { - if (sharedConfig.done) return set(); - sharedConfig.gather(key); - setHydrateContext(ctx); - set(); - setHydrateContext(); - }, err => { - error = err; - set(); - }); - } - } - const listContext = useContext(SuspenseListContext); - if (listContext) show = listContext.register(store.inFallback); - let dispose; - onCleanup(() => dispose && dispose()); - return createComponent(SuspenseContext.Provider, { - value: store, - get children() { - return createMemo(() => { - if (error) throw error; - ctx = sharedConfig.context; - if (flicker) { - flicker(); - return flicker = undefined; - } - if (ctx && p === "$$f") setHydrateContext(); - const rendered = createMemo(() => props.children); - return createMemo(prev => { - const inFallback = store.inFallback(), - { - showContent = true, - showFallback = true - } = show ? show() : {}; - if ((!inFallback || p && p !== "$$f") && showContent) { - store.resolved = true; - dispose && dispose(); - dispose = ctx = p = undefined; - resumeEffects(store.effects); - return rendered(); - } - if (!showFallback) return; - if (dispose) return prev; - return createRoot(disposer => { - dispose = disposer; - if (ctx) { - setHydrateContext({ - id: ctx.id + "F", - count: 0 - }); - ctx = undefined; - } - return props.fallback; - }, owner); - }); - }); - } - }); -} - -const DEV = { - hooks: DevHooks, - writeSignal, - registerGraph -} ; -if (globalThis) { - if (!globalThis.Solid$$) globalThis.Solid$$ = true;else console.warn("You appear to have multiple instances of Solid. This can lead to unexpected behavior."); -} - - - - -/***/ }), - -/***/ "./node_modules/solid-js/web/dist/dev.js": -/*!***********************************************!*\ - !*** ./node_modules/solid-js/web/dist/dev.js ***! - \***********************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Aliases: () => (/* binding */ Aliases), -/* harmony export */ Assets: () => (/* binding */ voidFn), -/* harmony export */ ChildProperties: () => (/* binding */ ChildProperties), -/* harmony export */ DOMElements: () => (/* binding */ DOMElements), -/* harmony export */ DelegatedEvents: () => (/* binding */ DelegatedEvents), -/* harmony export */ Dynamic: () => (/* binding */ Dynamic), -/* harmony export */ ErrorBoundary: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.ErrorBoundary), -/* harmony export */ For: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.For), -/* harmony export */ Hydration: () => (/* binding */ Hydration), -/* harmony export */ HydrationScript: () => (/* binding */ voidFn), -/* harmony export */ Index: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Index), -/* harmony export */ Match: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Match), -/* harmony export */ NoHydration: () => (/* binding */ NoHydration), -/* harmony export */ Portal: () => (/* binding */ Portal), -/* harmony export */ Properties: () => (/* binding */ Properties), -/* harmony export */ RequestContext: () => (/* binding */ RequestContext), -/* harmony export */ SVGElements: () => (/* binding */ SVGElements), -/* harmony export */ SVGNamespace: () => (/* binding */ SVGNamespace), -/* harmony export */ Show: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Show), -/* harmony export */ Suspense: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Suspense), -/* harmony export */ SuspenseList: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.SuspenseList), -/* harmony export */ Switch: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.Switch), -/* harmony export */ addEventListener: () => (/* binding */ addEventListener), -/* harmony export */ assign: () => (/* binding */ assign), -/* harmony export */ classList: () => (/* binding */ classList), -/* harmony export */ className: () => (/* binding */ className), -/* harmony export */ clearDelegatedEvents: () => (/* binding */ clearDelegatedEvents), -/* harmony export */ createComponent: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.createComponent), -/* harmony export */ delegateEvents: () => (/* binding */ delegateEvents), -/* harmony export */ dynamicProperty: () => (/* binding */ dynamicProperty), -/* harmony export */ effect: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect), -/* harmony export */ escape: () => (/* binding */ escape), -/* harmony export */ generateHydrationScript: () => (/* binding */ voidFn), -/* harmony export */ getAssets: () => (/* binding */ voidFn), -/* harmony export */ getHydrationKey: () => (/* binding */ getHydrationKey), -/* harmony export */ getNextElement: () => (/* binding */ getNextElement), -/* harmony export */ getNextMarker: () => (/* binding */ getNextMarker), -/* harmony export */ getNextMatch: () => (/* binding */ getNextMatch), -/* harmony export */ getOwner: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.getOwner), -/* harmony export */ getPropAlias: () => (/* binding */ getPropAlias), -/* harmony export */ getRequestEvent: () => (/* binding */ voidFn), -/* harmony export */ hydrate: () => (/* binding */ hydrate), -/* harmony export */ innerHTML: () => (/* binding */ innerHTML), -/* harmony export */ insert: () => (/* binding */ insert), -/* harmony export */ isDev: () => (/* binding */ isDev), -/* harmony export */ isServer: () => (/* binding */ isServer), -/* harmony export */ memo: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo), -/* harmony export */ mergeProps: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.mergeProps), -/* harmony export */ render: () => (/* binding */ render), -/* harmony export */ renderToStream: () => (/* binding */ renderToStream), -/* harmony export */ renderToString: () => (/* binding */ renderToString), -/* harmony export */ renderToStringAsync: () => (/* binding */ renderToStringAsync), -/* harmony export */ resolveSSRNode: () => (/* binding */ resolveSSRNode), -/* harmony export */ runHydrationEvents: () => (/* binding */ runHydrationEvents), -/* harmony export */ setAttribute: () => (/* binding */ setAttribute), -/* harmony export */ setAttributeNS: () => (/* binding */ setAttributeNS), -/* harmony export */ setProperty: () => (/* binding */ setProperty), -/* harmony export */ spread: () => (/* binding */ spread), -/* harmony export */ ssr: () => (/* binding */ ssr), -/* harmony export */ ssrAttribute: () => (/* binding */ ssrAttribute), -/* harmony export */ ssrClassList: () => (/* binding */ ssrClassList), -/* harmony export */ ssrElement: () => (/* binding */ ssrElement), -/* harmony export */ ssrHydrationKey: () => (/* binding */ ssrHydrationKey), -/* harmony export */ ssrSpread: () => (/* binding */ ssrSpread), -/* harmony export */ ssrStyle: () => (/* binding */ ssrStyle), -/* harmony export */ style: () => (/* binding */ style), -/* harmony export */ template: () => (/* binding */ template), -/* harmony export */ untrack: () => (/* reexport safe */ solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack), -/* harmony export */ use: () => (/* binding */ use), -/* harmony export */ useAssets: () => (/* binding */ voidFn) -/* harmony export */ }); -/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); - - - -const booleans = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "disabled", "formnovalidate", "hidden", "indeterminate", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "seamless", "selected"]; -const Properties = /*#__PURE__*/new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]); -const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]); -const Aliases = /*#__PURE__*/Object.assign(Object.create(null), { - className: "class", - htmlFor: "for" -}); -const PropAliases = /*#__PURE__*/Object.assign(Object.create(null), { - class: "className", - formnovalidate: { - $: "formNoValidate", - BUTTON: 1, - INPUT: 1 - }, - ismap: { - $: "isMap", - IMG: 1 - }, - nomodule: { - $: "noModule", - SCRIPT: 1 - }, - playsinline: { - $: "playsInline", - VIDEO: 1 - }, - readonly: { - $: "readOnly", - INPUT: 1, - TEXTAREA: 1 - } -}); -function getPropAlias(prop, tagName) { - const a = PropAliases[prop]; - return typeof a === "object" ? a[tagName] ? a["$"] : undefined : a; -} -const DelegatedEvents = /*#__PURE__*/new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]); -const SVGElements = /*#__PURE__*/new Set([ -"altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "font", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignObject", "g", "glyph", "glyphRef", "hkern", "image", "line", "linearGradient", "marker", "mask", "metadata", "missing-glyph", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", -"set", "stop", -"svg", "switch", "symbol", "text", "textPath", -"tref", "tspan", "use", "view", "vkern"]); -const SVGNamespace = { - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace" -}; -const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input", "h1", "h2", "h3", "h4", "h5", "h6"]); - -function reconcileArrays(parentNode, a, b) { - let bLength = b.length, - aEnd = a.length, - bEnd = bLength, - aStart = 0, - bStart = 0, - after = a[aEnd - 1].nextSibling, - map = null; - while (aStart < aEnd || bStart < bEnd) { - if (a[aStart] === b[bStart]) { - aStart++; - bStart++; - continue; - } - while (a[aEnd - 1] === b[bEnd - 1]) { - aEnd--; - bEnd--; - } - if (aEnd === aStart) { - const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after; - while (bStart < bEnd) parentNode.insertBefore(b[bStart++], node); - } else if (bEnd === bStart) { - while (aStart < aEnd) { - if (!map || !map.has(a[aStart])) a[aStart].remove(); - aStart++; - } - } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) { - const node = a[--aEnd].nextSibling; - parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling); - parentNode.insertBefore(b[--bEnd], node); - a[aEnd] = b[bEnd]; - } else { - if (!map) { - map = new Map(); - let i = bStart; - while (i < bEnd) map.set(b[i], i++); - } - const index = map.get(a[aStart]); - if (index != null) { - if (bStart < index && index < bEnd) { - let i = aStart, - sequence = 1, - t; - while (++i < aEnd && i < bEnd) { - if ((t = map.get(a[i])) == null || t !== index + sequence) break; - sequence++; - } - if (sequence > index - bStart) { - const node = a[aStart]; - while (bStart < index) parentNode.insertBefore(b[bStart++], node); - } else parentNode.replaceChild(b[bStart++], a[aStart++]); - } else aStart++; - } else a[aStart++].remove(); - } - } -} - -const $$EVENTS = "_$DX_DELEGATE"; -function render(code, element, init, options = {}) { - if (!element) { - throw new Error("The `element` passed to `render(..., element)` doesn't exist. Make sure `element` exists in the document."); - } - let disposer; - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRoot)(dispose => { - disposer = dispose; - element === document ? code() : insert(element, code(), element.firstChild ? null : undefined, init); - }, options.owner); - return () => { - disposer(); - element.textContent = ""; - }; -} -function template(html, isCE, isSVG) { - let node; - const create = () => { - if (isHydrating()) throw new Error("Failed attempt to create new DOM elements during hydration. Check that the libraries you are using support hydration."); - const t = document.createElement("template"); - t.innerHTML = html; - return isSVG ? t.content.firstChild.firstChild : t.content.firstChild; - }; - const fn = isCE ? () => (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack)(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true); - fn.cloneNode = fn; - return fn; -} -function delegateEvents(eventNames, document = window.document) { - const e = document[$$EVENTS] || (document[$$EVENTS] = new Set()); - for (let i = 0, l = eventNames.length; i < l; i++) { - const name = eventNames[i]; - if (!e.has(name)) { - e.add(name); - document.addEventListener(name, eventHandler); - } - } -} -function clearDelegatedEvents(document = window.document) { - if (document[$$EVENTS]) { - for (let name of document[$$EVENTS].keys()) document.removeEventListener(name, eventHandler); - delete document[$$EVENTS]; - } -} -function setProperty(node, name, value) { - if (isHydrating(node)) return; - node[name] = value; -} -function setAttribute(node, name, value) { - if (isHydrating(node)) return; - if (value == null) node.removeAttribute(name);else node.setAttribute(name, value); -} -function setAttributeNS(node, namespace, name, value) { - if (isHydrating(node)) return; - if (value == null) node.removeAttributeNS(namespace, name);else node.setAttributeNS(namespace, name, value); -} -function className(node, value) { - if (isHydrating(node)) return; - if (value == null) node.removeAttribute("class");else node.className = value; -} -function addEventListener(node, name, handler, delegate) { - if (delegate) { - if (Array.isArray(handler)) { - node[`$$${name}`] = handler[0]; - node[`$$${name}Data`] = handler[1]; - } else node[`$$${name}`] = handler; - } else if (Array.isArray(handler)) { - const handlerFn = handler[0]; - node.addEventListener(name, handler[0] = e => handlerFn.call(node, handler[1], e)); - } else node.addEventListener(name, handler); -} -function classList(node, value, prev = {}) { - const classKeys = Object.keys(value || {}), - prevKeys = Object.keys(prev); - let i, len; - for (i = 0, len = prevKeys.length; i < len; i++) { - const key = prevKeys[i]; - if (!key || key === "undefined" || value[key]) continue; - toggleClassKey(node, key, false); - delete prev[key]; - } - for (i = 0, len = classKeys.length; i < len; i++) { - const key = classKeys[i], - classValue = !!value[key]; - if (!key || key === "undefined" || prev[key] === classValue || !classValue) continue; - toggleClassKey(node, key, true); - prev[key] = classValue; - } - return prev; -} -function style(node, value, prev) { - if (!value) return prev ? setAttribute(node, "style") : value; - const nodeStyle = node.style; - if (typeof value === "string") return nodeStyle.cssText = value; - typeof prev === "string" && (nodeStyle.cssText = prev = undefined); - prev || (prev = {}); - value || (value = {}); - let v, s; - for (s in prev) { - value[s] == null && nodeStyle.removeProperty(s); - delete prev[s]; - } - for (s in value) { - v = value[s]; - if (v !== prev[s]) { - nodeStyle.setProperty(s, v); - prev[s] = v; - } - } - return prev; -} -function spread(node, props = {}, isSVG, skipChildren) { - const prevProps = {}; - if (!skipChildren) { - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => prevProps.children = insertExpression(node, props.children, prevProps.children)); - } - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => typeof props.ref === "function" && use(props.ref, node)); - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => assign(node, props, isSVG, true, prevProps, true)); - return prevProps; -} -function dynamicProperty(props, key) { - const src = props[key]; - Object.defineProperty(props, key, { - get() { - return src(); - }, - enumerable: true - }); - return props; -} -function use(fn, element, arg) { - return (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack)(() => fn(element, arg)); -} -function insert(parent, accessor, marker, initial) { - if (marker !== undefined && !initial) initial = []; - if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker); - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(current => insertExpression(parent, accessor(), current, marker), initial); -} -function assign(node, props, isSVG, skipChildren, prevProps = {}, skipRef = false) { - props || (props = {}); - for (const prop in prevProps) { - if (!(prop in props)) { - if (prop === "children") continue; - prevProps[prop] = assignProp(node, prop, null, prevProps[prop], isSVG, skipRef); - } - } - for (const prop in props) { - if (prop === "children") { - if (!skipChildren) insertExpression(node, props.children); - continue; - } - const value = props[prop]; - prevProps[prop] = assignProp(node, prop, value, prevProps[prop], isSVG, skipRef); - } -} -function hydrate$1(code, element, options = {}) { - if (globalThis._$HY.done) return render(code, element, [...element.childNodes], options); - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed = globalThis._$HY.completed; - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events = globalThis._$HY.events; - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.load = id => globalThis._$HY.r[id]; - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.has = id => id in globalThis._$HY.r; - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.gather = root => gatherHydratable(element, root); - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry = new Map(); - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context = { - id: options.renderId || "", - count: 0 - }; - try { - gatherHydratable(element, options.renderId); - return render(code, element, [...element.childNodes], options); - } finally { - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context = null; - } -} -function getNextElement(template) { - let node, - key, - hydrating = isHydrating(); - if (!hydrating || !(node = solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.get(key = getHydrationKey()))) { - if (hydrating) throw new Error(`Hydration Mismatch. Unable to find DOM nodes for hydration key: ${key}`); - return template(); - } - if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed) solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed.add(node); - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.delete(key); - return node; -} -function getNextMatch(el, nodeName) { - while (el && el.localName !== nodeName) el = el.nextSibling; - return el; -} -function getNextMarker(start) { - let end = start, - count = 0, - current = []; - if (isHydrating(start)) { - while (end) { - if (end.nodeType === 8) { - const v = end.nodeValue; - if (v === "$") count++;else if (v === "/") { - if (count === 0) return [end, current]; - count--; - } - } - current.push(end); - end = end.nextSibling; - } - } - return [end, current]; -} -function runHydrationEvents() { - if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events.queued) { - queueMicrotask(() => { - const { - completed, - events - } = solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig; - events.queued = false; - while (events.length) { - const [el, e] = events[0]; - if (!completed.has(el)) return; - events.shift(); - eventHandler(e); - } - if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done) { - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events = _$HY.events = null; - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.completed = _$HY.completed = null; - } - }); - solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events.queued = true; - } -} -function isHydrating(node) { - return !!solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done && (!node || node.isConnected); -} -function toPropertyName(name) { - return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase()); -} -function toggleClassKey(node, key, value) { - const classNames = key.trim().split(/\s+/); - for (let i = 0, nameLen = classNames.length; i < nameLen; i++) node.classList.toggle(classNames[i], value); -} -function assignProp(node, prop, value, prev, isSVG, skipRef) { - let isCE, isProp, isChildProp, propAlias, forceProp; - if (prop === "style") return style(node, value, prev); - if (prop === "classList") return classList(node, value, prev); - if (value === prev) return prev; - if (prop === "ref") { - if (!skipRef) value(node); - } else if (prop.slice(0, 3) === "on:") { - const e = prop.slice(3); - prev && node.removeEventListener(e, prev); - value && node.addEventListener(e, value); - } else if (prop.slice(0, 10) === "oncapture:") { - const e = prop.slice(10); - prev && node.removeEventListener(e, prev, true); - value && node.addEventListener(e, value, true); - } else if (prop.slice(0, 2) === "on") { - const name = prop.slice(2).toLowerCase(); - const delegate = DelegatedEvents.has(name); - if (!delegate && prev) { - const h = Array.isArray(prev) ? prev[0] : prev; - node.removeEventListener(name, h); - } - if (delegate || value) { - addEventListener(node, name, value, delegate); - delegate && delegateEvents([name]); - } - } else if (prop.slice(0, 5) === "attr:") { - setAttribute(node, prop.slice(5), value); - } else if ((forceProp = prop.slice(0, 5) === "prop:") || (isChildProp = ChildProperties.has(prop)) || !isSVG && ((propAlias = getPropAlias(prop, node.tagName)) || (isProp = Properties.has(prop))) || (isCE = node.nodeName.includes("-"))) { - if (forceProp) { - prop = prop.slice(5); - isProp = true; - } else if (isHydrating(node)) return value; - if (prop === "class" || prop === "className") className(node, value);else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value;else node[propAlias || prop] = value; - } else { - const ns = isSVG && prop.indexOf(":") > -1 && SVGNamespace[prop.split(":")[0]]; - if (ns) setAttributeNS(node, ns, prop, value);else setAttribute(node, Aliases[prop] || prop, value); - } - return value; -} -function eventHandler(e) { - if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry && solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events) { - if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.events.find(([el, ev]) => ev === e)) return; - } - const key = `$$${e.type}`; - let node = e.composedPath && e.composedPath()[0] || e.target; - if (e.target !== node) { - Object.defineProperty(e, "target", { - configurable: true, - value: node - }); - } - Object.defineProperty(e, "currentTarget", { - configurable: true, - get() { - return node || document; - } - }); - if (solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done) solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.done = _$HY.done = true; - while (node) { - const handler = node[key]; - if (handler && !node.disabled) { - const data = node[`${key}Data`]; - data !== undefined ? handler.call(node, data, e) : handler.call(node, e); - if (e.cancelBubble) return; - } - node = node._$host || node.parentNode || node.host; - } -} -function insertExpression(parent, value, current, marker, unwrapArray) { - const hydrating = isHydrating(parent); - if (hydrating) { - !current && (current = [...parent.childNodes]); - let cleaned = []; - for (let i = 0; i < current.length; i++) { - const node = current[i]; - if (node.nodeType === 8 && node.data.slice(0, 2) === "!$") node.remove();else cleaned.push(node); - } - current = cleaned; - } - while (typeof current === "function") current = current(); - if (value === current) return current; - const t = typeof value, - multi = marker !== undefined; - parent = multi && current[0] && current[0].parentNode || parent; - if (t === "string" || t === "number") { - if (hydrating) return current; - if (t === "number") { - value = value.toString(); - if (value === current) return current; - } - if (multi) { - let node = current[0]; - if (node && node.nodeType === 3) { - node.data !== value && (node.data = value); - } else node = document.createTextNode(value); - current = cleanChildren(parent, current, marker, node); - } else { - if (current !== "" && typeof current === "string") { - current = parent.firstChild.data = value; - } else current = parent.textContent = value; - } - } else if (value == null || t === "boolean") { - if (hydrating) return current; - current = cleanChildren(parent, current, marker); - } else if (t === "function") { - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => { - let v = value(); - while (typeof v === "function") v = v(); - current = insertExpression(parent, v, current, marker); - }); - return () => current; - } else if (Array.isArray(value)) { - const array = []; - const currentArray = current && Array.isArray(current); - if (normalizeIncomingArray(array, value, current, unwrapArray)) { - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRenderEffect)(() => current = insertExpression(parent, array, current, marker, true)); - return () => current; - } - if (hydrating) { - if (!array.length) return current; - if (marker === undefined) return current = [...parent.childNodes]; - let node = array[0]; - if (node.parentNode !== parent) return current; - const nodes = [node]; - while ((node = node.nextSibling) !== marker) nodes.push(node); - return current = nodes; - } - if (array.length === 0) { - current = cleanChildren(parent, current, marker); - if (multi) return current; - } else if (currentArray) { - if (current.length === 0) { - appendNodes(parent, array, marker); - } else reconcileArrays(parent, current, array); - } else { - current && cleanChildren(parent); - appendNodes(parent, array); - } - current = array; - } else if (value.nodeType) { - if (hydrating && value.parentNode) return current = multi ? [value] : value; - if (Array.isArray(current)) { - if (multi) return current = cleanChildren(parent, current, marker, value); - cleanChildren(parent, current, null, value); - } else if (current == null || current === "" || !parent.firstChild) { - parent.appendChild(value); - } else parent.replaceChild(value, parent.firstChild); - current = value; - } else console.warn(`Unrecognized value. Skipped inserting`, value); - return current; -} -function normalizeIncomingArray(normalized, array, current, unwrap) { - let dynamic = false; - for (let i = 0, len = array.length; i < len; i++) { - let item = array[i], - prev = current && current[normalized.length], - t; - if (item == null || item === true || item === false) ; else if ((t = typeof item) === "object" && item.nodeType) { - normalized.push(item); - } else if (Array.isArray(item)) { - dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic; - } else if (t === "function") { - if (unwrap) { - while (typeof item === "function") item = item(); - dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic; - } else { - normalized.push(item); - dynamic = true; - } - } else { - const value = String(item); - if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev);else normalized.push(document.createTextNode(value)); - } - } - return dynamic; -} -function appendNodes(parent, array, marker = null) { - for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker); -} -function cleanChildren(parent, current, marker, replacement) { - if (marker === undefined) return parent.textContent = ""; - const node = replacement || document.createTextNode(""); - if (current.length) { - let inserted = false; - for (let i = current.length - 1; i >= 0; i--) { - const el = current[i]; - if (node !== el) { - const isParent = el.parentNode === parent; - if (!inserted && !i) isParent ? parent.replaceChild(node, el) : parent.insertBefore(node, marker);else isParent && el.remove(); - } else inserted = true; - } - } else parent.insertBefore(node, marker); - return [node]; -} -function gatherHydratable(element, root) { - const templates = element.querySelectorAll(`*[data-hk]`); - for (let i = 0; i < templates.length; i++) { - const node = templates[i]; - const key = node.getAttribute("data-hk"); - if ((!root || key.startsWith(root)) && !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.has(key)) solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.registry.set(key, node); - } -} -function getHydrationKey() { - return solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.getNextContextId(); -} -function NoHydration(props) { - return solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context ? undefined : props.children; -} -function Hydration(props) { - return props.children; -} -const voidFn = () => undefined; -const RequestContext = Symbol(); -function innerHTML(parent, content) { - !solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context && (parent.innerHTML = content); -} - -function throwInBrowser(func) { - const err = new Error(`${func.name} is not supported in the browser, returning undefined`); - console.error(err); -} -function renderToString(fn, options) { - throwInBrowser(renderToString); -} -function renderToStringAsync(fn, options) { - throwInBrowser(renderToStringAsync); -} -function renderToStream(fn, options) { - throwInBrowser(renderToStream); -} -function ssr(template, ...nodes) {} -function ssrElement(name, props, children, needsId) {} -function ssrClassList(value) {} -function ssrStyle(value) {} -function ssrAttribute(key, value) {} -function ssrHydrationKey() {} -function resolveSSRNode(node) {} -function escape(html) {} -function ssrSpread(props, isSVG, skipChildren) {} - -const isServer = false; -const isDev = true; -const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; -function createElement(tagName, isSVG = false) { - return isSVG ? document.createElementNS(SVG_NAMESPACE, tagName) : document.createElement(tagName); -} -const hydrate = (...args) => { - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.enableHydration)(); - return hydrate$1(...args); -}; -function Portal(props) { - const { - useShadow - } = props, - marker = document.createTextNode(""), - mount = () => props.mount || document.body, - owner = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.getOwner)(); - let content; - let hydrating = !!solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context; - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createEffect)(() => { - if (hydrating) (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.getOwner)().user = hydrating = false; - content || (content = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.runWithOwner)(owner, () => (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo)(() => props.children))); - const el = mount(); - if (el instanceof HTMLHeadElement) { - const [clean, setClean] = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createSignal)(false); - const cleanup = () => setClean(true); - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createRoot)(dispose => insert(el, () => !clean() ? content() : dispose(), null)); - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.onCleanup)(cleanup); - } else { - const container = createElement(props.isSVG ? "g" : "div", props.isSVG), - renderRoot = useShadow && container.attachShadow ? container.attachShadow({ - mode: "open" - }) : container; - Object.defineProperty(container, "_$host", { - get() { - return marker.parentNode; - }, - configurable: true - }); - insert(renderRoot, content); - el.appendChild(container); - props.ref && props.ref(container); - (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.onCleanup)(() => el.removeChild(container)); - } - }, undefined, { - render: !hydrating - }); - return marker; -} -function Dynamic(props) { - const [p, others] = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.splitProps)(props, ["component"]); - const cached = (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo)(() => p.component); - return (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.createMemo)(() => { - const component = cached(); - switch (typeof component) { - case "function": - Object.assign(component, { - [solid_js__WEBPACK_IMPORTED_MODULE_0__.$DEVCOMP]: true - }); - return (0,solid_js__WEBPACK_IMPORTED_MODULE_0__.untrack)(() => component(others)); - case "string": - const isSvg = SVGElements.has(component); - const el = solid_js__WEBPACK_IMPORTED_MODULE_0__.sharedConfig.context ? getNextElement() : createElement(component, isSvg); - spread(el, others, isSvg); - return el; - } - }); -} - - - - -/***/ }), - -/***/ "./node_modules/solid-styled-components/src/index.js": -/*!***********************************************************!*\ - !*** ./node_modules/solid-styled-components/src/index.js ***! - \***********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ThemeProvider: () => (/* binding */ ThemeProvider), -/* harmony export */ createGlobalStyles: () => (/* binding */ createGlobalStyles), -/* harmony export */ css: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.css), -/* harmony export */ extractCss: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.extractCss), -/* harmony export */ glob: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.glob), -/* harmony export */ keyframes: () => (/* reexport safe */ goober__WEBPACK_IMPORTED_MODULE_0__.keyframes), -/* harmony export */ setup: () => (/* binding */ setup), -/* harmony export */ shouldForwardProp: () => (/* binding */ shouldForwardProp), -/* harmony export */ styled: () => (/* binding */ styled), -/* harmony export */ useTheme: () => (/* binding */ useTheme) -/* harmony export */ }); -/* harmony import */ var goober__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! goober */ "./node_modules/goober/dist/goober.modern.js"); -/* harmony import */ var solid_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! solid-js */ "./node_modules/solid-js/dist/dev.js"); -/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/web/dist/dev.js"); - - - - - -let getForwardProps = null; - -function shouldForwardProp(predicate) { - return props => props.filter(predicate); -} - -function setup(prefixer, shouldForwardProp = null) { - (0,goober__WEBPACK_IMPORTED_MODULE_0__.setup)(null, prefixer); - getForwardProps = shouldForwardProp; -} -const ThemeContext = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.createContext)(); -function ThemeProvider(props) { - return (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.createComponent)(ThemeContext.Provider, { - value: props.theme, - get children() { - return props.children; - } - }); -} -function useTheme() { - return (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.useContext)(ThemeContext); -} - -function makeStyled(tag) { - let _ctx = this || {}; - return (...args) => { - const Styled = props => { - const theme = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.useContext)(ThemeContext); - const withTheme = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.mergeProps)(props, { theme }); - const clone = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.mergeProps)(withTheme, { - get class() { - const pClass = withTheme.class, - append = "class" in withTheme && /^go[0-9]+/.test(pClass); - // Call `css` with the append flag and pass the props - let className = goober__WEBPACK_IMPORTED_MODULE_0__.css.apply( - { target: _ctx.target, o: append, p: withTheme, g: _ctx.g }, - args - ); - return [pClass, className].filter(Boolean).join(" "); - } - }); - const [local, newProps] = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.splitProps)(clone, ["as", "theme"]); - const htmlProps = getForwardProps - ? (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.splitProps)(newProps, getForwardProps(Object.keys(newProps)))[0] - : newProps; - const createTag = local.as || tag; - let el; - - if (typeof createTag === "function") { - el = createTag(htmlProps); - } else { - if (solid_js_web__WEBPACK_IMPORTED_MODULE_2__.isServer) { - const [local, others] = (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.splitProps)(htmlProps, ["children", "theme"]); - el = (0,solid_js_web__WEBPACK_IMPORTED_MODULE_2__.Dynamic)({ - component: createTag, - get children() { - return local.children; - }, - ...others - }); - } else { - if (_ctx.g == 1) { - // When using Global Styles we don't want to hydrate the unused nodes - el = document.createElement(createTag); - (0,solid_js_web__WEBPACK_IMPORTED_MODULE_2__.spread)(el, htmlProps); - } else { - el = (0,solid_js_web__WEBPACK_IMPORTED_MODULE_2__.Dynamic)((0,solid_js__WEBPACK_IMPORTED_MODULE_1__.mergeProps)({ component: createTag }, htmlProps)); - } - } - } - return el; - }; - Styled.class = props => { - return (0,solid_js__WEBPACK_IMPORTED_MODULE_1__.untrack)(() => { - return goober__WEBPACK_IMPORTED_MODULE_0__.css.apply({ target: _ctx.target, p: props, g: _ctx.g }, args); - }); - }; - - return Styled; - }; -} - -const styled = new Proxy(makeStyled, { - get(target, tag) { - return target(tag); - } -}); - -function createGlobalStyles() { - const fn = makeStyled.call({ g: 1 }, "div").apply(null, arguments); - - return function GlobalStyles(props) { - fn(props); - return null; - }; -} - - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/compat get default export */ -/******/ (() => { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = (module) => { -/******/ var getter = module && module.__esModule ? -/******/ () => (module['default']) : -/******/ () => (module); -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be in strict mode. -(() => { -"use strict"; -/*!**********************!*\ - !*** ./src/main.tsx ***! - \**********************/ -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/web/dist/dev.js"); -/* harmony import */ var solid_js_web__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! solid-js/web */ "./node_modules/solid-js/dist/dev.js"); -/* harmony import */ var solid_styled_components__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! solid-styled-components */ "./node_modules/solid-styled-components/src/index.js"); -/* harmony import */ var _state_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./state.ts */ "./src/state.ts"); -/* harmony import */ var _timeline__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./timeline */ "./src/timeline/index.ts"); - - - - -var _tmpl$ = /*#__PURE__*/(0,solid_js_web__WEBPACK_IMPORTED_MODULE_0__.template)(`
Hello, world!
\r\n
\r\n \r\n \r\n}\r\n\r\n\r\nconst AppRoot = styled.div`\r\n display: grid;\r\n grid-template: auto 1fr / 1fr;\r\n margin: auto;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n`\r\n\r\n\r\nSolidWeb.render(\r\n App,\r\n document.getElementById(\"app\")!)"],"names":["makeNew","timeline","bkgColor","bkgAlternateMeasureColor","bkgInactiveOverlayColor","trackVBorderColor","trackHBorderColor","selectionCursorColor","selectionBkgColor","playbackCursorColor","trackSeparatorColor","measureColor","submeasureColor","halfSubmeasureColor","measureLabelColor","octaveLabelColor","meterChangeColor","keyChangeColor","noteVelocityMarkerColor","noteVelocityMarkerInactiveColor","keyPan","keyPencil","keySelectMultiple","keySelectRange","keySelectRect","keySelectClone","keyDisplaceCursor2","keyDisplaceFast","keyDisplaceChromatically","keyDisplaceStretch","mouseDoubleClickThresholdMs","mouseDragXLockedDistance","mouseDragYLockedDistance","mouseEdgeScrollThreshold","mouseEdgeScrollSpeed","Range","MinVolumeDb","MaxVolumeDb","DefaultVolumeDb","DefaultChordVolumeDb","elemModify","original","changes","makeTrackNotes","type","trackType","id","parentId","range","dummy","name","mute","solo","makeTrackChords","trackDisplayName","track","makeTrackKeyChanges","makeTrackMeterChanges","makeMeterChange","time","meter","fromPoint","makeKeyChange","key","makeNote","midiPitch","makeChord","chord","Project","BinarySearch","measureCacheKey","measureCache","firstMeterCh","lastMeterCh","ensureMeasureCacheRefreshed","project","meterChangeTrackId","meterChangeList","lists","get","num","elem1","elem2","iterAllPairwise","meterCh1","meterCh2","numLocal","measureN","measureD","time1","time2","iterMeasuresPairwise","start","compare","push","min","meterCh","iterMeasuresAtRange","measureStart","findPreviousOrEqual","m","subtract","fullCycleDuration","add","lastMeasureNum","measureIndex","length","measure","end","Immutable","Theory","Rational","ListOfRanges","MAX_RATIONAL_DENOMINATOR","makeEmpty","nextId","baseBpm","tracks","Map","elems","keyChangeTrackId","chordTrackId","noteTrackId","track1Id","upsertTrack","track2Id","upsertElement","Key","parse","Meter","track3Id","track4Id","makeTest","i","fromStartDuration","Utils","midiMiddleC","remove","insertBefore","trackIndex","findIndex","t","slice","delete","set","elem","prevElem","changeParent","list","upsert","prevList","removeById","nextList","keyAt","trackId","keyChangeTrackTimedElems","defaultKey","keyCh","findActiveAt","firstKeyCh","findFirst","meterChangeAt","meterChangeTrackTimedElems","meterAt","defaultMeter","withRefreshedRange","merge","getTotalRange","getElem","getTrack","cloneElem","fromProject","toProject","newElem","newId","innerList","innerElem","iterAll","newInnerElem","splitElem","splitRange","origProject","absRange","getAbsoluteRange","overlapsRange","removeElem","splitInnerElem","newParentId","relativeDisplace","keepRange","iterSlices","newElemPart","getRelativeRange","newElemPartId","innerRelativeDisplace","parentTrackFor","elemId","getAbsoluteTime","getRelativeTime","displace","getRangeForElems","elemIds","getMillisecondsAt","measuresPerSecond","asFloat","Solid","Timeline","Prefs","state","setState","createSignal","test","prefs","root","refresh","MathUtils","chordKinds","pitches","symbol","startGroup","Chord","kinds","constructor","rootChroma","kind","inversion","modifiers","withChanges","obj","Object","assign","kindFromId","k","kindFromPitches","every","p","suggestChordsForPitches","suggestions","rootPitch","matches","Set","misses","pitch","relPitch","mod","kindMatch","size","sort","a","b","kindId","romanBase","degree","degreeForMidi","chordKind","roman","Math","floor","accidental","baseStr","accidentalToStr","degreeToRomanStr","toLowerCase","romanSup","supStr","add9","add11","add13","no3","no5","romanSub","subStr","sus2","sus4","chordData","rootMidi","splice","strummingPitches","octave","map","x","y","sum","reduce","shift","unshift","default","Pitch","PitchName","Scale","tonic","scale","_chromaToDegree","chromas","chroma","midi","nextDegree","nextChroma","testNextChroma","fromTonicAndScale","str","trim","separator","indexOf","tonicStr","substr","scaleStr","toString","degreeForChroma","degreeForPitch","octavedDegreeForMidi","degreeOctave","octavedDegreeForPitch","midiForDegree","octavedDegree","pitchForDegree","fromMidi","chromaForDegree","nameForMidi","letter1","letter","accidental1","letterToChroma","letter2","accidental2","letter3","accidental3","attempts","abs","nameForPitch","nameForChroma","nameForDegree","namedPitches","numerator","denominator","nextTime","alternatingMeasureCount","src","split","parseInt","isFinite","fromOctaveAndChroma","fromOctaveAndName","pitchName","c","charCodeAt","undefined","isNaN","frequency","pow","chromaToLetter","chromaToAccidental","fromChroma","letterStr","strToLetter","altered","additionalAccidental","simplified","letterToStr","accidentalStr","strUnicode","knownScales","mode","names","metadata","find","s","index","fromChromas","fromId","knownScale","some","n","alterationsFromMajor","join","chromaToDegreeInCMajor","d","e","f","g","degreeToColor","degreeToColorFaded","useUnicode","repeat","Global","Rect","Element","props","div","canvas","createEffect","cleanup","registerHandlers","onCleanup","_el$","_tmpl$","_el$2","firstChild","_ref$","_$use","style","setProperty","_ref$2","canvasResize","pixelRatio","window","devicePixelRatio","domRect","getBoundingClientRect","w","width","h","height","rect","resize","ctx","getContext","transformMousePos","ev","clientX","left","clientY","top","setCursor","action","mouse","down","hover","cursor","MouseAction","DragTime","DragRow","DragTimeAndRow","StretchTimeStart","StretchTimeEnd","onResize","layout","draw","onMouseMove","preventDefault","mouseMove","mouseDrag","onMouseDown","mouseDown","button","onMouseUp","mouseUp","onMouseWheel","mouseWheel","deltaX","deltaY","onKeyDown","keyDown","onKeyUp","keyUp","addEventListener","removeEventListener","State","save","translate","fillStyle","fillRect","renderRect","drawElements","elements","visible","timeMin","timeMax","max","drawCursorBeam","restore","element","beginPath","clip","drawLaneBkgSolid","drawLaneBkgMeasures","drawCursorBkg","subElements","drawLaneFrgOutline","drawLaneBkgOctaves","roundRect","noteRowH","fill","selection","has","strokeStyle","lineWidth","stroke","drawLaneBkgCenterStroke","lane","yCenter","moveTo","lineTo","mainLinePass","measureHalfH","submeasureHalfH","measures","x1","xAtTime","x2","submeasureSize","submeasureX","round","rowAtTop","rowAtY","rowAtBottom","octaveAtTop","ceil","octaveAtBottom","font","textAlign","textBaseline","keyRegion","keyRegions","tonicRowOffset","keyCh1","needsOctaveLabels","drewOctaveLabels","yForRow","labelX","fillText","j","ySuboctave","tipOffsetSide","laneIndexMin","cursorGetLaneIndexMin","laneIndexMax","cursorGetLaneIndexMax","laneMin","lanes","laneMax","lineCap","headYSize","headXSize","y1","y2","laneIndex","keysDown","Layout","elementCount","parent","visibleTimeRange","iterKeyChangePairsAtRange","laneMarkerH","laneChordH","laneMarginH","laneKeyChanges","laneMeterChanges","laneChords","laneNotesY","laneNotes","layoutLaneNotes","console","log","pair","iterActiveAtRangePairwise","keyCh2","iterElementsAtRegion","verticalRegion","iterNotesAtRegion","note","keyChPair","iterNotesAndKeyChanges","row","rowForPitch","cutStart","cutEnd","rectForNote","rectStretchStart","withX1","rectStretchEnd","withX2","priority","iterNotes","iterAtRange","pitchForRow","yScroll","noteRange","noteRow","keyChXStart","keyChXEnd","clampY","noteOrigX1","noteOrigX2","noteY","noteX1","noteX2","noteW","rightButton","prevDownDate","downDate","Date","None","selectMultiple","selectRange","selectClone","selectRect","forcePan","doubleClick","getTime","drag","origin","point","timeScroll","xLocked","yLocked","posDelta","timeDelta","rowDelta","trackDelta","trackInsertionBefore","notePreviewLast","Pan","hoverIsSelected","selectionClear","SelectCursor","cursorSetTime","rectY1","rectY2","trackPos","laneIndex1","laneIndex2","selectionToggle","selectionRange","pointPrev","pointAt","pos","handlePanning","handleSelectCursor","handleDragElements","timeScale","selectionAddAtCursor","newProject","quantize","stretch","snap","timeSnap","sorted","newPitch","hoverRecursive","wheelDate","prevMouseTime","timeAtX","newTimeScale","newMouseTime","newTimeScroll","timeSnapAdjustThresholdUpper","timeSnapAdjustThresholdLower","newTimeSnap","timeSnapBase","divide","trackMeasuresH","trackControlX","trackControlY","trackControlSize","originTrackPos","insertion","nearMidiPitch","duration","needsKeyFinish","rangeSelectOriginTrackIndex","fromFloat","timeRangeAtX","laneIndexAtY","clear","alreadySelected","selectionAdd","l","cursorSetTrack","trackIndex1","trackIndex2","array","compareFn","lo","hi","mi","findExact","value","findPreviousNotEqual","findNextNotEqual","iterEqual","assert","Bucket","idMap","buckets","bucketFn","clone","cloned","_ensureBucketsAtRange","newBuckets","newBucket","_iterBucketIndicesAtRange","bucket","update","newList","newElemIndex","upsertMany","removeId","elemIndex","findById","elemStart","firstBucket","iterAtPoint","item","prevItem","findPrevious","nextItem","firstElem","lastElem","result","findPreviousAnchor","previous","endB","nearestItem","nearestPoint","itemRange","findPreviousDeletionAnchor","anchor","anchorRange","deepEqual","elem3","elem4","elem5","elem1_2","step","midiToHertz","dbToLinearGain","db","linearGainToDb","linearGain","log10","minMidiDbLevel","dbToMidiVolume","midiVolumeToDb","midiVol","midiVolumeToLinearGain","startInclusive","endInclusive","setDuration","newDuration","lessThan","greaterThan","other","r1","r2","intersect","atZero","offset","pivot","grow","shrink","isPoint","equalTo","overlapsPoint","compStart","compEnd","checkStart","checkEnd","containsRangeCompletely","maxDenom","toJson","fromJson","json","simplifyInPlace","floatValue","maxDenominator","integer","frac","fromIntegerPlusRational","numeratorWithoutInteger","negate","absolute","multiply","multiplyByFloat","simplify","dist","move","isZero","thisNumerator","otherNumerator","notEqualTo","lessThanOrEqual","greaterThanOrEqual","trySimplifyInPlaceBy","divider","fromVertices","fromElement","clientRect","xCenter","withX","withY","withW","withH","withY1","withY2","expand","amount","expandW","contains","overlaps","SolidWeb","styled","App","_$createComponent","AppRoot","children","_el$3","nextSibling","_el$4","_$insert","$$click","render","document","getElementById","_$delegateEvents"],"sourceRoot":""} \ No newline at end of file diff --git a/.gitignore b/.gitignore index d150aeb..dacbd13 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /node_modules/ -/build/ +/.build/ /library/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5f5f255..65a0e6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,23 +8,22 @@ "name": "theorytracker2", "version": "0.1.0", "dependencies": { - "@babel/preset-typescript": "^7.24.6", - "babel-loader": "^9.1.3", - "babel-preset-solid": "^1.8.17", - "immutable": "^4.3.7", - "solid-js": "^1.8.17", + "@babel/preset-typescript": "^7.28.5", + "babel-loader": "^10.0.0", + "babel-preset-solid": "^1.9.10", + "immutable": "^5.1.4", + "solid-js": "^1.9.10", "solid-styled-components": "^0.28.5", "ts-node": "^10.9.2", - "typescript": "^5.4.5", - "webpack": "^5.91.0", - "webpack-cli": "^5.1.4" + "typescript": "^5.9.3", + "webpack": "^5.103.0", + "webpack-cli": "^6.0.1" } }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -34,12 +33,14 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" @@ -49,7 +50,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -85,38 +85,38 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.27.3" }, "engines": { "node": ">=6.9.0" @@ -126,7 +126,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", - "peer": true, "dependencies": { "@babel/compat-data": "^7.22.5", "@babel/helper-validator-option": "^7.22.5", @@ -145,7 +144,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "peer": true, "dependencies": { "yallist": "^3.0.2" } @@ -153,20 +151,20 @@ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "peer": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", - "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.4", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "engines": { @@ -176,39 +174,50 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -218,32 +227,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", - "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -252,88 +264,66 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", - "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", - "peer": true, + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -343,11 +333,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -357,11 +348,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", - "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -371,13 +363,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", - "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -387,15 +379,16 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", - "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", + "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -405,15 +398,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -423,43 +417,45 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -486,18 +482,18 @@ } }, "node_modules/@discoveryjs/json-ext": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", - "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=14.17.0" } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "peer": true, "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -523,36 +519,36 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "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==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -578,186 +574,227 @@ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" }, "node_modules/@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", - "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", + "peer": true }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", + "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", + "license": "MIT", "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", + "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", + "license": "MIT", "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", + "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", + "license": "MIT", "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -768,17 +805,21 @@ "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -786,12 +827,16 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, "peerDependencies": { - "acorn": "^8" + "acorn": "^8.14.0" } }, "node_modules/acorn-walk": { @@ -806,14 +851,16 @@ } }, "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -824,6 +871,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -840,6 +888,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -847,48 +896,99 @@ "ajv": "^8.8.2" } }, - "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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", + "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", + "license": "MIT", "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" + "find-up": "^5.0.0" }, "engines": { - "node": ">= 14.15.0" + "node": "^18.20.0 || ^20.10.0 || >=22.0.0" }, "peerDependencies": { "@babel/core": "^7.12.0", - "webpack": ">=5" + "webpack": ">=5.61.0" + } + }, + "node_modules/babel-loader/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/babel-plugin-jsx-dom-expressions": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.38.5.tgz", - "integrity": "sha512-JfjHYKOKGwoiOYQ56Oo8gbZPb9wNMpPuEEUhSCjMpnuHM9K21HFIUBm83TZPB40Av4caCIW4Tfjzpkp/MtFpMw==", + "version": "0.40.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.40.3.tgz", + "integrity": "sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", - "validate-html-nesting": "^1.2.1" + "parse5": "^7.1.2" }, "peerDependencies": { "@babel/core": "^7.20.12" @@ -898,6 +998,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "license": "MIT", "dependencies": { "@babel/types": "^7.18.6" }, @@ -906,20 +1007,36 @@ } }, "node_modules/babel-preset-solid": { - "version": "1.8.22", - "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.8.22.tgz", - "integrity": "sha512-nKwisb//lZsiRF2NErlRP64zVTJqa1OSZiDnSl0YbcTiCZoMt52CY2Pg+9fsYAPtjYMT7RHBmzU41pxK6hFOcg==", + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.9.10.tgz", + "integrity": "sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ==", + "license": "MIT", "dependencies": { - "babel-plugin-jsx-dom-expressions": "^0.38.5" + "babel-plugin-jsx-dom-expressions": "^0.40.3" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0", + "solid-js": "^1.9.10" + }, + "peerDependenciesMeta": { + "solid-js": { + "optional": true + } + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" } }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "funding": [ { "type": "opencollective", @@ -934,11 +1051,14 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", + "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -950,12 +1070,13 @@ "node_modules/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==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001655", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", - "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "funding": [ { "type": "opencollective", @@ -969,20 +1090,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] - }, - "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==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } + ], + "license": "CC-BY-4.0" }, "node_modules/chrome-trace-event": { "version": "1.0.3", @@ -996,6 +1105,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -1005,19 +1115,6 @@ "node": ">=6" } }, - "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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "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==" - }, "node_modules/colorette": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", @@ -1026,18 +1123,13 @@ "node_modules/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==" - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" }, "node_modules/convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "peer": true, "dependencies": { "safe-buffer": "~5.1.1" } @@ -1048,9 +1140,10 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1063,7 +1156,8 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "peer": true }, "node_modules/debug": { "version": "4.3.1", @@ -1090,14 +1184,16 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", - "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "license": "ISC" }, "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -1106,10 +1202,23 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "license": "MIT", "bin": { "envinfo": "dist/cli.js" }, @@ -1126,18 +1235,11 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -1188,112 +1290,30 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, "node_modules/fastest-levenshtein": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/find-cache-dir/node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -1306,6 +1326,15 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1318,7 +1347,6 @@ "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==", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -1326,15 +1354,8 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" }, "node_modules/goober": { "version": "2.1.14", @@ -1347,7 +1368,8 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, "node_modules/has": { "version": "1.0.3", @@ -1361,22 +1383,25 @@ } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/html-entities": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", + "license": "MIT" }, "node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "license": "MIT" }, "node_modules/import-local": { "version": "3.0.2", @@ -1416,6 +1441,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -1431,7 +1457,8 @@ "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1440,6 +1467,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -1449,42 +1477,22 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-parse-even-better-errors": { @@ -1495,13 +1503,13 @@ "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -1513,16 +1521,22 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -1544,7 +1558,8 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" }, "node_modules/mime-db": { "version": "1.48.0", @@ -1576,9 +1591,10 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" }, "node_modules/p-limit": { "version": "2.3.0", @@ -1613,6 +1629,18 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -1635,9 +1663,10 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/pkg-dir": { "version": "4.2.0", @@ -1650,18 +1679,11 @@ "node": ">=8" } }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -1681,6 +1703,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1726,9 +1749,10 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/schema-utils": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz", - "integrity": "sha512-Jw+GZVbP5IggB2WAn6UHI02LBwGmsIeYN/lNbSMZyDziQ7jmtAUrqKqDja+W89YHVs+KL/3IkIMltAklqB1vAw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -1736,7 +1760,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -1755,22 +1779,26 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/seroval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.1.1.tgz", - "integrity": "sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz", + "integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==", + "license": "MIT", + "peer": true, "engines": { "node": ">=10" } }, "node_modules/seroval-plugins": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.1.1.tgz", - "integrity": "sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.3.3.tgz", + "integrity": "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -1782,6 +1810,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -1809,13 +1838,15 @@ } }, "node_modules/solid-js": { - "version": "1.8.22", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.22.tgz", - "integrity": "sha512-VBzN5j+9Y4rqIKEnK301aBk+S7fvFSTs9ljg+YEdFxjNjH0hkjXPiQRcws9tE5fUzMznSS6KToL5hwMfHDgpLA==", + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.10.tgz", + "integrity": "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==", + "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.1.0", - "seroval": "^1.1.0", - "seroval-plugins": "^1.1.0" + "seroval": "~1.3.0", + "seroval-plugins": "~1.3.0" } }, "node_modules/solid-styled-components": { @@ -1834,6 +1865,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -1842,20 +1874,25 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "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==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -1870,20 +1907,26 @@ } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "version": "5.44.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", + "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -1895,15 +1938,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -1927,59 +1971,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "engines": { - "node": ">=4" - } - }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -2023,9 +2014,11 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2035,9 +2028,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", "funding": [ { "type": "opencollective", @@ -2052,9 +2045,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -2063,28 +2057,16 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, - "node_modules/validate-html-nesting": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", - "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==" - }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -2094,33 +2076,37 @@ } }, "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", - "dependencies": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "version": "5.103.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", + "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", + "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -2139,41 +2125,40 @@ } }, "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", + "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", + "license": "MIT", + "peer": true, "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", + "@discoveryjs/json-ext": "^0.6.1", + "@webpack-cli/configtest": "^3.0.1", + "@webpack-cli/info": "^3.0.1", + "@webpack-cli/serve": "^3.0.1", "colorette": "^2.0.14", - "commander": "^10.0.1", + "commander": "^12.1.0", "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", + "envinfo": "^7.14.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^3.1.1", "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" + "webpack-merge": "^6.0.1" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "5.x.x" + "webpack": "^5.82.0" }, "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, "webpack-bundle-analyzer": { "optional": true }, @@ -2183,78 +2168,37 @@ } }, "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" + "flat": "^5.0.2", + "wildcard": "^2.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "license": "MIT", "engines": { "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", - "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2270,9 +2214,10 @@ } }, "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "license": "MIT" }, "node_modules/yn": { "version": "3.1.1", @@ -2283,11 +2228,12 @@ } }, "node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2299,26 +2245,25 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "peer": true, "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" } }, "@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "requires": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" } }, "@babel/compat-data": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", - "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", - "peer": true + "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==" }, "@babel/core": { "version": "7.22.5", @@ -2344,41 +2289,40 @@ } }, "@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "requires": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } } } }, "@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "requires": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.27.3" } }, "@babel/helper-compilation-targets": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", - "peer": true, "requires": { "@babel/compat-data": "^7.22.5", "@babel/helper-validator-option": "^7.22.5", @@ -2391,7 +2335,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "peer": true, "requires": { "yallist": "^3.0.2" } @@ -2399,222 +2342,201 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "peer": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", - "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.4", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", "semver": "^6.3.1" } }, + "@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==" + }, "@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "requires": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" } }, "@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" } }, "@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "requires": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" } }, "@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "requires": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.27.1" } }, "@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==" + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==" }, "@babel/helper-replace-supers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", - "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" } }, "@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==" + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==" }, "@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==" }, "@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==" + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==" }, "@babel/helpers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", - "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", - "peer": true, - "requires": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "requires": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" } }, "@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "requires": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.28.5" } }, "@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "requires": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1" } }, "@babel/plugin-syntax-typescript": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", - "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "requires": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.27.1" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", - "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", "requires": { - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" } }, "@babel/plugin-transform-typescript": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", - "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", + "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", "requires": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" } }, "@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", "requires": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" } }, "@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" } }, "@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" } }, "@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "requires": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" } }, "@cspotcode/source-map-support": { @@ -2637,15 +2559,14 @@ } }, "@discoveryjs/json-ext": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", - "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==" + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==" }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "peer": true, "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -2662,35 +2583,34 @@ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" }, "@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "requires": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } } } }, "@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==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2716,168 +2636,187 @@ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, + "@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", - "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", + "peer": true }, "@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" }, "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" }, "@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" }, "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" }, "@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" }, "@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "requires": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", + "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", "requires": {} }, "@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", + "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", "requires": {} }, "@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", + "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", "requires": {} }, "@xtuc/ieee754": { @@ -2891,14 +2830,15 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" - }, - "acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "peer": true + }, + "acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "requires": {} }, "acorn-walk": { @@ -2910,14 +2850,15 @@ } }, "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "peer": true, "requires": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" } }, "ajv-formats": { @@ -2936,38 +2877,64 @@ "fast-deep-equal": "^3.1.3" } }, - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, "babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", + "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", "requires": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" + "find-up": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "requires": { + "p-limit": "^3.0.2" + } + } } }, "babel-plugin-jsx-dom-expressions": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.38.5.tgz", - "integrity": "sha512-JfjHYKOKGwoiOYQ56Oo8gbZPb9wNMpPuEEUhSCjMpnuHM9K21HFIUBm83TZPB40Av4caCIW4Tfjzpkp/MtFpMw==", + "version": "0.40.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.40.3.tgz", + "integrity": "sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w==", "requires": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", - "validate-html-nesting": "^1.2.1" + "parse5": "^7.1.2" }, "dependencies": { "@babel/helper-module-imports": { @@ -2981,22 +2948,29 @@ } }, "babel-preset-solid": { - "version": "1.8.22", - "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.8.22.tgz", - "integrity": "sha512-nKwisb//lZsiRF2NErlRP64zVTJqa1OSZiDnSl0YbcTiCZoMt52CY2Pg+9fsYAPtjYMT7RHBmzU41pxK6hFOcg==", + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.9.10.tgz", + "integrity": "sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ==", "requires": { - "babel-plugin-jsx-dom-expressions": "^0.38.5" + "babel-plugin-jsx-dom-expressions": "^0.40.3" } }, + "baseline-browser-mapping": { + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==" + }, "browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "peer": true, "requires": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" } }, "buffer-from": { @@ -3005,19 +2979,9 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "caniuse-lite": { - "version": "1.0.30001655", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", - "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==" }, "chrome-trace-event": { "version": "1.0.3", @@ -3034,19 +2998,6 @@ "shallow-clone": "^3.0.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==", - "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==" - }, "colorette": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", @@ -3057,16 +3008,10 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "peer": true, "requires": { "safe-buffer": "~5.1.1" } @@ -3077,9 +3022,9 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3089,7 +3034,8 @@ "csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "peer": true }, "debug": { "version": "4.3.1", @@ -3105,23 +3051,28 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, "electron-to-chromium": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", - "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==" }, "enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, + "entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==" + }, "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==" + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==" }, "es-module-lexer": { "version": "1.2.1", @@ -3133,11 +3084,6 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" }, - "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==" - }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -3177,73 +3123,16 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==" }, "fastest-levenshtein": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" }, - "find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "requires": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "dependencies": { - "find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "requires": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - } - }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "requires": { - "p-locate": "^6.0.0" - } - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "requires": { - "p-limit": "^4.0.0" - } - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==" - }, - "pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "requires": { - "find-up": "^6.3.0" - } - } - } - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -3253,6 +3142,11 @@ "path-exists": "^4.0.0" } }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" + }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3261,19 +3155,13 @@ "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==", - "peer": true + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, "goober": { "version": "2.1.14", "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", @@ -3294,9 +3182,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "html-entities": { "version": "2.3.3", @@ -3304,9 +3192,9 @@ "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, "immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==" }, "import-local": { "version": "3.0.2", @@ -3346,7 +3234,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "jest-worker": { "version": "27.5.1", @@ -3356,21 +3244,6 @@ "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } } }, "js-tokens": { @@ -3379,9 +3252,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==" }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -3396,8 +3269,7 @@ "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "peer": true + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "kind-of": { "version": "6.0.3", @@ -3405,9 +3277,9 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==" }, "locate-path": { "version": "5.0.0", @@ -3451,9 +3323,9 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==" }, "p-limit": { "version": "2.3.0", @@ -3476,6 +3348,14 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "requires": { + "entities": "^6.0.0" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3492,9 +3372,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "pkg-dir": { "version": "4.2.0", @@ -3504,11 +3384,6 @@ "find-up": "^4.0.0" } }, - "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -3559,9 +3434,9 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "schema-utils": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz", - "integrity": "sha512-Jw+GZVbP5IggB2WAn6UHI02LBwGmsIeYN/lNbSMZyDziQ7jmtAUrqKqDja+W89YHVs+KL/3IkIMltAklqB1vAw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "requires": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -3583,14 +3458,15 @@ } }, "seroval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.1.1.tgz", - "integrity": "sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz", + "integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==", + "peer": true }, "seroval-plugins": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.1.1.tgz", - "integrity": "sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.3.3.tgz", + "integrity": "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==", "requires": {} }, "shallow-clone": { @@ -3615,13 +3491,14 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "solid-js": { - "version": "1.8.22", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.22.tgz", - "integrity": "sha512-VBzN5j+9Y4rqIKEnK301aBk+S7fvFSTs9ljg+YEdFxjNjH0hkjXPiQRcws9tE5fUzMznSS6KToL5hwMfHDgpLA==", + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.10.tgz", + "integrity": "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==", + "peer": true, "requires": { "csstype": "^3.1.0", - "seroval": "^1.1.0", - "seroval-plugins": "^1.1.0" + "seroval": "~1.3.0", + "seroval-plugins": "~1.3.0" } }, "solid-styled-components": { @@ -3648,11 +3525,11 @@ } }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, "supports-preserve-symlinks-flag": { @@ -3661,72 +3538,33 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==" }, "terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "version": "5.44.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", + "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", "requires": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" } }, "terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "requires": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, "ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -3748,25 +3586,18 @@ } }, "typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==" + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "peer": true }, "update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "requires": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", "requires": { - "punycode": "^2.1.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" } }, "v8-compile-cache-lib": { @@ -3774,124 +3605,90 @@ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, - "validate-html-nesting": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", - "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==" - }, "watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", - "requires": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "version": "5.103.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", + "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", + "peer": true, + "requires": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", + "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "schema-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", - "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" } }, "webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", + "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", + "peer": true, "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", + "@discoveryjs/json-ext": "^0.6.1", + "@webpack-cli/configtest": "^3.0.1", + "@webpack-cli/info": "^3.0.1", + "@webpack-cli/serve": "^3.0.1", "colorette": "^2.0.14", - "commander": "^10.0.1", + "commander": "^12.1.0", "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", + "envinfo": "^7.14.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^3.1.1", "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" + "webpack-merge": "^6.0.1" }, "dependencies": { "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==" } } }, "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "requires": { "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" + "flat": "^5.0.2", + "wildcard": "^2.0.1" } }, "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==" }, "which": { "version": "2.0.2", @@ -3902,9 +3699,9 @@ } }, "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" }, "yn": { "version": "3.1.1", @@ -3912,9 +3709,9 @@ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" }, "yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==" + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/package.json b/package.json index 8d2e542..6821a3b 100644 --- a/package.json +++ b/package.json @@ -16,15 +16,15 @@ }, "browserslist": "> 2%, not dead", "dependencies": { - "@babel/preset-typescript": "^7.24.6", - "babel-loader": "^9.1.3", - "babel-preset-solid": "^1.8.17", - "immutable": "^4.3.7", - "solid-js": "^1.8.17", + "@babel/preset-typescript": "^7.28.5", + "babel-loader": "^10.0.0", + "babel-preset-solid": "^1.9.10", + "immutable": "^5.1.4", + "solid-js": "^1.9.10", "solid-styled-components": "^0.28.5", "ts-node": "^10.9.2", - "typescript": "^5.4.5", - "webpack": "^5.91.0", - "webpack-cli": "^5.1.4" + "typescript": "^5.9.3", + "webpack": "^5.103.0", + "webpack-cli": "^6.0.1" } } From 6cc4114645414d19d4baaa2b4edb8d4d9210fa8f Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Sun, 14 Dec 2025 14:56:48 -0300 Subject: [PATCH 03/20] layout chords and markers --- src/prefs.ts | 24 ++- src/project/root.ts | 8 +- src/theory/meter.ts | 2 +- src/timeline/Element.tsx | 29 +-- src/timeline/draw.ts | 314 +++++++++++++++++++++++++++------ src/timeline/index.ts | 2 + src/timeline/layout.ts | 109 +++++++----- src/timeline/layout_chords.ts | 168 ++++++++++++++++++ src/timeline/layout_markers.ts | 118 +++++++++++++ src/timeline/layout_notes.ts | 53 +++++- src/timeline/mouse_drag.ts | 20 ++- src/timeline/timeline.ts | 2 +- src/utils/listOfRanges.ts | 2 +- 13 files changed, 725 insertions(+), 126 deletions(-) create mode 100644 src/timeline/layout_chords.ts create mode 100644 src/timeline/layout_markers.ts diff --git a/src/prefs.ts b/src/prefs.ts index 520ce3b..3f46ff7 100644 --- a/src/prefs.ts +++ b/src/prefs.ts @@ -25,6 +25,12 @@ export interface Prefs noteVelocityMarkerColor: string noteVelocityMarkerInactiveColor: string + fontWeightChord: string, + fontNameChord: string, + + fontWeightMarker: string, + fontNameMarker: string, + keyPan: string keyPencil: string keySelectMultiple: string @@ -43,6 +49,9 @@ export interface Prefs mouseEdgeScrollThreshold: number mouseEdgeScrollSpeed: number + + hoverOuterStretchWidth: number + hoverInnerStretchWidth: number } } @@ -52,18 +61,18 @@ export function makeNew(): Prefs return { timeline: { bkgColor: "#202225", - bkgAlternateMeasureColor: "#1a1c1f", + bkgAlternateMeasureColor: "#1c1e21", bkgInactiveOverlayColor: "#0008", trackVBorderColor: "#888", trackHBorderColor: "#888", selectionCursorColor: "#0af", - selectionBkgColor: "#8cf8", + selectionBkgColor: "#8cf4", playbackCursorColor: "#f00", trackSeparatorColor: "#aaa", measureColor: "#040404", - submeasureColor: "#080808", + submeasureColor: "#181818", halfSubmeasureColor: "#181818", measureLabelColor: "#aaa", @@ -73,6 +82,12 @@ export function makeNew(): Prefs keyChangeColor: "#f0c", noteVelocityMarkerColor: "#0c4", noteVelocityMarkerInactiveColor: "#063", + + fontWeightChord: "", + fontNameChord: "Verdana", + + fontWeightMarker: "bold", + fontNameMarker: "Calibri", keyPan: " ", keyPencil: "a", @@ -92,6 +107,9 @@ export function makeNew(): Prefs mouseEdgeScrollThreshold: 10, mouseEdgeScrollSpeed: 1, + + hoverOuterStretchWidth: 8, + hoverInnerStretchWidth: 8, } } } \ No newline at end of file diff --git a/src/project/root.ts b/src/project/root.ts index ac92a2f..ee8fba5 100644 --- a/src/project/root.ts +++ b/src/project/root.ts @@ -1,4 +1,4 @@ -import Immutable from "immutable" +import * as Immutable from "immutable" import * as Project from "./index.ts" import * as Theory from "../theory" import Range from "../utils/range.ts" @@ -89,6 +89,12 @@ export function makeTest(): ImmutableRoot Range.fromStartDuration(new Rational(i, 4), new Rational(1, 4)), Theory.Utils.midiMiddleC + i)) + for (let i = 0; i < 4; i++) + project = upsertElement(project, Project.makeChord( + project.chordTrackId, + Range.fromStartDuration(new Rational(i * 4, 4), new Rational(4, 4)), + new Theory.Chord(i, 0))) + return project } diff --git a/src/theory/meter.ts b/src/theory/meter.ts index d06df17..f9d8b54 100644 --- a/src/theory/meter.ts +++ b/src/theory/meter.ts @@ -45,7 +45,7 @@ export default class Meter } - get str(): string + toString(): string { return this.numerator + " / " + this.denominator } diff --git a/src/timeline/Element.tsx b/src/timeline/Element.tsx index 021e20c..21684e4 100644 --- a/src/timeline/Element.tsx +++ b/src/timeline/Element.tsx @@ -21,7 +21,8 @@ export function Element(props: {}) return
@@ -46,6 +47,8 @@ function canvasResize( canvas.width = w canvas.height = h + console.log("resize", w, h) + const rect = new Rect(0, 0, w, h) Timeline.resize(timeline, pixelRatio, rect) @@ -89,10 +92,11 @@ function registerHandlers( const onResize = () => { const timeline = Global.get().timeline const project = Global.get().project + const prefs = Global.get().prefs canvasResize(div, canvas, timeline) - Timeline.layout(timeline, project.root) - Timeline.draw(timeline, ctx) + Timeline.layout(timeline, project.root, prefs) + Timeline.draw(timeline, prefs, ctx) } const onMouseMove = (ev: MouseEvent) => { @@ -100,14 +104,15 @@ function registerHandlers( const timeline = Global.get().timeline const project = Global.get().project + const prefs = Global.get().prefs const mouse = transformMousePos(canvas, ev) Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) if (Timeline.mouseDrag(timeline, project)) - Timeline.layout(timeline, project.root) + Timeline.layout(timeline, project.root, prefs) - Timeline.draw(timeline, ctx) + Timeline.draw(timeline, prefs, ctx) setCursor() } @@ -121,7 +126,7 @@ function registerHandlers( Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) Timeline.mouseDown(timeline, project.root, prefs, ev.button !== 0) - Timeline.draw(timeline, ctx) + Timeline.draw(timeline, prefs, ctx) setCursor() } @@ -130,11 +135,12 @@ function registerHandlers( const timeline = Global.get().timeline const project = Global.get().project + const prefs = Global.get().prefs const mouse = transformMousePos(canvas, ev) Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) Timeline.mouseUp(timeline, project.root, ev.button !== 0) - Timeline.draw(timeline, ctx) + Timeline.draw(timeline, prefs, ctx) setCursor() } @@ -143,10 +149,11 @@ function registerHandlers( const timeline = Global.get().timeline const project = Global.get().project + const prefs = Global.get().prefs Timeline.mouseWheel(timeline, ev.deltaX, ev.deltaY) - Timeline.layout(timeline, project.root) - Timeline.draw(timeline, ctx) + Timeline.layout(timeline, project.root, prefs) + Timeline.draw(timeline, prefs, ctx) } const onKeyDown = (ev: KeyboardEvent) => { @@ -167,7 +174,7 @@ function registerHandlers( onResize() - canvas.addEventListener("resize", onResize) + window.addEventListener("resize", onResize) window.addEventListener("mousemove", onMouseMove) canvas.addEventListener("mousedown", onMouseDown) window.addEventListener("mouseup", onMouseUp) @@ -177,7 +184,7 @@ function registerHandlers( window.addEventListener("keyup", onKeyUp) return () => { - canvas.removeEventListener("resize", onResize) + window.removeEventListener("resize", onResize) window.removeEventListener("mousemove", onMouseMove) canvas.removeEventListener("mousedown", onMouseDown) window.removeEventListener("mouseup", onMouseUp) diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index cff61e3..b1ae7cf 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -1,11 +1,13 @@ import * as State from "../state.ts" import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" import * as Theory from "../theory" import Rational from "../utils/rational.ts" export function draw( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D) { ctx.save() @@ -14,14 +16,14 @@ export function draw( ctx.fillStyle = "#fff" ctx.fillRect(0, 0, timeline.renderRect.w, timeline.renderRect.h) - drawElements(timeline, ctx, timeline.layout.elements) + drawElements(timeline, prefs, ctx, timeline.layout.elements) if (timeline.cursor.visible) { const timeMin = timeline.cursor.time1.min(timeline.cursor.time2) const timeMax = timeline.cursor.time1.max(timeline.cursor.time2) - drawCursorBeam(timeline, ctx, timeMin, false) - drawCursorBeam(timeline, ctx, timeMax, true) + drawCursorBeam(timeline, prefs, ctx, timeMin, false) + drawCursorBeam(timeline, prefs, ctx, timeMax, true) } ctx.restore() @@ -30,12 +32,30 @@ export function draw( function drawElements( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, elements: Timeline.LayoutElement[]) { for (const element of elements) { - if (element.kind === "lane") + if (element.id !== undefined && + timeline.selection.has(element.id)) + element.zIndexForHover = 1 + + else if (timeline.hover?.id === element.id) + element.zIndexForHover = 2 + + else + element.zIndexForHover = 0 + } + + elements.sort((a, b) => + ((a.zIndex ?? 0) + (a.zIndexForHover ?? 0)) - + ((b.zIndex ?? 0) + (b.zIndexForHover ?? 0))) + + for (const element of elements) + { + if (element.kind === "laneChords") { ctx.save() ctx.beginPath() @@ -46,20 +66,20 @@ function drawElements( element.rect.h) ctx.clip() - drawLaneBkgSolid(timeline, ctx, element) - drawLaneBkgMeasures(timeline, ctx, element, false) - drawLaneBkgMeasures(timeline, ctx, element, true) - drawCursorBkg(timeline, ctx, element) + drawLaneBkgSolid(timeline, prefs, ctx, element) + drawLaneBkgMeasures(timeline, prefs, ctx, element, false) + drawLaneBkgMeasures(timeline, prefs, ctx, element, true) + drawCursorBkg(timeline, prefs, ctx, element) if (element.subElements) - drawElements(timeline, ctx, element.subElements) + drawElements(timeline, prefs, ctx, element.subElements) - drawLaneFrgOutline(timeline, ctx, element) + drawLaneFrgOutline(timeline, prefs, ctx, element) ctx.restore() } - if (element.kind === "laneNotes") + else if (element.kind === "laneNotes") { ctx.save() ctx.beginPath() @@ -70,25 +90,24 @@ function drawElements( element.rect.h) ctx.clip() - drawLaneBkgSolid(timeline, ctx, element) - drawLaneBkgOctaves(timeline, ctx, element, false) - drawLaneBkgMeasures(timeline, ctx, element, false) - drawLaneBkgOctaves(timeline, ctx, element, true) - drawLaneBkgMeasures(timeline, ctx, element, true) - drawCursorBkg(timeline, ctx, element) + drawLaneBkgSolid(timeline, prefs, ctx, element) + drawLaneBkgOctaves(timeline, prefs, ctx, element, false) + drawLaneBkgMeasures(timeline, prefs, ctx, element, false) + drawLaneBkgOctaves(timeline, prefs, ctx, element, true) + drawLaneBkgMeasures(timeline, prefs, ctx, element, true) + drawCursorBkg(timeline, prefs, ctx, element) if (element.subElements) - drawElements(timeline, ctx, element.subElements) + drawElements(timeline, prefs, ctx, element.subElements) - drawLaneFrgOutline(timeline, ctx, element) + drawLaneFrgOutline(timeline, prefs, ctx, element) ctx.restore() } - if (element.kind === "note") + else if (element.kind === "note") { - ctx.fillStyle = - timeline.hover?.id === element.id ? "#f88" : "#f00" + ctx.save() ctx.beginPath() ctx.roundRect( element.rect.x, @@ -96,17 +115,172 @@ function drawElements( element.rect.w, element.rect.h, timeline.noteRowH / 4) + ctx.clip() + + const x1 = element.rect.x + (element.cutStart ? -16 : 0) + const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) + + ctx.fillStyle = "#f00" + ctx.beginPath() + ctx.roundRect( + x1, + element.rect.y, + x2 - x1, + element.rect.h, + timeline.noteRowH / 4) ctx.fill() + if (timeline.hover?.id === element.id) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } + if (element.id !== undefined && timeline.selection.has(element.id)) { - ctx.strokeStyle = "#fbb" - ctx.lineWidth = 4 + ctx.strokeStyle = "#fff8" + ctx.lineWidth = 6 ctx.stroke() } + + ctx.restore() } + + else if (element.kind === "chord") + { + ctx.save() + ctx.beginPath() + ctx.roundRect( + element.rect.x, + element.rect.y, + element.rect.w, + element.rect.h, + 5) + ctx.clip() + + const x1 = element.rect.x + (element.cutStart ? -16 : 0) + const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) + + ctx.fillStyle = "#f00" + ctx.beginPath() + ctx.roundRect( + x1, + element.rect.y, + x2 - x1, + element.rect.h, + 5) + ctx.fill() + + const ornamentH = 6 + ctx.fillStyle = "#ddd" + ctx.fillRect( + x1, + element.rect.y + ornamentH, + x2 - x1, + element.rect.h - ornamentH * 2) + + ctx.fillStyle = "#000" + ctx.font = `${prefs.timeline.fontWeightChord} ${element.rect.h * 0.65}px ${prefs.timeline.fontNameChord}` + ctx.textAlign = "center" + ctx.textBaseline = "middle" + ctx.fillText( + element.chord.chord.romanBase(element.key) + + element.chord.chord.romanSup(element.key) + + element.chord.chord.romanSub(element.key), + element.rect.xCenter, + element.rect.yCenter + element.rect.h * 0.05, + element.rect.w * 0.95) + + ctx.beginPath() + ctx.roundRect( + x1, + element.rect.y, + x2 - x1, + element.rect.h, + 5) + + if (timeline.hover?.id === element.id) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } + + if (element.id !== undefined && + timeline.selection.has(element.id)) + { + ctx.strokeStyle = "#fff8" + ctx.lineWidth = 6 + ctx.stroke() + } + + ctx.restore() + } + + else if (element.kind === "marker") + drawMarker(timeline, prefs, ctx, element) + } +} + + +function drawMarker( + timeline: Timeline.State, + prefs: Prefs.Prefs, + ctx: CanvasRenderingContext2D, + element: Timeline.LayoutElementMarker) +{ + ctx.save() + + const color = + element.keyCh ? prefs.timeline.keyChangeColor : + element.meterCh ? prefs.timeline.meterChangeColor : + "#000" + + const text = + element.keyCh ? element.keyCh.key.toString() : + element.meterCh ? element.meterCh.meter.toString() : + "" + + ctx.fillStyle = color + ctx.strokeStyle = prefs.timeline.bkgColor + ctx.font = `bold ${element.rect.h * 0.85}px ${prefs.timeline.fontNameMarker}` + ctx.textAlign = "left" + ctx.textBaseline = "middle" + ctx.lineWidth = 8 + ctx.strokeText( + text, + element.rect.x2 + 8, + element.rect.yCenter) + ctx.fillText( + text, + element.rect.x2 + 8, + element.rect.yCenter) + + ctx.beginPath() + ctx.moveTo(element.rect.x, element.rect.y) + ctx.lineTo(element.rect.x2, element.rect.y) + ctx.lineTo(element.rect.x2, element.rect.y + element.rect.h * 0.65) + ctx.lineTo(element.rect.xCenter, element.rect.y2) + ctx.lineTo(element.rect.x, element.rect.y + element.rect.h * 0.65) + ctx.lineTo(element.rect.x, element.rect.y) + ctx.clip() + ctx.fill() + + if (timeline.hover?.id === element.id) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } + + if (element.id !== undefined && + timeline.selection.has(element.id)) + { + ctx.strokeStyle = "#fff8" + ctx.lineWidth = 6 + ctx.stroke() } + + ctx.restore() } @@ -127,24 +301,47 @@ export function drawLaneBkgCenterStroke( export function drawLaneBkgSolid( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutElementLaneMarkers | Timeline.LayoutElementLaneNotes) + lane: Timeline.LayoutLane) { - ctx.fillStyle = "#eee" - ctx.fillRect( - lane.rect.x, - lane.rect.y, - lane.rect.w, - lane.rect.h) + if (timeline.layout.measures.length > 100) + { + ctx.fillStyle = prefs.timeline.bkgColor + ctx.fillRect( + lane.rect.x, + lane.rect.y, + lane.rect.w, + lane.rect.h) + + return + } + + for (const measure of timeline.layout.measures) + { + const x1 = Math.floor(Timeline.xAtTime(timeline, measure.time1)) + const x2 = Math.floor(Timeline.xAtTime(timeline, measure.time2)) + + ctx.fillStyle = + measure.num % 2 === 0 ? prefs.timeline.bkgColor : + prefs.timeline.bkgAlternateMeasureColor + + ctx.fillRect( + x1, + lane.rect.y, + x2 - x1, + lane.rect.h) + } } export function drawLaneFrgOutline( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutElementLaneMarkers | Timeline.LayoutElementLaneNotes) + lane: Timeline.LayoutLane) { - ctx.strokeStyle = "#000" + ctx.strokeStyle = prefs.timeline.measureColor ctx.lineWidth = 1 ctx.beginPath() ctx.moveTo(lane.rect.x, lane.rect.y) @@ -157,13 +354,12 @@ export function drawLaneFrgOutline( export function drawLaneBkgMeasures( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutElementLaneMarkers | Timeline.LayoutElementLaneNotes, + lane: Timeline.LayoutLane, mainLinePass: boolean) { // Render alternating measure background and sub-measure dividers. - const measureHalfH = lane.rect.h / 2 - const submeasureHalfH = lane.rect.h / 2 for (const measure of timeline.layout.measures) { const x1 = Math.floor(Timeline.xAtTime(timeline, measure.time1)) @@ -175,7 +371,7 @@ export function drawLaneBkgMeasures( if (mainLinePass) { - ctx.strokeStyle = "#444" + ctx.strokeStyle = prefs.timeline.measureColor ctx.lineWidth = 2 ctx.beginPath() ctx.moveTo(x1 + 0.5, lane.rect.y) @@ -186,7 +382,7 @@ export function drawLaneBkgMeasures( if (!mainLinePass && submeasureSize > 8) { - ctx.strokeStyle = "#fff" + ctx.strokeStyle = prefs.timeline.submeasureColor ctx.lineWidth = 1 ctx.beginPath() @@ -203,11 +399,32 @@ export function drawLaneBkgMeasures( ctx.stroke() } } + + if (mainLinePass) + { + for (const marker of timeline.layout.markers) + { + const x = Math.floor(Timeline.xAtTime(timeline, marker.time)) + + const color = + marker.keyCh ? prefs.timeline.keyChangeColor : + marker.meterCh ? prefs.timeline.meterChangeColor : + prefs.timeline.measureColor + + ctx.strokeStyle = color + ctx.lineWidth = 2 + ctx.beginPath() + ctx.moveTo(x + 0.5, lane.rect.y) + ctx.lineTo(x + 0.5, lane.rect.y + lane.rect.h) + ctx.stroke() + } + } } export function drawLaneBkgOctaves( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, lane: Timeline.LayoutElementLaneNotes, mainLinePass: boolean) @@ -218,7 +435,7 @@ export function drawLaneBkgOctaves( const octaveAtTop = Math.ceil(rowAtTop / 7) + 1 const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1 - ctx.fillStyle = "#444" + ctx.fillStyle = prefs.timeline.octaveLabelColor ctx.font = Math.floor(timeline.noteRowH - 4) + "px system-ui" ctx.textAlign = "left" ctx.textBaseline = "bottom" @@ -232,12 +449,11 @@ export function drawLaneBkgOctaves( for (const measure of timeline.layout.measures) { - /*if (measure.time1.lessThan(keyRegion.keyCh1.range.start) || - measure.time2.greaterThan(keyRegion.keyCh2.range.start)) - continue*/ + const time1 = measure.time1.max(keyRegion.keyCh1.range.start) + const time2 = measure.time2.min(keyRegion.keyCh2.range.start) - const x1 = Math.floor(Timeline.xAtTime(timeline, measure.time1)) - const x2 = Math.floor(Timeline.xAtTime(timeline, measure.time2)) + const x1 = Math.floor(Timeline.xAtTime(timeline, time1)) + const x2 = Math.floor(Timeline.xAtTime(timeline, time2)) for (let i = octaveAtBottom; i <= octaveAtTop; i++) { @@ -253,7 +469,7 @@ export function drawLaneBkgOctaves( drewOctaveLabels = true } - ctx.strokeStyle = "#444" + ctx.strokeStyle = prefs.timeline.measureColor ctx.beginPath() ctx.moveTo(x1, y) ctx.lineTo(x2, y) @@ -264,7 +480,7 @@ export function drawLaneBkgOctaves( if (!mainLinePass) { - ctx.strokeStyle = "#fff" + ctx.strokeStyle = prefs.timeline.submeasureColor ctx.beginPath() for (let j = 1; j < 7; j += 1) { @@ -287,12 +503,11 @@ export function drawLaneBkgOctaves( function drawCursorBeam( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, time: Rational, tipOffsetSide: boolean) { - const prefs = State.get().prefs - const laneIndexMin = Timeline.cursorGetLaneIndexMin(timeline) const laneIndexMax = Timeline.cursorGetLaneIndexMax(timeline) @@ -333,14 +548,13 @@ function drawCursorBeam( function drawCursorBkg( timeline: Timeline.State, + prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, lane: Timeline.LayoutLane) { if (!timeline.cursor.visible) return - const prefs = State.get().prefs - const timeMin = timeline.cursor.time1.min(timeline.cursor.time2) const timeMax = timeline.cursor.time1.max(timeline.cursor.time2) const laneIndexMin = Timeline.cursorGetLaneIndexMin(timeline) diff --git a/src/timeline/index.ts b/src/timeline/index.ts index 67ee95d..af35fad 100644 --- a/src/timeline/index.ts +++ b/src/timeline/index.ts @@ -1,7 +1,9 @@ export * from "./Element.tsx" export * from "./timeline.ts" export * from "./layout.ts" +export * from "./layout_markers.ts" export * from "./layout_notes.ts" +export * from "./layout_chords.ts" export * from "./mouse_move.ts" export * from "./mouse_down.ts" export * from "./mouse_drag.ts" diff --git a/src/timeline/layout.ts b/src/timeline/layout.ts index 4ac9209..d6c9d0b 100644 --- a/src/timeline/layout.ts +++ b/src/timeline/layout.ts @@ -1,7 +1,10 @@ import * as Project from "../project" import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" +import * as Theory from "../theory/index.ts" import Rect from "../utils/rect.ts" import Range from "../utils/range.ts" +import Rational from "utils/rational.ts" export interface LayoutElementCommon @@ -9,6 +12,10 @@ export interface LayoutElementCommon id?: Project.ID action?: Timeline.MouseAction rect: Rect + zIndex?: number + zIndexForHover?: number + cutStart?: boolean + cutEnd?: boolean priority?: number subElements?: LayoutElement[] } @@ -34,7 +41,7 @@ export interface LayoutElementLaneCommon extends LayoutElementCommon export interface LayoutElementLaneMarkers extends LayoutElementLaneCommon { - kind: "lane" + kind: "laneMarkers" } @@ -44,22 +51,48 @@ export interface LayoutElementLaneNotes extends LayoutElementLaneCommon } +export interface LayoutElementLaneChords extends LayoutElementLaneCommon +{ + kind: "laneChords" +} + + export interface LayoutElementNote extends LayoutElementCommon { kind: "note" } +export interface LayoutElementChord extends LayoutElementCommon +{ + kind: "chord" + chord: Project.Chord + key: Theory.Key +} + + +export interface LayoutElementMarker extends LayoutElementCommon +{ + kind: "marker" + keyCh?: Project.KeyChange + meterCh?: Project.MeterChange +} + + export type LayoutElement = LayoutElementHidden | LayoutElementLaneMarkers | LayoutElementLaneNotes | - LayoutElementNote + LayoutElementLaneChords | + LayoutElementNote | + LayoutElementChord | + LayoutElementMarker export type LayoutLane = LayoutElementLaneMarkers | - LayoutElementLaneNotes + LayoutElementLaneNotes | + LayoutElementLaneChords export interface KeyRegion @@ -71,6 +104,14 @@ export interface KeyRegion } +export interface Marker +{ + time: Rational + keyCh?: Project.KeyChange + meterCh?: Project.MeterChange +} + + export class Layout { range: Range @@ -78,9 +119,11 @@ export class Layout elements: LayoutElement[] = [] elementCount: number = 0 laneNotes?: LayoutElementLaneNotes + laneChords?: LayoutElementLaneChords measures: Project.Measure[] = [] keyRegions: KeyRegion[] = [] + markers: Marker[] = [] constructor() @@ -104,8 +147,9 @@ export class Layout { this.elements.push(elem) - if (elem.kind === "lane" || - elem.kind === "laneNotes") + if (elem.kind === "laneMarkers" || + elem.kind === "laneNotes" || + elem.kind === "laneChords") this.lanes.push(elem) } } @@ -114,71 +158,46 @@ export class Layout export function layout( timeline: Timeline.State, - project: Project.ImmutableRoot) + project: Project.ImmutableRoot, + prefs: Prefs.Prefs) { const layout = new Layout() layout.range = Timeline.visibleTimeRange(timeline) layout.measures = [...Project.iterMeasuresAtRange(project, layout.range)] layout.keyRegions = [...iterKeyChangePairsAtRange(timeline, project, layout.range)] + layout.markers = [] - const laneMarkerH = 32 const laneChordH = 60 - const laneMarginH = 8 + const laneMarginY = 8 - const laneKeyChanges: LayoutElementLaneMarkers = { - kind: "lane", + const laneNotes: LayoutElementLaneNotes = { + kind: "laneNotes", laneIndex: 0, rect: new Rect( 0, 0, timeline.renderRect.w, - laneMarkerH), + timeline.renderRect.h - laneChordH - laneMarginY), } - const laneMeterChanges: LayoutElementLaneMarkers = { - kind: "lane", + const laneChords: LayoutElementLaneChords = { + kind: "laneChords", laneIndex: 1, rect: new Rect( 0, - laneMarkerH + laneMarginH, + timeline.renderRect.h - laneChordH, timeline.renderRect.w, - laneMarkerH), + laneChordH - 1), } - const laneChords: LayoutElementLaneMarkers = { - kind: "lane", - laneIndex: 2, - rect: new Rect( - 0, - laneMarkerH + laneMarginH + - laneMarkerH + laneMarginH, - timeline.renderRect.w, - laneChordH), - } - - const laneNotesY = - laneMarkerH + laneMarginH + - laneMarkerH + laneMarginH + - laneChordH + laneMarginH - - const laneNotes: LayoutElementLaneNotes = { - kind: "laneNotes", - laneIndex: 3, - rect: new Rect( - 0, - laneNotesY, - timeline.renderRect.w, - timeline.renderRect.h - laneNotesY), - } - - layout.add(undefined, laneKeyChanges) - layout.add(undefined, laneMeterChanges) - layout.add(undefined, laneChords) layout.add(undefined, laneNotes) + layout.add(undefined, laneChords) layout.laneNotes = laneNotes - Timeline.layoutLaneNotes(timeline, project, layout, laneNotes) + Timeline.layoutLaneMarkers(timeline, project, prefs, layout, laneNotes) + Timeline.layoutLaneNotes(timeline, project, prefs, layout, laneNotes) + Timeline.layoutLaneChords(timeline, project, prefs, layout, laneChords) timeline.layout = layout console.log(layout.elementCount, layout) diff --git a/src/timeline/layout_chords.ts b/src/timeline/layout_chords.ts new file mode 100644 index 0000000..1ebb82a --- /dev/null +++ b/src/timeline/layout_chords.ts @@ -0,0 +1,168 @@ +import * as Project from "../project" +import * as Theory from "../theory" +import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" + + +export function layoutLaneChords( + timeline: Timeline.State, + project: Project.ImmutableRoot, + prefs: Prefs.Prefs, + layout: Timeline.Layout, + laneChords: Timeline.LayoutElementLaneChords) +{ + laneChords.iterElementsAtRegion = (timeline, project, range, verticalRegion) => + iterChordsAtRegion(timeline, project, laneChords, range) + + for (const [chord, keyChPair] of iterChordsAndKeyChanges(timeline, project, layout)) + { + const key = keyChPair.keyCh1.key + + const [rect, cutStart, cutEnd] = rectForChord( + timeline, + laneChords, + chord.range, + keyChPair.x1, + keyChPair.x2) + + if (!cutStart) + { + layout.add(laneChords, { + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rect.withX1(rect.x1 - prefs.timeline.hoverOuterStretchWidth), + }) + } + + if (!cutEnd) + { + layout.add(laneChords, { + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rect.withX2(rect.x2 + prefs.timeline.hoverOuterStretchWidth), + }) + } + + if (rect.w > prefs.timeline.hoverInnerStretchWidth * 2) + { + if (!cutStart) + { + layout.add(laneChords, { + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rect.withX2(rect.x1 + prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + + if (!cutEnd) + { + layout.add(laneChords, { + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rect.withX1(rect.x2 - prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + } + + layout.add(laneChords, { + kind: "chord", + id: chord.id, + action: Timeline.MouseAction.DragTime, + rect, + cutStart, + cutEnd, + priority: 1, + chord: chord, + key: key, + }) + } +} + + +function *iterChordsAndKeyChanges( + timeline: Timeline.State, + project: Project.ImmutableRoot, + layout: Timeline.Layout) + : Generator<[Project.Chord, Timeline.KeyRegion], void, void> +{ + for (const keyRegion of layout.keyRegions) + { + const time1 = keyRegion.keyCh1.range.start.max(layout.range.start) + const time2 = keyRegion.keyCh2.range.start.min(layout.range.end) + + for (const chord of iterChords(timeline, project, new Range(time1, time2))) + yield [chord, keyRegion] + } +} + + +function *iterChords( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const list = project.lists.get(project.chordTrackId) + if (!list) + return + + for (const elem of list.iterAtRange(range)) + yield elem as Project.Chord +} + + +function rectForChord( + timeline: Timeline.State, + lane: Timeline.LayoutElementLaneChords, + chordRange: Range, + keyChXStart: number, + keyChXEnd: number) + : [Rect, boolean, boolean] +{ + const chordOrigX1 = Timeline.xAtTime(timeline, chordRange.start) + const chordOrigX2 = Timeline.xAtTime(timeline, chordRange.end) + + let chordX1 = Math.max(chordOrigX1, keyChXStart) + let chordX2 = Math.min(chordOrigX2, keyChXEnd) + + const cutStart = chordOrigX1 < chordX1 + const cutEnd = chordOrigX2 > chordX2 + + //if (!cutStart) chordX1 += 1 + //if (!cutEnd) chordX2 -= 1 + + chordX1 = 0.5 + Math.floor(chordX1) + chordX2 = 0.5 + Math.floor(chordX2) + + const chordW = Math.max(2, chordX2 - chordX1) + + return [ + new Rect(chordX1, lane.rect.y, chordW, lane.rect.h), + cutStart, + cutEnd] +} + + +function *iterChordsAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + lane: Timeline.LayoutElementLaneChords, + range: Range) + : Generator +{ + for (const [chord, keyChPair] of iterChordsAndKeyChanges(timeline, project, timeline.layout)) + { + if (!chord.range.overlapsRange(range)) + continue + + yield chord.id + } +} \ No newline at end of file diff --git a/src/timeline/layout_markers.ts b/src/timeline/layout_markers.ts new file mode 100644 index 0000000..e0c7acc --- /dev/null +++ b/src/timeline/layout_markers.ts @@ -0,0 +1,118 @@ +import * as Project from "../project" +import * as Theory from "../theory" +import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" +import Rational from "../utils/rational.ts" + + +export function layoutLaneMarkers( + timeline: Timeline.State, + project: Project.ImmutableRoot, + prefs: Prefs.Prefs, + layout: Timeline.Layout, + lane: Timeline.LayoutElementLaneNotes) +{ + lane.iterElementsAtRegion = (timeline, project, range, verticalRegion) => + iterMarkersForSelection(timeline, project, range) + + for (const elem of iterMarkersForLayout(timeline, project, layout.range)) + { + const rect = rectForMarker( + timeline, + lane, + elem.type === "keyChange" ? 0 : + 1, + elem.range.start) + + layout.add(lane, { + kind: "marker", + id: elem.id, + action: Timeline.MouseAction.DragTime, + rect, + priority: 1, + zIndex: 1, + keyCh: elem.type === "keyChange" ? elem : undefined, + meterCh: elem.type === "meterChange" ? elem : undefined, + }) + + layout.markers.push({ + time: elem.range.start, + keyCh: elem.type === "keyChange" ? elem : undefined, + meterCh: elem.type === "meterChange" ? elem : undefined, + }) + } +} + + +function *iterMarkersForLayout( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const keyChTrackId = Project.keyChangeTrackId(project) + const keyChTrackElems = project.lists.get(keyChTrackId) + if (!keyChTrackElems) + return + + for (const keyCh of keyChTrackElems.iterAtRange(range)) + { + yield keyCh as Project.KeyChange + } + + const meterChTrackId = Project.meterChangeTrackId(project) + const meterChTrackElems = project.lists.get(meterChTrackId) + if (!meterChTrackElems) + return + + for (const meterCh of meterChTrackElems.iterAtRange(range)) + { + yield meterCh as Project.MeterChange + } +} + + +function rectForMarker( + timeline: Timeline.State, + lane: Timeline.LayoutLane, + row: number, + time: Rational) + : Rect +{ + const x = Timeline.xAtTime(timeline, time) + const w = 16 + const h = 24 + const y = lane.rect.y + h * row + + return new Rect(x - w / 2, y, w, h) +} + + +export function *iterMarkersForSelection( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const keyChTrackId = Project.keyChangeTrackId(project) + const keyChTrackElems = project.lists.get(keyChTrackId) + if (!keyChTrackElems) + return + + for (const keyCh of keyChTrackElems.iterAtRange(range)) + { + yield keyCh.id + } + + const meterChTrackId = Project.meterChangeTrackId(project) + const meterChTrackElems = project.lists.get(meterChTrackId) + if (!meterChTrackElems) + return + + for (const meterCh of meterChTrackElems.iterAtRange(range)) + { + yield meterCh.id + } +} \ No newline at end of file diff --git a/src/timeline/layout_notes.ts b/src/timeline/layout_notes.ts index 3b1c490..a6240a9 100644 --- a/src/timeline/layout_notes.ts +++ b/src/timeline/layout_notes.ts @@ -1,6 +1,7 @@ import * as Project from "../project" import * as Theory from "../theory" import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" import Rect from "../utils/rect.ts" import Range from "../utils/range.ts" @@ -8,11 +9,12 @@ import Range from "../utils/range.ts" export function layoutLaneNotes( timeline: Timeline.State, project: Project.ImmutableRoot, + prefs: Prefs.Prefs, layout: Timeline.Layout, laneNotes: Timeline.LayoutElementLaneNotes) { laneNotes.iterElementsAtRegion = (timeline, project, range, verticalRegion) => - iterNotesAtRegion(timeline, project, laneNotes, range, verticalRegion) + iterNotesAndMarkersAtRegion(timeline, project, laneNotes, range, verticalRegion) for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, layout)) { @@ -30,31 +32,56 @@ export function layoutLaneNotes( if (!cutStart) { - const rectStretchStart = rect.withX1(rect.x1 - 8) layout.add(laneNotes, { kind: "hidden", id: note.id, action: Timeline.MouseAction.StretchTimeStart, - rect: rectStretchStart, + rect: rect.withX1(rect.x1 - prefs.timeline.hoverOuterStretchWidth), }) } if (!cutEnd) { - const rectStretchEnd = rect.withX2(rect.x2 + 8) layout.add(laneNotes, { kind: "hidden", id: note.id, action: Timeline.MouseAction.StretchTimeEnd, - rect: rectStretchEnd, + rect: rect.withX2(rect.x2 + prefs.timeline.hoverOuterStretchWidth), }) } + if (rect.w > prefs.timeline.hoverInnerStretchWidth * 2) + { + if (!cutStart) + { + layout.add(laneNotes, { + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rect.withX2(rect.x1 + prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + + if (!cutEnd) + { + layout.add(laneNotes, { + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rect.withX1(rect.x2 - prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + } + layout.add(laneNotes, { kind: "note", id: note.id, action: Timeline.MouseAction.DragTimeAndRow, rect, + cutStart, + cutEnd, priority: 1, }) } @@ -177,6 +204,22 @@ function rectForNote( } +function *iterNotesAndMarkersAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + lane: Timeline.LayoutElementLaneNotes, + range: Range, + verticalRegion?: { y1: number, y2: number }) + : Generator +{ + for (const note of iterNotesAtRegion(timeline, project, lane, range, verticalRegion)) + yield note + + for (const marker of Timeline.iterMarkersForSelection(timeline, project, range)) + yield marker +} + + function *iterNotesAtRegion( timeline: Timeline.State, project: Project.ImmutableRoot, diff --git a/src/timeline/mouse_drag.ts b/src/timeline/mouse_drag.ts index ded96c9..1f422da 100644 --- a/src/timeline/mouse_drag.ts +++ b/src/timeline/mouse_drag.ts @@ -136,10 +136,12 @@ function handleDragElements( timeline.drag.origin.range) { changes.range = Project.getAbsoluteRange(origProject, elem.parentId, elem.range) - changes.range = changes.range.stretch( - timeline.drag.timeDelta, - timeline.drag.origin.range.end, - timeline.drag.origin.range.start) + changes.range = changes.range + .stretch( + timeline.drag.timeDelta, + timeline.drag.origin.range.end, + timeline.drag.origin.range.start) + .sorted() if (elem.range.start.compare(timeline.drag.origin.range.start) == 0) changes.range = new Range( @@ -156,10 +158,12 @@ function handleDragElements( timeline.drag.origin.range) { changes.range = Project.getAbsoluteRange(origProject, elem.parentId, elem.range) - changes.range = changes.range.stretch( - timeline.drag.timeDelta, - timeline.drag.origin.range.start, - timeline.drag.origin.range.end) + changes.range = changes.range + .stretch( + timeline.drag.timeDelta, + timeline.drag.origin.range.start, + timeline.drag.origin.range.end) + .sorted() if (elem.range.end.compare(timeline.drag.origin.range.end) == 0) changes.range = new Range( diff --git a/src/timeline/timeline.ts b/src/timeline/timeline.ts index 1739cff..7c7836a 100644 --- a/src/timeline/timeline.ts +++ b/src/timeline/timeline.ts @@ -1,4 +1,4 @@ -import Immutable from "immutable" +import * as Immutable from "immutable" import * as Project from "../project" import * as Timeline from "./index.ts" import Rational from "../utils/rational.ts" diff --git a/src/utils/listOfRanges.ts b/src/utils/listOfRanges.ts index 0651303..ccc21be 100644 --- a/src/utils/listOfRanges.ts +++ b/src/utils/listOfRanges.ts @@ -1,5 +1,5 @@ import assert from "assert" -import Immutable from "immutable" +import * as Immutable from "immutable" import Rational from "./rational.ts" import Range from "./range.ts" import BinarySearch from "./binarySearch.ts" From 7320ac57cbac803db968600627d890e27fa2fa04 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Mon, 15 Dec 2025 20:16:11 -0300 Subject: [PATCH 04/20] add keyboard interactions; add tuple indicators --- src/main.tsx | 1 + src/timeline/Element.tsx | 13 +- src/timeline/draw.ts | 23 ++- src/timeline/key_down.ts | 264 ++++++++++++++++++++++++++++++++++ src/timeline/layout.ts | 15 ++ src/timeline/layout_chords.ts | 2 +- src/timeline/layout_notes.ts | 31 +++- src/timeline/mouse_down.ts | 10 +- src/timeline/mouse_up.ts | 6 +- src/timeline/timeline.ts | 97 +++++++++++++ src/utils/rect.ts | 10 ++ 11 files changed, 461 insertions(+), 11 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 798f709..a8f7012 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -26,6 +26,7 @@ const AppRoot = styled.div` width: 100%; height: 100%; min-height: 0; + background-color: #101215; ` diff --git a/src/timeline/Element.tsx b/src/timeline/Element.tsx index 21684e4..275f065 100644 --- a/src/timeline/Element.tsx +++ b/src/timeline/Element.tsx @@ -125,7 +125,7 @@ function registerHandlers( const mouse = transformMousePos(canvas, ev) Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) - Timeline.mouseDown(timeline, project.root, prefs, ev.button !== 0) + Timeline.mouseDown(timeline, project, prefs, ev.button !== 0) Timeline.draw(timeline, prefs, ctx) setCursor() } @@ -139,7 +139,10 @@ function registerHandlers( const mouse = transformMousePos(canvas, ev) Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) - Timeline.mouseUp(timeline, project.root, ev.button !== 0) + + if (Timeline.mouseUp(timeline, project, ev.button !== 0)) + Timeline.layout(timeline, project.root, prefs) + Timeline.draw(timeline, prefs, ctx) setCursor() } @@ -158,8 +161,12 @@ function registerHandlers( const onKeyDown = (ev: KeyboardEvent) => { const timeline = Global.get().timeline + const project = Global.get().project + const prefs = Global.get().prefs - Timeline.keyDown(timeline, ev.key.toLowerCase()) + Timeline.keyDown(timeline, project, prefs, ev.key.toLowerCase()) + Timeline.layout(timeline, project.root, prefs) + Timeline.draw(timeline, prefs, ctx) } const onKeyUp = (ev: KeyboardEvent) => { diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index b1ae7cf..5f01798 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -14,7 +14,7 @@ export function draw( ctx.translate(0.5, 0.5) ctx.fillStyle = "#fff" - ctx.fillRect(0, 0, timeline.renderRect.w, timeline.renderRect.h) + ctx.clearRect(0, 0, timeline.renderRect.w, timeline.renderRect.h) drawElements(timeline, prefs, ctx, timeline.layout.elements) @@ -100,6 +100,27 @@ function drawElements( if (element.subElements) drawElements(timeline, prefs, ctx, element.subElements) + for (const tuple of element.tupleIndicators) + { + ctx.strokeStyle = prefs.timeline.octaveLabelColor + ctx.lineWidth = 2 + ctx.beginPath() + ctx.moveTo(tuple.rect.x, tuple.rect.y2 + 2) + ctx.lineTo(tuple.rect.x, tuple.rect.y2 + 5) + ctx.lineTo(tuple.rect.x2, tuple.rect.y2 + 5) + ctx.lineTo(tuple.rect.x2, tuple.rect.y2 + 2) + ctx.stroke() + + ctx.fillStyle = prefs.timeline.octaveLabelColor + ctx.font = Math.floor(timeline.noteRowH - 4) + "px system-ui" + ctx.textAlign = "center" + ctx.textBaseline = "top" + ctx.fillText( + tuple.denominator.toString(), + tuple.rect.xCenter, + tuple.rect.y2 + 8) + } + drawLaneFrgOutline(timeline, prefs, ctx, element) ctx.restore() diff --git a/src/timeline/key_down.ts b/src/timeline/key_down.ts index 3f0bba4..766cef4 100644 --- a/src/timeline/key_down.ts +++ b/src/timeline/key_down.ts @@ -1,9 +1,273 @@ +import * as Project from "../project" import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" +import * as Theory from "../theory" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" export function keyDown( timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, key: string) { timeline.keysDown.add(key) + + switch (key) + { + case "arrowright": + case "arrowleft": + { + handleLeftRight(timeline, project, prefs, key === "arrowleft") + break + } + + case "arrowup": + case "arrowdown": + { + handleUpDown(timeline, project, prefs, key === "arrowup", false) + break + } + } +} + + +function modifySelectedElems( + timeline: Timeline.State, + project: Project.Mutable, + func: (elem: Project.Element) => Project.Element) +{ + for (const id of timeline.selection) + { + const elem = project.root.elems.get(id) + if (!elem) + continue + + const newElem = func(elem) + if (newElem === elem) + continue + + project.root = Project.upsertElement(project.root, newElem) + } + + project.root = Project.withRefreshedRange(project.root) +} + + +function handleLeftRight( + timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, + isLeft: boolean) +{ + const keyFast = timeline.keysDown.has(prefs.timeline.keyDisplaceFast) + const keyCursor2 = timeline.keysDown.has(prefs.timeline.keyDisplaceCursor2) + const keyStretch = timeline.keysDown.has(prefs.timeline.keyDisplaceStretch) + + + /*if (Playback.global.playing) + { + const timeDelta = state.timeSnap.multiplyByFloat( + (keyFast ? 64 : 16) * (isLeft ? -1 : 1)) + + Playback.setStartTime(Playback.global.playTime.add(timeDelta)) + Playback.setPlaying(true) + } + else*/ + if (timeline.cursor.visible && + (timeline.selection.size === 0 || keyCursor2)) + { + const timeDelta = timeline.timeSnap.multiplyByFloat( + (keyFast ? 16 : 1) * (isLeft ? -1 : 1)) + + Timeline.keyHandlePendingFinish(timeline, project) + + if (keyCursor2) + { + const newTime = timeline.cursor.time2.add(timeDelta) + Timeline.cursorSetTime(timeline, null, newTime) + Timeline.selectionClear(timeline) + Timeline.selectionAddAtCursor(timeline, project.root) + Timeline.scrollTimeIntoView(timeline, newTime) + //Playback.setStartTime(newTime) + } + else + { + const timeMin = timeline.cursor.time1.min(timeline.cursor.time2) + const timeMax = timeline.cursor.time1.max(timeline.cursor.time2) + + const newTime = (isLeft ? timeMin : timeMax).add(timeDelta) + + Timeline.cursorSetTime(timeline, newTime, newTime) + Timeline.scrollTimeIntoView(timeline, newTime) + //Playback.setStartTime(newTime) + } + } + else + { + const timeDelta = timeline.timeSnap.multiplyByFloat( + (keyFast ? 16 : 1) * (isLeft ? -1 : 1)) + + const selectionRange = Timeline.selectionRange(timeline, project.root) + + let playedPreview = false + modifySelectedElems(timeline, project, (elem) => { + if (elem.type == "track") + return elem + + let newRange = elem.range + + if (keyStretch && selectionRange) + { + const absRange = Project.getAbsoluteRange( + project.root, + elem.parentId, + elem.range) + + newRange = Project.getRelativeRange( + project.root, + elem.parentId, + absRange.stretch( + timeDelta, + selectionRange.start, + selectionRange.end)) + } + else + { + newRange = elem.range.displace(timeDelta) + } + + if (!elem.range.duration.isZero() && newRange.duration.isZero()) + return elem + + if (!playedPreview) + { + if (elem.type == "note") + { + playedPreview = true + timeline.insertion.nearMidiPitch = elem.midiPitch + timeline.insertion.duration = newRange.duration + } + else if (elem.type == "chord") + { + playedPreview = true + timeline.insertion.duration = newRange.duration + } + } + + return Project.elemModify(elem, { + range: newRange + }) + }) + + const range = + Timeline.selectionRange(timeline, project.root) || + new Range(new Rational(0), new Rational(0)) + + const newTime = (isLeft && !keyStretch ? range.start : range.end) + timeline.cursor.visible = false + Timeline.cursorSetTime(timeline, newTime, newTime) + Timeline.scrollTimeIntoView(timeline, newTime) + + timeline.needsKeyFinish = true + } +} + + +function handleUpDown( + timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, + isUp: boolean, + isChromatic: boolean) +{ + const keyFast = timeline.keysDown.has(prefs.timeline.keyDisplaceFast) + const keyCursor2 = timeline.keysDown.has(prefs.timeline.keyDisplaceCursor2) + const keyChromatic = timeline.keysDown.has(prefs.timeline.keyDisplaceChromatically) + + + if (!isChromatic && + timeline.cursor.visible && + (timeline.selection.size === 0 || keyCursor2)) + { + const trackDelta = (isUp ? -1 : 1) + + Timeline.keyHandlePendingFinish(timeline, project) + + if (keyCursor2) + { + const newTrack = timeline.cursor.laneIndex2 + trackDelta + Timeline.cursorSetTrack(timeline, null, newTrack) + Timeline.selectionClear(timeline) + Timeline.selectionAddAtCursor(timeline, project.root) + } + else + { + const trackMin = Math.min(timeline.cursor.laneIndex1, timeline.cursor.laneIndex2) + const trackMax = Math.max(timeline.cursor.laneIndex1, timeline.cursor.laneIndex2) + + const newTrack = (isUp ? trackMin : trackMax) + trackDelta + Timeline.cursorSetTrack(timeline, newTrack, newTrack) + } + } + else + { + const pitchDelta = (keyFast ? 12 : (keyChromatic || isChromatic ? 1 : 0)) * (isUp ? 1 : -1) + const degreeDelta = (keyFast || isChromatic ? 0 : 1) * (isUp ? 1 : -1) + + let playedPreview = false + modifySelectedElems(timeline, project, (elem) => { + if (elem.type == "note") + { + const track = Project.parentTrackFor(project.root, elem.parentId) + const key = Project.keyAt(project.root, track.id, elem.range.start) + const degree = key.octavedDegreeForMidi(elem.midiPitch) + const newDegree = degree + degreeDelta + const newPitch = pitchDelta != 0 ? + elem.midiPitch + pitchDelta : + key.midiForDegree(degreeDelta >= 0 ? Math.floor(newDegree) : Math.ceil(newDegree)) + + if (!playedPreview) + { + playedPreview = true + //Playback.playNotePreview(track.id, newPitch, elem.volumeDb, elem.velocity) + timeline.insertion.nearMidiPitch = newPitch + timeline.insertion.duration = elem.range.duration + } + + return Project.elemModify(elem, { midiPitch: newPitch }) + } + else if (elem.type == "chord") + { + const track = Project.parentTrackFor(project.root, elem.parentId) + const key = Project.keyAt(project.root, track.id, elem.range.start) + const degree = key.octavedDegreeForMidi(elem.chord.rootChroma) + const newDegree = degree + degreeDelta + const newRoot = pitchDelta != 0 ? + elem.chord.rootChroma + pitchDelta : + key.midiForDegree(degreeDelta >= 0 ? Math.floor(newDegree) : Math.ceil(newDegree)) + + const newChord = new Theory.Chord( + newRoot, + elem.chord.kind, elem.chord.inversion, elem.chord.modifiers) + + if (!playedPreview) + { + playedPreview = true + //Playback.playChordPreview(track.id, newChord, 0, 1) + timeline.insertion.duration = elem.range.duration + } + + return Project.elemModify(elem, { chord: newChord }) + } + else + { + return elem + } + }) + + timeline.cursor.visible = false + timeline.needsKeyFinish = true + } } \ No newline at end of file diff --git a/src/timeline/layout.ts b/src/timeline/layout.ts index d6c9d0b..c53b5bf 100644 --- a/src/timeline/layout.ts +++ b/src/timeline/layout.ts @@ -48,6 +48,7 @@ export interface LayoutElementLaneMarkers extends LayoutElementLaneCommon export interface LayoutElementLaneNotes extends LayoutElementLaneCommon { kind: "laneNotes" + tupleIndicators: TupleIndicator[] } @@ -112,6 +113,19 @@ export interface Marker } +export interface TupleIndicator +{ + denominator: number + rect: Rect + range: Range + highestMidiPitch: number + lowestMidiPitch: number +} + + +export const tupleDenominators = [13, 11, 7, 5, 3] + + export class Layout { range: Range @@ -179,6 +193,7 @@ export function layout( 0, timeline.renderRect.w, timeline.renderRect.h - laneChordH - laneMarginY), + tupleIndicators: [], } const laneChords: LayoutElementLaneChords = { diff --git a/src/timeline/layout_chords.ts b/src/timeline/layout_chords.ts index 1ebb82a..add2f92 100644 --- a/src/timeline/layout_chords.ts +++ b/src/timeline/layout_chords.ts @@ -47,7 +47,7 @@ export function layoutLaneChords( }) } - if (rect.w > prefs.timeline.hoverInnerStretchWidth * 2) + if (rect.w > prefs.timeline.hoverInnerStretchWidth * 4) { if (!cutStart) { diff --git a/src/timeline/layout_notes.ts b/src/timeline/layout_notes.ts index a6240a9..89896f6 100644 --- a/src/timeline/layout_notes.ts +++ b/src/timeline/layout_notes.ts @@ -50,7 +50,7 @@ export function layoutLaneNotes( }) } - if (rect.w > prefs.timeline.hoverInnerStretchWidth * 2) + if (rect.w > prefs.timeline.hoverInnerStretchWidth * 4) { if (!cutStart) { @@ -84,6 +84,35 @@ export function layoutLaneNotes( cutEnd, priority: 1, }) + + for (const denom of Timeline.tupleDenominators) + { + if (note.range.duration.denominator % denom !== 0) + continue + + let tuple = laneNotes.tupleIndicators.find(t => + t.denominator === denom && + t.range.end.compare(note.range.start) === 0) + + if (tuple === undefined) + { + tuple = { + denominator: denom, + rect: rect, + range: note.range, + highestMidiPitch: note.midiPitch, + lowestMidiPitch: note.midiPitch, + } + + laneNotes.tupleIndicators.push(tuple) + } + + tuple.highestMidiPitch = Math.max(tuple.highestMidiPitch, note.midiPitch) + tuple.lowestMidiPitch = Math.min(tuple.lowestMidiPitch, note.midiPitch) + tuple.range = tuple.range.merge(note.range) + tuple.rect = tuple.rect.merge(rect) + break + } } } diff --git a/src/timeline/mouse_down.ts b/src/timeline/mouse_down.ts index d845090..01c327a 100644 --- a/src/timeline/mouse_down.ts +++ b/src/timeline/mouse_down.ts @@ -8,13 +8,15 @@ import Range from "../utils/range.ts" export function mouseDown( timeline: Timeline.State, - project: Project.ImmutableRoot, + project: Project.Mutable, prefs: Prefs.Prefs, rightButton: boolean) { if (timeline.mouse.down) return + Timeline.keyHandlePendingFinish(timeline, project) + const prevDownDate = timeline.mouse.downDate timeline.mouse.down = true @@ -43,7 +45,7 @@ export function mouseDown( range: null, timeScroll: timeline.timeScroll, yScroll: timeline.yScroll, - project, + project: project.root, }, xLocked: true, @@ -109,11 +111,11 @@ export function mouseDown( if (!hoverIsSelected) Timeline.selectionToggle( timeline, - project, + project.root, timeline.hover) timeline.drag.origin.range = - Timeline.selectionRange(timeline, project) + Timeline.selectionRange(timeline, project.root) timeline.mouse.action = timeline.hover.action return diff --git a/src/timeline/mouse_up.ts b/src/timeline/mouse_up.ts index d1dd80f..23723fe 100644 --- a/src/timeline/mouse_up.ts +++ b/src/timeline/mouse_up.ts @@ -7,7 +7,7 @@ import Range from "../utils/range.ts" export function mouseUp( timeline: Timeline.State, - project: Project.ImmutableRoot, + project: Project.Mutable, rightButton: boolean) { if (!timeline.mouse.down) @@ -15,4 +15,8 @@ export function mouseUp( timeline.mouse.down = false timeline.mouse.action = Timeline.MouseAction.None + + const origProject = project.root + Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) + return project.root !== origProject } \ No newline at end of file diff --git a/src/timeline/timeline.ts b/src/timeline/timeline.ts index 7c7836a..671bd97 100644 --- a/src/timeline/timeline.ts +++ b/src/timeline/timeline.ts @@ -437,4 +437,101 @@ export function cursorGetLaneIndexMax( return Math.min(timeline.layout.lanes.length - 1, Math.max( timeline.cursor.laneIndex1, timeline.cursor.laneIndex2)) +} + + +export function scrollTimeIntoView( + timeline: Timeline.State, + time: Rational) +{ + const range = visibleTimeRange(timeline) + const marginPixels = 100 + const marginTime = Rational.fromFloat(marginPixels / timeline.timeScale, 10000) + + if (time.compare(range.end.subtract(marginTime)) >= 0) + { + timeline.timeScroll = + time.asFloat() - + (timeline.renderRect.w - marginPixels) / timeline.timeScale + } + else if (time.compare(range.start.add(marginTime)) <= 0) + { + timeline.timeScroll = + time.asFloat() - + marginPixels / timeline.timeScale + } +} + + +export function keyHandlePendingFinish( + timeline: Timeline.State, + project: Project.Mutable) +{ + if (!timeline.needsKeyFinish) + return + + timeline.needsKeyFinish = false + + selectionResolveOverlappingAndDegenerate(timeline, project) +} + + +export function selectionResolveOverlappingAndDegenerate( + timeline: Timeline.State, + project: Project.Mutable) +{ + for (const id of timeline.selection) + { + const selectedElem = project.root.elems.get(id) + if (!selectedElem) + continue + + const list = project.root.lists.get(selectedElem.parentId) + if (!list) + continue + + const absSelectedRange = Project.getAbsoluteRange( + project.root, + selectedElem.parentId, + selectedElem.range) + + if (selectedElem.range.duration.isZero()) + { + if (selectedElem.type === "note" || + selectedElem.type === "chord") + { + const removeElem = Project.elemModify(selectedElem, { parentId: -1 }) + project.root = Project.upsertElement(project.root, removeElem) + } + else + { + for (const elem of list.iterAtPoint(selectedElem.range.start)) + { + if (timeline.selection.has(elem.id)) + continue + + const removeElem = Project.elemModify(elem, { parentId: -1 }) + project.root = Project.upsertElement(project.root, removeElem) + } + } + } + else + { + for (const elem of list.iterAtRange(selectedElem.range)) + { + if (timeline.selection.has(elem.id)) + continue + + if (elem.type === "note" && + selectedElem.type === "note" && + elem.midiPitch !== selectedElem.midiPitch) + continue + + project.root = Project.splitElem( + project.root, + elem, + absSelectedRange) + } + } + } } \ No newline at end of file diff --git a/src/utils/rect.ts b/src/utils/rect.ts index cade3a1..624a353 100644 --- a/src/utils/rect.ts +++ b/src/utils/rect.ts @@ -168,4 +168,14 @@ export default class Rect this.y2 >= other.y && this.y < other.y2 } + + + merge(other: Rect): Rect + { + return Rect.fromVertices( + Math.min(this.x1, other.x1), + Math.min(this.y1, other.y1), + Math.max(this.x2, other.x2), + Math.max(this.y2, other.y2)) + } } \ No newline at end of file From 85f92ef7c0ce059eb1d54ee4a911ea7f09174473 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Sun, 21 Dec 2025 22:46:22 -0300 Subject: [PATCH 05/20] improve lane handling; add key change inspector --- src/inspector/Inspector.tsx | 358 ++++++++++++++++++++++++++ src/main.tsx | 6 +- src/prefs.ts | 4 +- src/project/root.ts | 13 +- src/theory/index.ts | 2 +- src/theory/key.ts | 29 ++- src/theory/scale.ts | 116 +++++++-- src/theory/utils.ts | 10 +- src/timeline/Element.tsx | 16 +- src/timeline/draw.ts | 228 +++++++++------- src/timeline/index.ts | 6 +- src/timeline/key_down.ts | 224 ++++++++++++++++ src/timeline/lane.ts | 86 +++++++ src/timeline/lane_chords.ts | 242 +++++++++++++++++ src/timeline/lane_notes.ts | 457 +++++++++++++++++++++++++++++++++ src/timeline/layout.ts | 103 +++----- src/timeline/layout_chords.ts | 168 ------------ src/timeline/layout_markers.ts | 118 --------- src/timeline/layout_notes.ts | 283 -------------------- src/timeline/mouse_down.ts | 17 +- src/timeline/mouse_move.ts | 22 +- src/timeline/timeline.ts | 182 ++++++++++++- src/utils/canvasUtils.ts | 51 ++++ src/utils/rational.ts | 36 +-- 24 files changed, 1985 insertions(+), 792 deletions(-) create mode 100644 src/inspector/Inspector.tsx create mode 100644 src/timeline/lane.ts create mode 100644 src/timeline/lane_chords.ts create mode 100644 src/timeline/lane_notes.ts delete mode 100644 src/timeline/layout_chords.ts delete mode 100644 src/timeline/layout_markers.ts delete mode 100644 src/timeline/layout_notes.ts create mode 100644 src/utils/canvasUtils.ts diff --git a/src/inspector/Inspector.tsx b/src/inspector/Inspector.tsx new file mode 100644 index 0000000..6281473 --- /dev/null +++ b/src/inspector/Inspector.tsx @@ -0,0 +1,358 @@ +import * as Solid from "solid-js" +import * as Global from "../state.ts" +import * as Project from "../project" +import * as Timeline from "../timeline" +import * as Theory from "../theory" +import Rect from "../utils/rect.ts" +import { styled } from "solid-styled-components" + + +export function Inspector(props: {}) +{ + const selectedIdsRaw = Solid.createMemo(() => { + const timeline = Global.get().timeline + return timeline.selection + }) + + const selectedIds = Solid.createMemo(() => { + const ids = selectedIdsRaw() + return ids + }) + + const firstElem = Solid.createMemo(() => { + if (selectedIds().count() !== 1) + return null + + const project = Global.get().project + + let firstElem = null + for (const id of selectedIds()) + { + firstElem = Project.getElem(project.root, id) + if (firstElem) + break + } + + return firstElem + }) + + const inspectorKind = Solid.createMemo(() => { + const setValue = (elem: Project.Element) => { + const project = Global.get().project + project.root = Project.upsertElement(project.root, elem) + Global.refresh() + } + + const elem = firstElem() + + if (elem?.type === "keyChange") + return + + return + }) + + return
+ { `${selectedIds().count()} selected` }
+ + { inspectorKind() } +
+} + + +export function InspectorInsert(props: { +}) +{ + const makeInsertKeyChange = () => { + const key = Theory.Key.parse("C Major") + + const insert = () => { + const project = Global.get().project + const timeline = Global.get().timeline + const time = timeline.cursor.time1 + const id = project.root.nextId + const keyCh = Project.makeKeyChange(project.root.keyChangeTrackId, time, key) + project.root = Project.upsertElement(project.root, keyCh) + Timeline.selectionClear(timeline) + Timeline.selectionAdd(timeline, id) + Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) + Global.refresh() + } + + return + } + + + return <> + { makeInsertKeyChange() } + +} + + +export function InspectorKeyChange(props: { + value: Project.KeyChange, + setValue: (newValue: Project.KeyChange) => void, +}) +{ + const tonic = props.value.key.tonic + const scale = props.value.key.scale + + const circleOfFifthsOffset = scale.metadata?.circleOfFifthsOffset ?? 0 + + + const makeTonicButton = (circleOfFifthsIndex: number) => { + const letter = Theory.Utils.circleOfFifthsToLetter(circleOfFifthsIndex + circleOfFifthsOffset) + const accidental = Theory.Utils.circleOfFifthsToAccidental(circleOfFifthsIndex + circleOfFifthsOffset) + const letterStr = Theory.Utils.letterToStr(letter) + const accidentalStr = Theory.Utils.accidentalToStr(accidental) + const pitchName = new Theory.PitchName(letter, accidental) + const key = new Theory.Key(pitchName, props.value.key.scale) + + const apply = () => { + props.setValue({...props.value, key }) + } + + const angleArc = Math.PI * 2 / 12 + const angle1 = (circleOfFifthsIndex - 0.5) * angleArc + const angle2 = (circleOfFifthsIndex + 0.5) * angleArc + const trigX1 = Math.sin(angle1) + const trigX2 = Math.sin(angle2) + const trigY1 = -Math.cos(angle1) + const trigY2 = -Math.cos(angle2) + const radius1 = 50 + const radius2 = 100 + const angleMargin1 = 0.025 + const angleMargin2 = angleMargin1 * (radius1 / radius2) + const subdiv = 4 + + let path = "" + for (let i = 0; i <= subdiv; i++) + { + const t = i / subdiv + const angle = angle1 + (angle2 - angle1) * t + (angleMargin1 - angleMargin1 * 2 * t) + path += `${ i == 0 ? "M" : "L"} ${Math.sin(angle) * radius1} ${-Math.cos(angle) * radius1} ` + } + for (let i = 0; i <= subdiv; i++) + { + const t = 1 - i / subdiv + const angle = angle1 + (angle2 - angle1) * t + (angleMargin2 - angleMargin2 * 2 * t) + path += `L ${Math.sin(angle) * radius2} ${-Math.cos(angle) * radius2} ` + } + path += "Z" + + return + + + { letterStr }{ accidentalStr } + + + } + + + const applyScale = (scaleId: string) => { + const scale = Theory.Scale.fromId(scaleId) + const key = new Theory.Key(props.value.key.tonic, scale) + props.setValue({...props.value, key }) + } + + + const makeScaleOption = (scaleMeta: Theory.ScaleMetadata) => { + return +
+ { scaleMeta.names[0] } + { " " } +
+ + { (chroma, i) => { + const degree = i() + const chromaCMajor = Theory.Utils.degreeToChromaInCMajor(degree) + const accidental = chroma - chromaCMajor + const accidentalStr = Theory.Utils.accidentalToStr(accidental) + + return
0 ? "red" : + accidental < 0 ? "blue" : + undefined, + }}> + { `${accidentalStr}${(degree + 1).toString()} ` } +
+ }} +
+
+
+ } + + + const makeScaleOption2 = (scaleMeta: Theory.ScaleMetadata) => { + const isSelected = scaleMeta.id === scale.id + let button: HTMLButtonElement | undefined = undefined + + Solid.createEffect(() => { + if (isSelected && button) + (button as HTMLButtonElement).scrollIntoView({ behavior: "instant", block: "center" }) + }) + + return applyScale(scaleMeta.id) } + > + { scaleMeta.names[0] } + + + { (chroma, i) => { + const degree = i() + const chromaCMajor = Theory.Utils.degreeToChromaInCMajor(degree) + const accidental = chroma - chromaCMajor + const accidentalStr = Theory.Utils.accidentalToStr(accidental) + + return
0 ? "#f88" : + accidental < 0 ? "#88f" : + undefined, + }}> + { `${accidentalStr}${(degree + 1).toString()} ` } +
+ }} +
+
+
+ } + + + return <> +

Key Change

+ + + + + + { (index, i) => makeTonicButton(index) } + + + + + + { (scaleMeta, i) => makeScaleOption2(scaleMeta) } + + + + {/* applyScale(ev.target.value) } + > + + + { (scaleMeta, i) => makeScaleOption(scaleMeta) } + + */} + + + +} + + +const Layout = styled.div` + display: grid; + grid-template: auto / auto auto; + justify-content: center; + column-gap: 1em; +` + + +const CircleOfFifthsPath = styled.path<{ + $selected: boolean, +}>` + cursor: pointer; + fill: #444; + + &:hover { + fill: #666; + } + + ${ props => props.$selected ? "fill: #06a;" : "" } +` + + +const ScaleList = styled.div` + width: 20em; + height: 15em; + overflow-x: hidden; + overflow-y: auto; + border-radius: 0.25em; +` + + +const ScaleButton = styled.div<{ + $selected: boolean, +}>` + display: grid; + grid-template: auto auto / auto; + justify-items: start; + justify-content: start; + user-select: none; + cursor: pointer; + + width: 100%; + margin: 0.25em; + padding: 0.25em; + border-radius: 0.25em; + background-color: #444; + + &:hover { + background-color: #666; + } + + ${ props => props.$selected ? "background-color: #06a;" : "" } +` + + +const StyledSelect = styled.select` + /*appearance: base-select; + + &::picker(select) { + appearance: base-select; + }*/ +` + + +const OptionScale = styled.option` + margin-top: 0.5em; + margin-bottom: 0.5em; +` \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index a8f7012..e4a5a1a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -3,6 +3,7 @@ import * as SolidWeb from "solid-js/web" import { styled } from "solid-styled-components" import * as State from "./state.ts" import * as Timeline from "./timeline" +import { Inspector } from "./inspector/Inspector.tsx" function App() @@ -15,18 +16,21 @@ function App()
+ } const AppRoot = styled.div` display: grid; - grid-template: auto 1fr / 1fr; + grid-template: auto 1fr 1fr / 1fr; margin: auto; width: 100%; height: 100%; min-height: 0; background-color: #101215; + color: #fff; + font-family: Verdana; ` diff --git a/src/prefs.ts b/src/prefs.ts index 3f46ff7..8ccc2c1 100644 --- a/src/prefs.ts +++ b/src/prefs.ts @@ -108,8 +108,8 @@ export function makeNew(): Prefs mouseEdgeScrollThreshold: 10, mouseEdgeScrollSpeed: 1, - hoverOuterStretchWidth: 8, - hoverInnerStretchWidth: 8, + hoverOuterStretchWidth: 16, + hoverInnerStretchWidth: 12, } } } \ No newline at end of file diff --git a/src/project/root.ts b/src/project/root.ts index ee8fba5..7c1d9a2 100644 --- a/src/project/root.ts +++ b/src/project/root.ts @@ -286,7 +286,16 @@ export function withRefreshedRange(project: ImmutableRoot): ImmutableRoot } -export function getElem( +export function getElem( + project: ImmutableRoot, + id: Project.ID) + : Project.Element | undefined +{ + return project.elems.get(id) +} + + +/*export function getElem( project: ImmutableRoot, id: Project.ID, type: T) @@ -297,7 +306,7 @@ export function getElem( return null return elem as Extract -} +}*/ export function getTrack( diff --git a/src/theory/index.ts b/src/theory/index.ts index b02f255..b81a51b 100644 --- a/src/theory/index.ts +++ b/src/theory/index.ts @@ -1,6 +1,6 @@ export { default as Pitch } from "./pitch.ts" export { default as PitchName } from "./pitchName.ts" -export { default as Scale } from "./scale.ts" +export { default as Scale, ScaleMetadata } from "./scale.ts" export { default as Key } from "./key.ts" export { default as Meter } from "./meter.ts" export { default as Chord } from "./chord.ts" diff --git a/src/theory/key.ts b/src/theory/key.ts index 392f5b8..034e6e0 100644 --- a/src/theory/key.ts +++ b/src/theory/key.ts @@ -38,6 +38,31 @@ export default class Key nextChroma += 1 } } + + /*let firstFrac: number | undefined = undefined + for (let c = 0; c <= this.scale.chromas.length; c++) + { + if (c >= this.scale.chromas.length || + (this._chromaToDegree[c] % 1) === 0) + { + if (firstFrac !== undefined) + { + const base = Math.floor(this._chromaToDegree[firstFrac]) + for (let d = firstFrac; d < c; d++) + { + const frac = (d - firstFrac + 1) / (c - d + 1) + this._chromaToDegree[d] = base + frac + } + + firstFrac = undefined + } + + continue + } + + if (firstFrac === undefined) + firstFrac = c + }*/ } @@ -55,8 +80,8 @@ export default class Key if (separator < 1) throw "invalid key string" - const tonicStr = str.substr(0, separator) - const scaleStr = str.substr(separator) + const tonicStr = str.substring(0, separator) + const scaleStr = str.substring(separator) const tonic = PitchName.parse(tonicStr) const scale = Scale.parse(scaleStr) diff --git a/src/theory/scale.ts b/src/theory/scale.ts index 9f942b7..b0bedf3 100644 --- a/src/theory/scale.ts +++ b/src/theory/scale.ts @@ -1,26 +1,90 @@ import PitchName from "./pitchName.ts" -interface ScaleMetadata +export interface ScaleMetadata { - chromas: number[] - mode: number id: string names: string[] + chromas: number[] + mode: number + circleOfFifthsOffset?: number } -export const knownScales: ScaleMetadata[] = -[ - { chromas: [0, 2, 4, 5, 7, 9, 11], mode: 0, id: "maj", names: ["Major", "Ionian"] }, - { chromas: [0, 2, 3, 5, 7, 9, 10], mode: 1, id: "dor", names: ["Dorian"] }, - { chromas: [0, 1, 3, 5, 7, 8, 10], mode: 2, id: "phr", names: ["Phrygian"] }, - { chromas: [0, 2, 4, 6, 7, 9, 11], mode: 3, id: "lyd", names: ["Lydian"] }, - { chromas: [0, 2, 4, 5, 7, 9, 10], mode: 4, id: "mix", names: ["Mixolydian"] }, - { chromas: [0, 2, 3, 5, 7, 8, 10], mode: 5, id: "min", names: ["Natural Minor", "Minor", "Aeolian"] }, - { chromas: [0, 1, 3, 5, 6, 8, 10], mode: 6, id: "loc", names: ["Locrian"] }, - - { chromas: [0, 1, 4, 5, 7, 8, 11], mode: 0, id: "dharmaj", names: ["Double Harmonic Major"] }, +export const knownScales: ScaleMetadata[] = [ + { + id: "maj", + names: ["Major", "Ionian"], + chromas: [0, 2, 4, 5, 7, 9, 11], + mode: 0, + circleOfFifthsOffset: 0, + }, + { + id: "dor", + names: ["Dorian"], + chromas: [0, 2, 3, 5, 7, 9, 10], + mode: 1, + circleOfFifthsOffset: 2, + }, + { + id: "phr", + names: ["Phrygian"], + chromas: [0, 1, 3, 5, 7, 8, 10], + mode: 2, + circleOfFifthsOffset: 4, + }, + { + id: "lyd", + names: ["Lydian"], + chromas: [0, 2, 4, 6, 7, 9, 11], + mode: 3, + circleOfFifthsOffset: -1, + }, + { + id: "mix", + names: ["Mixolydian"], + chromas: [0, 2, 4, 5, 7, 9, 10], + mode: 4, + circleOfFifthsOffset: 1, + }, + { + id: "min", + names: ["Natural Minor", "Minor", "Aeolian"], + chromas: [0, 2, 3, 5, 7, 8, 10], + mode: 5, + circleOfFifthsOffset: 3, + }, + { + id: "loc", + names: ["Locrian"], + chromas: [0, 1, 3, 5, 6, 8, 10], + mode: 6, + circleOfFifthsOffset: 5, + }, + + { + id: "phrdom", + names: ["Phrygian Dominant"], + chromas: [0, 1, 4, 5, 7, 8, 10], + mode: 2, + circleOfFifthsOffset: 4, + }, + + { + id: "dharmaj", + names: ["Double Harmonic Major"], + chromas: [0, 1, 4, 5, 7, 8, 11], + mode: 0, + circleOfFifthsOffset: 0, + }, + + { + id: "whole", + names: ["Whole-tone"], + chromas: [0, 2, 4, 6, 8, 10], + mode: 0, + circleOfFifthsOffset: 0, + }, ] @@ -29,7 +93,7 @@ export default class Scale static list = knownScales chromas: number[] - metadata: ScaleMetadata | null | undefined + metadata: ScaleMetadata | undefined constructor(chromas: number[]) @@ -40,8 +104,8 @@ export default class Scale this.chromas = chromas this.metadata = knownScales.find(s => - s.chromas.length == this.chromas.length && - s.chromas.every((p, index) => p == this.chromas[index])) + s.chromas.length === this.chromas.length && + s.chromas.every((p, index) => p === this.chromas[index])) } @@ -53,7 +117,11 @@ export default class Scale static fromId(id: string): Scale { - return new Scale(knownScales.find(s => s.id === id)!.chromas) + const meta = knownScales.find(s => s.id === id) + if (!meta) + throw "scale id not found" + + return new Scale(meta.chromas) } @@ -61,7 +129,7 @@ export default class Scale { str = str.toLowerCase().trim() - const knownScale = knownScales.find(s => s.names.some(n => n.toLowerCase() == str)) + const knownScale = knownScales.find(s => s.names.some(n => n.toLowerCase() === str)) if (!knownScale) throw "no known scale with given name" @@ -69,19 +137,19 @@ export default class Scale } - get id(): string | null + get id(): string | undefined { if (!this.metadata) - return null + return undefined return this.metadata.id } - get name(): string | null + get name(): string | undefined { if (!this.metadata) - return null + return undefined return this.metadata.names[0] } @@ -89,7 +157,7 @@ export default class Scale get alterationsFromMajor(): number[] { - if (this.chromas.length != 7) + if (this.chromas.length !== 7) throw "not a seven-note scale" return this.chromas.map((pitch, i) => pitch - knownScales[0].chromas[i]) diff --git a/src/theory/utils.ts b/src/theory/utils.ts index f7e289a..a17d370 100644 --- a/src/theory/utils.ts +++ b/src/theory/utils.ts @@ -7,6 +7,8 @@ export default class Utils static midiMiddleC = 60 + static degreeToChromaInCMajor = (degree: number): number => [0, 2, 4, 5, 7, 9, 11][degree] + static chromaToLetter = (chroma: number): number => [0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][chroma] static chromaToAccidental = (chroma: number): number => [0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0][chroma] static chromaToDegreeInCMajor = (chroma: number): number => [0, 0.5, 1, 1.5, 2, 3, 3.5, 4, 4.5, 5, 5.5, 6][chroma] @@ -19,6 +21,12 @@ export default class Utils return map[str] } + static circleOfFifthsToLetter = (index: number): number => + [0, 4, 1, 5, 2, 6, 3][Utils.mod(index, 7)] + + static circleOfFifthsToAccidental = (index: number): number => + Math.floor((index + 1) / 7) + static degreeToRomanStr = (degree: number): string => ["I", "II", "III", "IV", "V", "VI", "VII"][degree] @@ -29,7 +37,7 @@ export default class Utils ["#400", "#420", "#430", "#030", "#004", "#204", "#404"][degree] - static accidentalToStr(accidental: number, useUnicode: boolean = false): string + static accidentalToStr(accidental: number, useUnicode: boolean = true): string { if (accidental < 0) return (useUnicode ? "\u{266d}" : "b").repeat(-accidental) diff --git a/src/timeline/Element.tsx b/src/timeline/Element.tsx index 275f065..1e76463 100644 --- a/src/timeline/Element.tsx +++ b/src/timeline/Element.tsx @@ -21,7 +21,7 @@ export function Element(props: {}) return
@@ -41,6 +41,12 @@ function canvasResize( const y = Math.floor(domRect.y) const w = Math.floor(domRect.width * pixelRatio) const h = Math.floor(domRect.height * pixelRatio) + + if (canvas.width === w && + canvas.height === h && + timeline.renderRect.w === w && + timeline.renderRect.h === h) + return canvas.style.width = domRect.width + "px" canvas.style.height = domRect.height + "px" @@ -110,7 +116,10 @@ function registerHandlers( Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) if (Timeline.mouseDrag(timeline, project)) + { Timeline.layout(timeline, project.root, prefs) + Global.refresh() + } Timeline.draw(timeline, prefs, ctx) setCursor() @@ -127,6 +136,7 @@ function registerHandlers( Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) Timeline.mouseDown(timeline, project, prefs, ev.button !== 0) Timeline.draw(timeline, prefs, ctx) + Global.refresh() setCursor() } @@ -144,6 +154,7 @@ function registerHandlers( Timeline.layout(timeline, project.root, prefs) Timeline.draw(timeline, prefs, ctx) + Global.refresh() setCursor() } @@ -157,6 +168,7 @@ function registerHandlers( Timeline.mouseWheel(timeline, ev.deltaX, ev.deltaY) Timeline.layout(timeline, project.root, prefs) Timeline.draw(timeline, prefs, ctx) + Global.refresh() } const onKeyDown = (ev: KeyboardEvent) => { @@ -167,12 +179,14 @@ function registerHandlers( Timeline.keyDown(timeline, project, prefs, ev.key.toLowerCase()) Timeline.layout(timeline, project.root, prefs) Timeline.draw(timeline, prefs, ctx) + Global.refresh() } const onKeyUp = (ev: KeyboardEvent) => { const timeline = Global.get().timeline Timeline.keyUp(timeline, ev.key.toLowerCase()) + Global.refresh() } const preventDefault = (ev: MouseEvent) => { diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index 5f01798..8d7198a 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -3,6 +3,7 @@ import * as Timeline from "./index.ts" import * as Prefs from "../prefs.ts" import * as Theory from "../theory" import Rational from "../utils/rational.ts" +import * as CanvasUtils from "../utils/canvasUtils.ts" export function draw( @@ -16,7 +17,8 @@ export function draw( ctx.fillStyle = "#fff" ctx.clearRect(0, 0, timeline.renderRect.w, timeline.renderRect.h) - drawElements(timeline, prefs, ctx, timeline.layout.elements) + for (const lane of timeline.layout.lanes) + drawLane(ctx, timeline, prefs, lane) if (timeline.cursor.visible) { @@ -30,6 +32,90 @@ export function draw( } +function drawLane( + ctx: CanvasRenderingContext2D, + timeline: Timeline.State, + prefs: Prefs.Prefs, + lane: Timeline.Lane) +{ + if (lane instanceof Timeline.LaneChords) + { + ctx.save() + ctx.beginPath() + ctx.rect( + lane.rect.x, + lane.rect.y, + lane.rect.w, + lane.rect.h) + ctx.clip() + + drawLaneBkgSolid(timeline, prefs, ctx, lane) + drawLaneBkgMeasures(timeline, prefs, ctx, lane, false) + drawLaneBkgMeasures(timeline, prefs, ctx, lane, true) + drawCursorBkg(timeline, prefs, ctx, lane) + + ctx.save() + ctx.translate(lane.rect.x, lane.rect.y) + drawElements(timeline, prefs, ctx, lane.elements) + ctx.restore() + + drawLaneFrgOutline(timeline, prefs, ctx, lane) + + ctx.restore() + } + + else if (lane instanceof Timeline.LaneNotes) + { + ctx.save() + ctx.beginPath() + ctx.rect( + lane.rect.x, + lane.rect.y, + lane.rect.w, + lane.rect.h) + ctx.clip() + + drawLaneBkgSolid(timeline, prefs, ctx, lane) + drawLaneBkgOctaves(timeline, prefs, ctx, lane, false) + drawLaneBkgMeasures(timeline, prefs, ctx, lane, false) + drawLaneBkgOctaves(timeline, prefs, ctx, lane, true) + drawLaneBkgMeasures(timeline, prefs, ctx, lane, true) + drawCursorBkg(timeline, prefs, ctx, lane) + + ctx.save() + ctx.translate(lane.rect.x, lane.rect.y) + drawElements(timeline, prefs, ctx, lane.elements) + + for (const tuple of lane.tupleIndicators) + { + ctx.strokeStyle = prefs.timeline.octaveLabelColor + ctx.lineWidth = 2 + ctx.beginPath() + ctx.moveTo(tuple.rect.x, tuple.rect.y2 + 2) + ctx.lineTo(tuple.rect.x, tuple.rect.y2 + 5) + ctx.lineTo(tuple.rect.x2, tuple.rect.y2 + 5) + ctx.lineTo(tuple.rect.x2, tuple.rect.y2 + 2) + ctx.stroke() + + ctx.fillStyle = prefs.timeline.octaveLabelColor + ctx.font = Math.floor(timeline.noteRowH - 4) + "px system-ui" + ctx.textAlign = "center" + ctx.textBaseline = "top" + ctx.fillText( + tuple.denominator.toString(), + tuple.rect.xCenter, + tuple.rect.y2 + 8) + } + + ctx.restore() + + drawLaneFrgOutline(timeline, prefs, ctx, lane) + + ctx.restore() + } +} + + function drawElements( timeline: Timeline.State, prefs: Prefs.Prefs, @@ -55,78 +141,7 @@ function drawElements( for (const element of elements) { - if (element.kind === "laneChords") - { - ctx.save() - ctx.beginPath() - ctx.rect( - element.rect.x, - element.rect.y, - element.rect.w, - element.rect.h) - ctx.clip() - - drawLaneBkgSolid(timeline, prefs, ctx, element) - drawLaneBkgMeasures(timeline, prefs, ctx, element, false) - drawLaneBkgMeasures(timeline, prefs, ctx, element, true) - drawCursorBkg(timeline, prefs, ctx, element) - - if (element.subElements) - drawElements(timeline, prefs, ctx, element.subElements) - - drawLaneFrgOutline(timeline, prefs, ctx, element) - - ctx.restore() - } - - else if (element.kind === "laneNotes") - { - ctx.save() - ctx.beginPath() - ctx.rect( - element.rect.x, - element.rect.y, - element.rect.w, - element.rect.h) - ctx.clip() - - drawLaneBkgSolid(timeline, prefs, ctx, element) - drawLaneBkgOctaves(timeline, prefs, ctx, element, false) - drawLaneBkgMeasures(timeline, prefs, ctx, element, false) - drawLaneBkgOctaves(timeline, prefs, ctx, element, true) - drawLaneBkgMeasures(timeline, prefs, ctx, element, true) - drawCursorBkg(timeline, prefs, ctx, element) - - if (element.subElements) - drawElements(timeline, prefs, ctx, element.subElements) - - for (const tuple of element.tupleIndicators) - { - ctx.strokeStyle = prefs.timeline.octaveLabelColor - ctx.lineWidth = 2 - ctx.beginPath() - ctx.moveTo(tuple.rect.x, tuple.rect.y2 + 2) - ctx.lineTo(tuple.rect.x, tuple.rect.y2 + 5) - ctx.lineTo(tuple.rect.x2, tuple.rect.y2 + 5) - ctx.lineTo(tuple.rect.x2, tuple.rect.y2 + 2) - ctx.stroke() - - ctx.fillStyle = prefs.timeline.octaveLabelColor - ctx.font = Math.floor(timeline.noteRowH - 4) + "px system-ui" - ctx.textAlign = "center" - ctx.textBaseline = "top" - ctx.fillText( - tuple.denominator.toString(), - tuple.rect.xCenter, - tuple.rect.y2 + 8) - } - - drawLaneFrgOutline(timeline, prefs, ctx, element) - - ctx.restore() - } - - else if (element.kind === "note") + if (element.kind === "note") { ctx.save() ctx.beginPath() @@ -141,7 +156,14 @@ function drawElements( const x1 = element.rect.x + (element.cutStart ? -16 : 0) const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) - ctx.fillStyle = "#f00" + const key = element.key + const mode = key.scale.metadata!.mode + const fillStyle = CanvasUtils.fillStyleForDegree( + ctx, + key.degreeForMidi(element.note.midiPitch) + mode, + false) + + ctx.fillStyle = fillStyle ctx.beginPath() ctx.roundRect( x1, @@ -183,7 +205,14 @@ function drawElements( const x1 = element.rect.x + (element.cutStart ? -16 : 0) const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) - ctx.fillStyle = "#f00" + const key = element.key + const mode = key.scale.metadata!.mode + const fillStyle = CanvasUtils.fillStyleForDegree( + ctx, + key.degreeForMidi(element.chord.chord.rootChroma) + mode, + false) + + ctx.fillStyle = fillStyle ctx.beginPath() ctx.roundRect( x1, @@ -257,9 +286,24 @@ function drawMarker( element.meterCh ? prefs.timeline.meterChangeColor : "#000" + const makeKeyChangeDifferenceText = (chromaPrev: number | undefined, chromaNext: number) => { + if (chromaPrev === undefined) + return "" + + const diff1 = Theory.Utils.mod(chromaNext - chromaPrev, 12) + const diff2 = diff1 - 12 + const diff = Math.abs(diff1) < Math.abs(diff2) ? diff1 : diff2 + return ` (${diff >= 0 ? "+" : ""}${diff})` + } + const text = - element.keyCh ? element.keyCh.key.toString() : - element.meterCh ? element.meterCh.meter.toString() : + element.keyCh ? + element.keyCh.key.toString() + + makeKeyChangeDifferenceText( + element.keyChPrev?.key.tonic.chroma, + element.keyCh.key.tonic.chroma) : + element.meterCh ? + element.meterCh.meter.toString() : "" ctx.fillStyle = color @@ -308,7 +352,7 @@ function drawMarker( export function drawLaneBkgCenterStroke( timeline: Timeline.State, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutElementLaneMarkers) + lane: Timeline.Lane) { const yCenter = Math.floor(lane.rect.y + lane.rect.h / 2) + 0.5 ctx.strokeStyle = "#fff" @@ -324,7 +368,7 @@ export function drawLaneBkgSolid( timeline: Timeline.State, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutLane) + lane: Timeline.Lane) { if (timeline.layout.measures.length > 100) { @@ -360,7 +404,7 @@ export function drawLaneFrgOutline( timeline: Timeline.State, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutLane) + lane: Timeline.Lane) { ctx.strokeStyle = prefs.timeline.measureColor ctx.lineWidth = 1 @@ -377,7 +421,7 @@ export function drawLaneBkgMeasures( timeline: Timeline.State, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutLane, + lane: Timeline.Lane, mainLinePass: boolean) { // Render alternating measure background and sub-measure dividers. @@ -447,7 +491,7 @@ export function drawLaneBkgOctaves( timeline: Timeline.State, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutElementLaneNotes, + lane: Timeline.Lane, mainLinePass: boolean) { const rowAtTop = Timeline.rowAtY(timeline, lane, lane.rect.y) @@ -463,13 +507,21 @@ export function drawLaneBkgOctaves( for (const keyRegion of timeline.layout.keyRegions) { - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(keyRegion.keyCh1.key.tonic.chroma) + const key = keyRegion.keyCh1.key + const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) + const scaleLength = key.scale.chromas.length let needsOctaveLabels = true let drewOctaveLabels = false for (const measure of timeline.layout.measures) { + if (measure.time1.compare(keyRegion.keyCh2.range.start) >= 0) + continue + + if (measure.time2.compare(keyRegion.keyCh1.range.start) <= 0) + continue + const time1 = measure.time1.max(keyRegion.keyCh1.range.start) const time2 = measure.time2.min(keyRegion.keyCh2.range.start) @@ -479,14 +531,14 @@ export function drawLaneBkgOctaves( for (let i = octaveAtBottom; i <= octaveAtTop; i++) { const y = Math.floor( - Timeline.yForRow(timeline, lane, tonicRowOffset + i * 7) + timeline.noteRowH) + Timeline.yForRow(timeline, lane, tonicRowOffset + i * scaleLength) + timeline.noteRowH) if (mainLinePass) { const labelX = Math.max(x1 + 5, 5) if (needsOctaveLabels && labelX + 30 < x2) { - ctx.fillText(keyRegion.keyCh1.key.tonic.str + (i + 5).toString(), labelX, y - 1) + ctx.fillText(key.tonic.str + (i + 5).toString(), labelX, y - 1) drewOctaveLabels = true } @@ -503,10 +555,10 @@ export function drawLaneBkgOctaves( { ctx.strokeStyle = prefs.timeline.submeasureColor ctx.beginPath() - for (let j = 1; j < 7; j += 1) + for (let j = 1; j < scaleLength; j += 1) { const ySuboctave = Math.floor( - Timeline.yForRow(timeline, lane, tonicRowOffset + i * 7 + j) + timeline.noteRowH) + Timeline.yForRow(timeline, lane, tonicRowOffset + i * scaleLength + j) + timeline.noteRowH) ctx.moveTo(x1, ySuboctave) ctx.lineTo(x2, ySuboctave) @@ -571,7 +623,7 @@ function drawCursorBkg( timeline: Timeline.State, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, - lane: Timeline.LayoutLane) + lane: Timeline.Lane) { if (!timeline.cursor.visible) return diff --git a/src/timeline/index.ts b/src/timeline/index.ts index af35fad..97c3c87 100644 --- a/src/timeline/index.ts +++ b/src/timeline/index.ts @@ -1,9 +1,9 @@ export * from "./Element.tsx" export * from "./timeline.ts" export * from "./layout.ts" -export * from "./layout_markers.ts" -export * from "./layout_notes.ts" -export * from "./layout_chords.ts" +export * from "./lane.ts" +export * from "./lane_notes.ts" +export * from "./lane_chords.ts" export * from "./mouse_move.ts" export * from "./mouse_down.ts" export * from "./mouse_drag.ts" diff --git a/src/timeline/key_down.ts b/src/timeline/key_down.ts index 766cef4..64742dd 100644 --- a/src/timeline/key_down.ts +++ b/src/timeline/key_down.ts @@ -16,6 +16,30 @@ export function keyDown( switch (key) { + case "escape": + { + handleEscape(timeline, project.root) + break + } + + case "enter": + { + handleEnter(timeline, project) + break + } + + case "delete": + { + handleDelete(timeline, project) + break + } + + case "backspace": + { + handleBackspace(timeline, project) + break + } + case "arrowright": case "arrowleft": { @@ -29,6 +53,59 @@ export function keyDown( handleUpDown(timeline, project, prefs, key === "arrowup", false) break } + + case ".": + case ">": + case ",": + case "<": + { + handleUpDown(timeline, project, prefs, key === "." || key === ">", true) + break + } + + case "1": + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + { + const degree = key.charCodeAt(0) - "1".charCodeAt(0) + handleInsertByDegree(timeline, project, prefs, degree) + break + } + + case "h": + { + handleLengthChange(timeline, project, prefs, 0) + break + } + + case "j": + { + handleLengthChange(timeline, project, prefs, 1) + break + } + + case "k": + { + handleLengthChange(timeline, project, prefs, 2) + break + } + + case "l": + { + handleLengthChange(timeline, project, prefs, 3) + break + } + + case ";": + case ":": + { + handleLengthChange(timeline, project, prefs, 4) + break + } } } @@ -55,6 +132,95 @@ function modifySelectedElems( } +function handleEscape( + timeline: Timeline.State, + project: Project.ImmutableRoot) +{ + /*if (Playback.global.playing) + { + Playback.setStartTime(Project.global.project.range.start) + Playback.setPlaying(true) + } + else*/ + { + Timeline.rewind(timeline, project) + } +} + + +function handleEnter( + timeline: Timeline.State, + project: Project.Mutable) +{ + if (timeline.cursor.visible && timeline.selection.size != 0) + { + timeline.cursor.visible = false + return + } + + timeline.cursor.visible = true + + const range = Timeline.selectionRange(timeline, project.root) + if (range) + { + Timeline.cursorSetTime(timeline, range.end, range.end) + //Timeline.cursorSetTrack(state, trackIndex, trackIndex) + Timeline.scrollTimeIntoView(timeline, range.end) + } + + Timeline.keyHandlePendingFinish(timeline, project) + Timeline.selectionClear(timeline) +} + + +function handleDelete( + state: Timeline.State, + project: Project.Mutable) +{ + Timeline.deleteElems(state, project, state.selection) +} + + +function handleBackspace( + state: Timeline.State, + project: Project.Mutable) +{ + if (!state.cursor.visible) + { + Timeline.deleteElems(state, project, state.selection) + return + } + + const lane1 = Math.min(state.cursor.laneIndex1, state.cursor.laneIndex2) + const lane2 = Math.max(state.cursor.laneIndex1, state.cursor.laneIndex2) + + if (state.cursor.time1.compare(state.cursor.time2) === 0) + { + const time = state.cursor.time1.min(state.cursor.time2) + const prevAnchor = Timeline.findPreviousAnchor(state, project.root, time, lane1, lane2) + const range = new Range(prevAnchor, time, false, false) + Timeline.deleteRange(state, project, range, lane1, lane2) + + state.cursor.visible = true + Timeline.cursorSetTime(state, prevAnchor, prevAnchor) + Timeline.scrollTimeIntoView(state, prevAnchor) + } + else + { + const time1 = state.cursor.time1.min(state.cursor.time2) + const time2 = state.cursor.time1.max(state.cursor.time2) + const range = new Range(time1, time2, false, false) + Timeline.deleteRange(state, project, range, lane1, lane2) + + state.cursor.visible = true + Timeline.cursorSetTime(state, time1, time1) + Timeline.scrollTimeIntoView(state, time1) + } + + project.root = Project.withRefreshedRange(project.root) +} + + function handleLeftRight( timeline: Timeline.State, project: Project.Mutable, @@ -270,4 +436,62 @@ function handleUpDown( timeline.cursor.visible = false timeline.needsKeyFinish = true } +} + + +function handleInsertByDegree( + timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, + degree: number) +{ + const time = timeline.cursor.time1.min(timeline.cursor.time2) + const lane = timeline.layout.lanes[timeline.cursor.laneIndex1] + lane.insertByDegree(timeline, project, prefs, time, degree) +} + + +function handleLengthChange( + timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, + lengthIndex: number) +{ + const lengths = [ + new Rational(1, 16), + new Rational(1, 8), + new Rational(1, 4), + new Rational(1, 2), + new Rational(1, 1), + ] + + if (lengthIndex < 0 || + lengthIndex >= lengths.length) + return + + const length = lengths[lengthIndex] + + modifySelectedElems(timeline, project, (elem) => { + if (elem.type === "note" || + elem.type === "chord") + { + timeline.insertion.duration = length + + const newRange = Range.fromStartDuration(elem.range.start, length) + return Project.elemModify(elem, { range: newRange }) + } + else + return elem + }) + + const range = + Timeline.selectionRange(timeline, project.root) || + new Range(new Rational(0), new Rational(0)) + + const newTime = range.end + timeline.cursor.visible = false + Timeline.cursorSetTime(timeline, newTime, newTime) + Timeline.scrollTimeIntoView(timeline, newTime) + + timeline.needsKeyFinish = true } \ No newline at end of file diff --git a/src/timeline/lane.ts b/src/timeline/lane.ts new file mode 100644 index 0000000..a9f0906 --- /dev/null +++ b/src/timeline/lane.ts @@ -0,0 +1,86 @@ +import * as Project from "../project" +import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" +import * as Theory from "../theory/index.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" +import Rational from "../utils/rational.ts" + + +export class Lane +{ + rect: Rect = Rect.fromVertices(0, 0, 0, 0) + + laneIndex: number = -1 + elements: Timeline.LayoutElement[] = [] + + + constructor() + { + + } + + + add(elem: Timeline.LayoutElement) + { + this.elements.push(elem) + } + + + refreshLayout( + timeline: Timeline.State, + project: Project.ImmutableRoot, + prefs: Prefs.Prefs) + { + + } + + + *iterElementsAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range, + verticalRegion?: { y1: number, y2: number }) + : Generator + { + + } + + + findPreviousAnchor( + timeline: Timeline.State, + project: Project.ImmutableRoot, + time: Rational) + : Rational | null + { + return null + } + + + deleteRange( + timeline: Timeline.State, + project: Project.Mutable, + range: Range) + { + + } + + + insertByDegree( + timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, + time: Rational, + degree: number) + { + + } + + + rowAtY( + timeline: Timeline.State, + y: number) + { + return 0 + } +} \ No newline at end of file diff --git a/src/timeline/lane_chords.ts b/src/timeline/lane_chords.ts new file mode 100644 index 0000000..e5b8586 --- /dev/null +++ b/src/timeline/lane_chords.ts @@ -0,0 +1,242 @@ +import * as Project from "../project" +import * as Theory from "../theory" +import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" +import Rational from "../utils/rational.ts" + + +export class LaneChords extends Timeline.Lane +{ + refreshLayout( + timeline: Timeline.State, + project: Project.ImmutableRoot, + prefs: Prefs.Prefs) + { + this.elements = [] + + for (const [chord, keyChPair] of iterChordsAndKeyChanges(timeline, project)) + { + const key = keyChPair.keyCh1.key + + const [rect, cutStart, cutEnd] = rectForChord( + timeline, + this, + chord.range, + keyChPair.x1, + keyChPair.x2) + + if (!cutStart) + { + this.add({ + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rect.withX1(rect.x1 - prefs.timeline.hoverOuterStretchWidth), + }) + } + + if (!cutEnd) + { + this.add({ + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rect.withX2(rect.x2 + prefs.timeline.hoverOuterStretchWidth), + }) + } + + if (rect.w > prefs.timeline.hoverInnerStretchWidth * 4) + { + if (!cutStart) + { + this.add({ + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rect.withX2(rect.x1 + prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + + if (!cutEnd) + { + this.add({ + kind: "hidden", + id: chord.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rect.withX1(rect.x2 - prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + } + + this.add({ + kind: "chord", + id: chord.id, + action: Timeline.MouseAction.DragTime, + rect, + cutStart, + cutEnd, + priority: 1, + chord: chord, + key: key, + }) + } + } + + + *iterElementsAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range, + verticalRegion?: { y1: number, y2: number }) + : Generator + { + for (const chord of iterChords(timeline, project, range)) + yield chord.id + } + + + findPreviousAnchor( + timeline: Timeline.State, + project: Project.ImmutableRoot, + time: Rational) + : Rational | null + { + const list = project.lists.get(project.chordTrackId) + if (!list) + return null + + const anchor = list.findPreviousDeletionAnchor(time) + return anchor + } + + + deleteRange( + timeline: Timeline.State, + project: Project.Mutable, + range: Range) + { + const list = project.root.lists.get(project.root.chordTrackId) + if (!list) + return + + if (range.duration.isZero()) + { + for (const elem of list.iterAtPoint(range.start)) + { + const removeElem = Project.elemModify(elem, { parentId: -1 }) + project.root = Project.upsertElement(project.root, removeElem) + } + } + else + { + for (const elem of list.iterAtRange(range)) + { + project.root = Project.splitElem(project.root, elem, range) + } + } + } + + + insertByDegree( + timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, + time: Rational, + degree: number) + { + const trackId = project.root.chordTrackId + const key = Project.keyAt(project.root, trackId, time) + const root = key.midiForDegree(degree) + + const pitches = [0] + pitches.push(key.midiForDegree(degree + 2) - root) + pitches.push(key.midiForDegree(degree + 4) - root) + + const kind = Theory.Chord.kindFromPitches(pitches) + const chord = new Theory.Chord(root, kind, 0, []) + Timeline.insertChord(timeline, project, trackId, time, chord) + } +} + + +function *iterChordsAndKeyChanges( + timeline: Timeline.State, + project: Project.ImmutableRoot) + : Generator<[Project.Chord, Timeline.KeyRegion], void, void> +{ + for (const keyRegion of timeline.layout.keyRegions) + { + const time1 = keyRegion.keyCh1.range.start.max(timeline.layout.range.start) + const time2 = keyRegion.keyCh2.range.start.min(timeline.layout.range.end) + + for (const chord of iterChords(timeline, project, new Range(time1, time2))) + yield [chord, keyRegion] + } +} + + +function *iterChords( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) +{ + const list = project.lists.get(project.chordTrackId) + if (!list) + return + + for (const elem of list.iterAtRange(range)) + yield elem as Project.Chord +} + + +function rectForChord( + timeline: Timeline.State, + lane: Timeline.Lane, + chordRange: Range, + keyChXStart: number, + keyChXEnd: number) + : [Rect, boolean, boolean] +{ + const chordOrigX1 = Timeline.xAtTime(timeline, chordRange.start) + const chordOrigX2 = Timeline.xAtTime(timeline, chordRange.end) + + let chordX1 = Math.max(chordOrigX1, keyChXStart) + let chordX2 = Math.min(chordOrigX2, keyChXEnd) + + const cutStart = chordOrigX1 < chordX1 + const cutEnd = chordOrigX2 > chordX2 + + //if (!cutStart) chordX1 += 1 + //if (!cutEnd) chordX2 -= 1 + + chordX1 = 0.5 + Math.floor(chordX1) + chordX2 = 0.5 + Math.floor(chordX2) + + const chordW = Math.max(2, chordX2 - chordX1) + + return [ + new Rect(chordX1, 0, chordW, lane.rect.h), + cutStart, + cutEnd] +} + + +function *iterChordsAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + lane: Timeline.Lane, + range: Range) + : Generator +{ + for (const [chord, keyChPair] of iterChordsAndKeyChanges(timeline, project)) + { + if (!chord.range.overlapsRange(range)) + continue + + yield chord.id + } +} \ No newline at end of file diff --git a/src/timeline/lane_notes.ts b/src/timeline/lane_notes.ts new file mode 100644 index 0000000..2ab8aed --- /dev/null +++ b/src/timeline/lane_notes.ts @@ -0,0 +1,457 @@ +import * as Project from "../project" +import * as Timeline from "./index.ts" +import * as Prefs from "../prefs.ts" +import * as Theory from "../theory/index.ts" +import Rect from "../utils/rect.ts" +import Range from "../utils/range.ts" +import Rational from "../utils/rational.ts" + + +export interface TupleIndicator +{ + denominator: number + rect: Rect + range: Range + highestMidiPitch: number + lowestMidiPitch: number +} + + +export const tupleDenominators = [13, 11, 7, 5, 3] + + +export class LaneNotes extends Timeline.Lane +{ + tupleIndicators: TupleIndicator[] = [] + + + refreshLayout( + timeline: Timeline.State, + project: Project.ImmutableRoot, + prefs: Prefs.Prefs) + { + this.elements = [] + this.tupleIndicators = [] + + for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project)) + { + const key = keyChPair.keyCh1.key + const row = rowForPitch(note.midiPitch, key) + + const [rect, cutStart, cutEnd] = rectForNote( + timeline, + this, + note.range, + row, + keyChPair.x1, + keyChPair.x2, + true) + + if (!cutStart) + { + this.add({ + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rect.withX1(rect.x1 - prefs.timeline.hoverOuterStretchWidth), + }) + } + + if (!cutEnd) + { + this.add({ + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rect.withX2(rect.x2 + prefs.timeline.hoverOuterStretchWidth), + }) + } + + if (rect.w > prefs.timeline.hoverInnerStretchWidth * 4) + { + if (!cutStart) + { + this.add({ + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeStart, + rect: rect.withX2(rect.x1 + prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + + if (!cutEnd) + { + this.add({ + kind: "hidden", + id: note.id, + action: Timeline.MouseAction.StretchTimeEnd, + rect: rect.withX1(rect.x2 - prefs.timeline.hoverInnerStretchWidth), + priority: 2, + }) + } + } + + this.add({ + kind: "note", + id: note.id, + note: note, + key: keyChPair.keyCh1.key, + action: Timeline.MouseAction.DragTimeAndRow, + rect, + cutStart, + cutEnd, + priority: 1, + }) + + for (const denom of Timeline.tupleDenominators) + { + if (note.range.duration.denominator % denom !== 0) + continue + + let tuple = this.tupleIndicators.find(t => + t.denominator === denom && + t.range.end.compare(note.range.start) === 0) + + if (tuple === undefined) + { + tuple = { + denominator: denom, + rect: rect, + range: note.range, + highestMidiPitch: note.midiPitch, + lowestMidiPitch: note.midiPitch, + } + + this.tupleIndicators.push(tuple) + } + + tuple.highestMidiPitch = Math.max(tuple.highestMidiPitch, note.midiPitch) + tuple.lowestMidiPitch = Math.min(tuple.lowestMidiPitch, note.midiPitch) + tuple.range = tuple.range.merge(note.range) + tuple.rect = tuple.rect.merge(rect) + break + } + } + + let keyChPrev = timeline.layout.keyRegions[0].keyCh1 + + for (const elem of iterMarkersForLayout(timeline, project, timeline.layout.range)) + { + const rect = rectForMarker( + timeline, + this, + elem.type === "keyChange" ? 0 : + 1, + elem.range.start) + + this.add({ + kind: "marker", + id: elem.id, + action: Timeline.MouseAction.DragTime, + rect, + priority: 1, + zIndex: 1, + keyCh: elem.type === "keyChange" ? elem : undefined, + keyChPrev: elem.type === "keyChange" ? keyChPrev : undefined, + meterCh: elem.type === "meterChange" ? elem : undefined, + }) + + timeline.layout.markers.push({ + time: elem.range.start, + keyCh: elem.type === "keyChange" ? elem : undefined, + meterCh: elem.type === "meterChange" ? elem : undefined, + }) + + if (elem.type === "keyChange") + keyChPrev = elem + } + } + + + *iterElementsAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range, + verticalRegion?: { y1: number, y2: number }) + : Generator + { + for (const note of iterNotesAtRegion(timeline, project, this, range, verticalRegion)) + yield note + + for (const marker of iterMarkersForSelection(timeline, project, range)) + yield marker + } + + + findPreviousAnchor( + timeline: Timeline.State, + project: Project.ImmutableRoot, + time: Rational) + : Rational | null + { + const list = project.lists.get(project.noteTrackId) + if (!list) + return null + + const anchor = list.findPreviousDeletionAnchor(time) + return anchor + } + + + deleteRange( + timeline: Timeline.State, + project: Project.Mutable, + range: Range) + { + const list = project.root.lists.get(project.root.noteTrackId) + if (!list) + return + + if (range.duration.isZero()) + { + for (const elem of list.iterAtPoint(range.start)) + { + const removeElem = Project.elemModify(elem, { parentId: -1 }) + project.root = Project.upsertElement(project.root, removeElem) + } + } + else + { + for (const elem of list.iterAtRange(range)) + { + project.root = Project.splitElem(project.root, elem, range) + } + } + } + + + insertByDegree( + timeline: Timeline.State, + project: Project.Mutable, + prefs: Prefs.Prefs, + time: Rational, + degree: number) + { + const trackId = project.root.noteTrackId + const key = Project.keyAt(project.root, trackId, time) + const chroma = key.chromaForDegree(degree) + Timeline.insertNote(timeline, project, trackId, time, chroma) + } + + + rowAtY( + timeline: Timeline.State, + y: number) + { + return rowAtY(timeline, this, y) + } +} + + +function *iterNotesAndKeyChanges( + timeline: Timeline.State, + project: Project.ImmutableRoot) + : Generator<[Project.Note, Timeline.KeyRegion], void, void> +{ + for (const keyRegion of timeline.layout.keyRegions) + { + const time1 = keyRegion.keyCh1.range.start.max(timeline.layout.range.start) + const time2 = keyRegion.keyCh2.range.start.min(timeline.layout.range.end) + + for (const note of iterNotes(timeline, project, new Range(time1, time2))) + yield [note, keyRegion] + } +} + + +function *iterNotes( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const list = project.lists.get(project.noteTrackId) + if (!list) + return + + for (const elem of list.iterAtRange(range)) + yield elem as Project.Note +} + + +export function rowForPitch( + pitch: number, + key: Theory.Key) + : number +{ + const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) + return key.octavedDegreeForMidi(pitch - Theory.Utils.midiMiddleC) + tonicRowOffset +} + + +export function pitchForRow( + row: number, + key: Theory.Key) + : number +{ + const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) + return key.midiForDegree(row - Math.floor(tonicRowOffset)) + Theory.Utils.midiMiddleC +} + + +export function yForRow( + timeline: Timeline.State, + lane: Timeline.Lane, + row: number) + : number +{ + return lane.rect.h / 2 - (row + 1) * timeline.noteRowH - timeline.yScroll +} + + +export function rowAtY( + timeline: Timeline.State, + lane: Timeline.Lane, + y: number) + : number +{ + return -Math.floor((y + timeline.yScroll - lane.rect.h / 2) / timeline.noteRowH) - 1 +} + + +function rectForNote( + timeline: Timeline.State, + lane: Timeline.Lane, + noteRange: Range, + noteRow: number, + keyChXStart: number, + keyChXEnd: number, + clampY: boolean) + : [Rect, boolean, boolean] +{ + const noteOrigX1 = Timeline.xAtTime(timeline, noteRange.start) + const noteOrigX2 = Timeline.xAtTime(timeline, noteRange.end) + + let noteY = 0.5 + Math.floor(yForRow(timeline, lane, noteRow)) + if (clampY) + { + noteY = + Math.max(lane.rect.y - timeline.noteRowH / 2, + Math.min(lane.rect.y + lane.rect.h - timeline.noteRowH / 2, + noteY)) + } + + let noteX1 = Math.max(noteOrigX1, keyChXStart) + let noteX2 = Math.min(noteOrigX2, keyChXEnd) + + const cutStart = noteOrigX1 < noteX1 + const cutEnd = noteOrigX2 > noteX2 + + //if (!cutStart) noteX1 += 1 + //if (!cutEnd) noteX2 -= 1 + + noteX1 = 0.5 + Math.floor(noteX1) + noteX2 = 0.5 + Math.floor(noteX2) + + const noteW = Math.max(2, noteX2 - noteX1) + + return [ + new Rect(noteX1, noteY, noteW, timeline.noteRowH), + cutStart, + cutEnd] +} + + +function *iterNotesAtRegion( + timeline: Timeline.State, + project: Project.ImmutableRoot, + lane: Timeline.Lane, + range: Range, + verticalRegion?: { y1: number, y2: number }) + : Generator +{ + for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project)) + { + if (!note.range.overlapsRange(range)) + continue + + if (verticalRegion !== undefined) + { + const [rect] = rectForNote( + timeline, + lane, + note.range, + rowForPitch(note.midiPitch, keyChPair.keyCh1.key), + keyChPair.x1, + keyChPair.x2, + false) + + if (verticalRegion.y1 > rect.y2 || + verticalRegion.y2 < rect.y1) + continue + } + + yield note.id + } +} + + +function *iterMarkersForLayout( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const keyChTrackElems = project.lists.get(project.keyChangeTrackId) + if (!keyChTrackElems) + return + + for (const keyCh of keyChTrackElems.iterAtRange(range)) + yield keyCh as Project.KeyChange + + const meterChTrackElems = project.lists.get(project.meterChangeTrackId) + if (!meterChTrackElems) + return + + for (const meterCh of meterChTrackElems.iterAtRange(range)) + yield meterCh as Project.MeterChange +} + + +function rectForMarker( + timeline: Timeline.State, + lane: Timeline.Lane, + row: number, + time: Rational) + : Rect +{ + const x = Timeline.xAtTime(timeline, time) + const w = 16 + const h = 24 + const y = h * row + + return new Rect(x - w / 2, y, w, h) +} + + +function *iterMarkersForSelection( + timeline: Timeline.State, + project: Project.ImmutableRoot, + range: Range) + : Generator +{ + const keyChTrackElems = project.lists.get(project.keyChangeTrackId) + if (!keyChTrackElems) + return + + for (const keyCh of keyChTrackElems.iterAtRange(range)) + yield keyCh.id + + const meterChTrackElems = project.lists.get(project.meterChangeTrackId) + if (!meterChTrackElems) + return + + for (const meterCh of meterChTrackElems.iterAtRange(range)) + yield meterCh.id +} \ No newline at end of file diff --git a/src/timeline/layout.ts b/src/timeline/layout.ts index c53b5bf..a4d9b8b 100644 --- a/src/timeline/layout.ts +++ b/src/timeline/layout.ts @@ -4,7 +4,7 @@ import * as Prefs from "../prefs.ts" import * as Theory from "../theory/index.ts" import Rect from "../utils/rect.ts" import Range from "../utils/range.ts" -import Rational from "utils/rational.ts" +import Rational from "../utils/rational.ts" export interface LayoutElementCommon @@ -48,7 +48,6 @@ export interface LayoutElementLaneMarkers extends LayoutElementLaneCommon export interface LayoutElementLaneNotes extends LayoutElementLaneCommon { kind: "laneNotes" - tupleIndicators: TupleIndicator[] } @@ -61,6 +60,8 @@ export interface LayoutElementLaneChords extends LayoutElementLaneCommon export interface LayoutElementNote extends LayoutElementCommon { kind: "note" + note: Project.Note + key: Theory.Key } @@ -76,6 +77,7 @@ export interface LayoutElementMarker extends LayoutElementCommon { kind: "marker" keyCh?: Project.KeyChange + keyChPrev?: Project.KeyChange meterCh?: Project.MeterChange } @@ -113,27 +115,10 @@ export interface Marker } -export interface TupleIndicator -{ - denominator: number - rect: Rect - range: Range - highestMidiPitch: number - lowestMidiPitch: number -} - - -export const tupleDenominators = [13, 11, 7, 5, 3] - - export class Layout { range: Range - lanes: LayoutLane[] = [] - elements: LayoutElement[] = [] - elementCount: number = 0 - laneNotes?: LayoutElementLaneNotes - laneChords?: LayoutElementLaneChords + lanes: Timeline.Lane[] = [] measures: Project.Measure[] = [] keyRegions: KeyRegion[] = [] @@ -146,26 +131,20 @@ export class Layout } - add(parent: LayoutElement | undefined, elem: LayoutElement) + addLane(lane: Timeline.Lane) { - this.elementCount++ - - if (parent !== undefined) - { - if (parent.subElements === undefined) - parent.subElements = [] - - parent.subElements.push(elem) - } - else - { - this.elements.push(elem) - - if (elem.kind === "laneMarkers" || - elem.kind === "laneNotes" || - elem.kind === "laneChords") - this.lanes.push(elem) - } + lane.laneIndex = this.lanes.length + this.lanes.push(lane) + } + + + getElementCount() + { + let count = 0 + for (const lane of this.lanes) + count += lane.elements.length + + return count } } @@ -176,6 +155,8 @@ export function layout( prefs: Prefs.Prefs) { const layout = new Layout() + timeline.layout = layout + layout.range = Timeline.visibleTimeRange(timeline) layout.measures = [...Project.iterMeasuresAtRange(project, layout.range)] layout.keyRegions = [...iterKeyChangePairsAtRange(timeline, project, layout.range)] @@ -185,37 +166,27 @@ export function layout( const laneChordH = 60 const laneMarginY = 8 - const laneNotes: LayoutElementLaneNotes = { - kind: "laneNotes", - laneIndex: 0, - rect: new Rect( - 0, - 0, - timeline.renderRect.w, - timeline.renderRect.h - laneChordH - laneMarginY), - tupleIndicators: [], - } + const laneNotes = new Timeline.LaneNotes() + laneNotes.rect = new Rect( + 0, + 0, + timeline.renderRect.w, + timeline.renderRect.h - laneChordH - laneMarginY) - const laneChords: LayoutElementLaneChords = { - kind: "laneChords", - laneIndex: 1, - rect: new Rect( - 0, - timeline.renderRect.h - laneChordH, - timeline.renderRect.w, - laneChordH - 1), - } + const laneChords = new Timeline.LaneChords() + laneChords.rect = new Rect( + 0, + timeline.renderRect.h - laneChordH, + timeline.renderRect.w, + laneChordH - 1) - layout.add(undefined, laneNotes) - layout.add(undefined, laneChords) - layout.laneNotes = laneNotes + layout.addLane(laneNotes) + layout.addLane(laneChords) - Timeline.layoutLaneMarkers(timeline, project, prefs, layout, laneNotes) - Timeline.layoutLaneNotes(timeline, project, prefs, layout, laneNotes) - Timeline.layoutLaneChords(timeline, project, prefs, layout, laneChords) + laneNotes.refreshLayout(timeline, project, prefs) + laneChords.refreshLayout(timeline, project, prefs) - timeline.layout = layout - console.log(layout.elementCount, layout) + //console.log(layout.getElementCount(), layout) } diff --git a/src/timeline/layout_chords.ts b/src/timeline/layout_chords.ts deleted file mode 100644 index add2f92..0000000 --- a/src/timeline/layout_chords.ts +++ /dev/null @@ -1,168 +0,0 @@ -import * as Project from "../project" -import * as Theory from "../theory" -import * as Timeline from "./index.ts" -import * as Prefs from "../prefs.ts" -import Rect from "../utils/rect.ts" -import Range from "../utils/range.ts" - - -export function layoutLaneChords( - timeline: Timeline.State, - project: Project.ImmutableRoot, - prefs: Prefs.Prefs, - layout: Timeline.Layout, - laneChords: Timeline.LayoutElementLaneChords) -{ - laneChords.iterElementsAtRegion = (timeline, project, range, verticalRegion) => - iterChordsAtRegion(timeline, project, laneChords, range) - - for (const [chord, keyChPair] of iterChordsAndKeyChanges(timeline, project, layout)) - { - const key = keyChPair.keyCh1.key - - const [rect, cutStart, cutEnd] = rectForChord( - timeline, - laneChords, - chord.range, - keyChPair.x1, - keyChPair.x2) - - if (!cutStart) - { - layout.add(laneChords, { - kind: "hidden", - id: chord.id, - action: Timeline.MouseAction.StretchTimeStart, - rect: rect.withX1(rect.x1 - prefs.timeline.hoverOuterStretchWidth), - }) - } - - if (!cutEnd) - { - layout.add(laneChords, { - kind: "hidden", - id: chord.id, - action: Timeline.MouseAction.StretchTimeEnd, - rect: rect.withX2(rect.x2 + prefs.timeline.hoverOuterStretchWidth), - }) - } - - if (rect.w > prefs.timeline.hoverInnerStretchWidth * 4) - { - if (!cutStart) - { - layout.add(laneChords, { - kind: "hidden", - id: chord.id, - action: Timeline.MouseAction.StretchTimeStart, - rect: rect.withX2(rect.x1 + prefs.timeline.hoverInnerStretchWidth), - priority: 2, - }) - } - - if (!cutEnd) - { - layout.add(laneChords, { - kind: "hidden", - id: chord.id, - action: Timeline.MouseAction.StretchTimeEnd, - rect: rect.withX1(rect.x2 - prefs.timeline.hoverInnerStretchWidth), - priority: 2, - }) - } - } - - layout.add(laneChords, { - kind: "chord", - id: chord.id, - action: Timeline.MouseAction.DragTime, - rect, - cutStart, - cutEnd, - priority: 1, - chord: chord, - key: key, - }) - } -} - - -function *iterChordsAndKeyChanges( - timeline: Timeline.State, - project: Project.ImmutableRoot, - layout: Timeline.Layout) - : Generator<[Project.Chord, Timeline.KeyRegion], void, void> -{ - for (const keyRegion of layout.keyRegions) - { - const time1 = keyRegion.keyCh1.range.start.max(layout.range.start) - const time2 = keyRegion.keyCh2.range.start.min(layout.range.end) - - for (const chord of iterChords(timeline, project, new Range(time1, time2))) - yield [chord, keyRegion] - } -} - - -function *iterChords( - timeline: Timeline.State, - project: Project.ImmutableRoot, - range: Range) - : Generator -{ - const list = project.lists.get(project.chordTrackId) - if (!list) - return - - for (const elem of list.iterAtRange(range)) - yield elem as Project.Chord -} - - -function rectForChord( - timeline: Timeline.State, - lane: Timeline.LayoutElementLaneChords, - chordRange: Range, - keyChXStart: number, - keyChXEnd: number) - : [Rect, boolean, boolean] -{ - const chordOrigX1 = Timeline.xAtTime(timeline, chordRange.start) - const chordOrigX2 = Timeline.xAtTime(timeline, chordRange.end) - - let chordX1 = Math.max(chordOrigX1, keyChXStart) - let chordX2 = Math.min(chordOrigX2, keyChXEnd) - - const cutStart = chordOrigX1 < chordX1 - const cutEnd = chordOrigX2 > chordX2 - - //if (!cutStart) chordX1 += 1 - //if (!cutEnd) chordX2 -= 1 - - chordX1 = 0.5 + Math.floor(chordX1) - chordX2 = 0.5 + Math.floor(chordX2) - - const chordW = Math.max(2, chordX2 - chordX1) - - return [ - new Rect(chordX1, lane.rect.y, chordW, lane.rect.h), - cutStart, - cutEnd] -} - - -function *iterChordsAtRegion( - timeline: Timeline.State, - project: Project.ImmutableRoot, - lane: Timeline.LayoutElementLaneChords, - range: Range) - : Generator -{ - for (const [chord, keyChPair] of iterChordsAndKeyChanges(timeline, project, timeline.layout)) - { - if (!chord.range.overlapsRange(range)) - continue - - yield chord.id - } -} \ No newline at end of file diff --git a/src/timeline/layout_markers.ts b/src/timeline/layout_markers.ts deleted file mode 100644 index e0c7acc..0000000 --- a/src/timeline/layout_markers.ts +++ /dev/null @@ -1,118 +0,0 @@ -import * as Project from "../project" -import * as Theory from "../theory" -import * as Timeline from "./index.ts" -import * as Prefs from "../prefs.ts" -import Rect from "../utils/rect.ts" -import Range from "../utils/range.ts" -import Rational from "../utils/rational.ts" - - -export function layoutLaneMarkers( - timeline: Timeline.State, - project: Project.ImmutableRoot, - prefs: Prefs.Prefs, - layout: Timeline.Layout, - lane: Timeline.LayoutElementLaneNotes) -{ - lane.iterElementsAtRegion = (timeline, project, range, verticalRegion) => - iterMarkersForSelection(timeline, project, range) - - for (const elem of iterMarkersForLayout(timeline, project, layout.range)) - { - const rect = rectForMarker( - timeline, - lane, - elem.type === "keyChange" ? 0 : - 1, - elem.range.start) - - layout.add(lane, { - kind: "marker", - id: elem.id, - action: Timeline.MouseAction.DragTime, - rect, - priority: 1, - zIndex: 1, - keyCh: elem.type === "keyChange" ? elem : undefined, - meterCh: elem.type === "meterChange" ? elem : undefined, - }) - - layout.markers.push({ - time: elem.range.start, - keyCh: elem.type === "keyChange" ? elem : undefined, - meterCh: elem.type === "meterChange" ? elem : undefined, - }) - } -} - - -function *iterMarkersForLayout( - timeline: Timeline.State, - project: Project.ImmutableRoot, - range: Range) - : Generator -{ - const keyChTrackId = Project.keyChangeTrackId(project) - const keyChTrackElems = project.lists.get(keyChTrackId) - if (!keyChTrackElems) - return - - for (const keyCh of keyChTrackElems.iterAtRange(range)) - { - yield keyCh as Project.KeyChange - } - - const meterChTrackId = Project.meterChangeTrackId(project) - const meterChTrackElems = project.lists.get(meterChTrackId) - if (!meterChTrackElems) - return - - for (const meterCh of meterChTrackElems.iterAtRange(range)) - { - yield meterCh as Project.MeterChange - } -} - - -function rectForMarker( - timeline: Timeline.State, - lane: Timeline.LayoutLane, - row: number, - time: Rational) - : Rect -{ - const x = Timeline.xAtTime(timeline, time) - const w = 16 - const h = 24 - const y = lane.rect.y + h * row - - return new Rect(x - w / 2, y, w, h) -} - - -export function *iterMarkersForSelection( - timeline: Timeline.State, - project: Project.ImmutableRoot, - range: Range) - : Generator -{ - const keyChTrackId = Project.keyChangeTrackId(project) - const keyChTrackElems = project.lists.get(keyChTrackId) - if (!keyChTrackElems) - return - - for (const keyCh of keyChTrackElems.iterAtRange(range)) - { - yield keyCh.id - } - - const meterChTrackId = Project.meterChangeTrackId(project) - const meterChTrackElems = project.lists.get(meterChTrackId) - if (!meterChTrackElems) - return - - for (const meterCh of meterChTrackElems.iterAtRange(range)) - { - yield meterCh.id - } -} \ No newline at end of file diff --git a/src/timeline/layout_notes.ts b/src/timeline/layout_notes.ts deleted file mode 100644 index 89896f6..0000000 --- a/src/timeline/layout_notes.ts +++ /dev/null @@ -1,283 +0,0 @@ -import * as Project from "../project" -import * as Theory from "../theory" -import * as Timeline from "./index.ts" -import * as Prefs from "../prefs.ts" -import Rect from "../utils/rect.ts" -import Range from "../utils/range.ts" - - -export function layoutLaneNotes( - timeline: Timeline.State, - project: Project.ImmutableRoot, - prefs: Prefs.Prefs, - layout: Timeline.Layout, - laneNotes: Timeline.LayoutElementLaneNotes) -{ - laneNotes.iterElementsAtRegion = (timeline, project, range, verticalRegion) => - iterNotesAndMarkersAtRegion(timeline, project, laneNotes, range, verticalRegion) - - for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, layout)) - { - const key = keyChPair.keyCh1.key - const row = rowForPitch(note.midiPitch, key) - - const [rect, cutStart, cutEnd] = rectForNote( - timeline, - laneNotes, - note.range, - row, - keyChPair.x1, - keyChPair.x2, - true) - - if (!cutStart) - { - layout.add(laneNotes, { - kind: "hidden", - id: note.id, - action: Timeline.MouseAction.StretchTimeStart, - rect: rect.withX1(rect.x1 - prefs.timeline.hoverOuterStretchWidth), - }) - } - - if (!cutEnd) - { - layout.add(laneNotes, { - kind: "hidden", - id: note.id, - action: Timeline.MouseAction.StretchTimeEnd, - rect: rect.withX2(rect.x2 + prefs.timeline.hoverOuterStretchWidth), - }) - } - - if (rect.w > prefs.timeline.hoverInnerStretchWidth * 4) - { - if (!cutStart) - { - layout.add(laneNotes, { - kind: "hidden", - id: note.id, - action: Timeline.MouseAction.StretchTimeStart, - rect: rect.withX2(rect.x1 + prefs.timeline.hoverInnerStretchWidth), - priority: 2, - }) - } - - if (!cutEnd) - { - layout.add(laneNotes, { - kind: "hidden", - id: note.id, - action: Timeline.MouseAction.StretchTimeEnd, - rect: rect.withX1(rect.x2 - prefs.timeline.hoverInnerStretchWidth), - priority: 2, - }) - } - } - - layout.add(laneNotes, { - kind: "note", - id: note.id, - action: Timeline.MouseAction.DragTimeAndRow, - rect, - cutStart, - cutEnd, - priority: 1, - }) - - for (const denom of Timeline.tupleDenominators) - { - if (note.range.duration.denominator % denom !== 0) - continue - - let tuple = laneNotes.tupleIndicators.find(t => - t.denominator === denom && - t.range.end.compare(note.range.start) === 0) - - if (tuple === undefined) - { - tuple = { - denominator: denom, - rect: rect, - range: note.range, - highestMidiPitch: note.midiPitch, - lowestMidiPitch: note.midiPitch, - } - - laneNotes.tupleIndicators.push(tuple) - } - - tuple.highestMidiPitch = Math.max(tuple.highestMidiPitch, note.midiPitch) - tuple.lowestMidiPitch = Math.min(tuple.lowestMidiPitch, note.midiPitch) - tuple.range = tuple.range.merge(note.range) - tuple.rect = tuple.rect.merge(rect) - break - } - } -} - - -function *iterNotesAndKeyChanges( - timeline: Timeline.State, - project: Project.ImmutableRoot, - layout: Timeline.Layout) - : Generator<[Project.Note, Timeline.KeyRegion], void, void> -{ - for (const keyRegion of layout.keyRegions) - { - const time1 = keyRegion.keyCh1.range.start.max(layout.range.start) - const time2 = keyRegion.keyCh2.range.start.min(layout.range.end) - - for (const note of iterNotes(timeline, project, new Range(time1, time2))) - yield [note, keyRegion] - } -} - - -function *iterNotes( - timeline: Timeline.State, - project: Project.ImmutableRoot, - range: Range) - : Generator -{ - const list = project.lists.get(project.noteTrackId) - if (!list) - return - - for (const elem of list.iterAtRange(range)) - yield elem as Project.Note -} - - -export function rowForPitch( - pitch: number, - key: Theory.Key) - : number -{ - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.octavedDegreeForMidi(pitch - Theory.Utils.midiMiddleC) + tonicRowOffset -} - - -export function pitchForRow( - row: number, - key: Theory.Key) - : number -{ - const tonicRowOffset = Theory.Utils.chromaToDegreeInCMajor(key.tonic.chroma) - return key.midiForDegree(row - Math.floor(tonicRowOffset)) + Theory.Utils.midiMiddleC -} - - -export function yForRow( - timeline: Timeline.State, - lane: Timeline.LayoutElementLaneNotes, - row: number) - : number -{ - return lane.rect.y + - lane.rect.h / 2 - (row + 1) * timeline.noteRowH - timeline.yScroll -} - - -export function rowAtY( - timeline: Timeline.State, - lane: Timeline.LayoutElementLaneNotes, - y: number) - : number -{ - return -Math.floor((y - lane.rect.y + timeline.yScroll - lane.rect.h / 2) / timeline.noteRowH) - 1 -} - - -function rectForNote( - timeline: Timeline.State, - lane: Timeline.LayoutElementLaneNotes, - noteRange: Range, - noteRow: number, - keyChXStart: number, - keyChXEnd: number, - clampY: boolean) - : [Rect, boolean, boolean] -{ - const noteOrigX1 = Timeline.xAtTime(timeline, noteRange.start) - const noteOrigX2 = Timeline.xAtTime(timeline, noteRange.end) - - let noteY = 0.5 + Math.floor(yForRow(timeline, lane, noteRow)) - if (clampY) - { - noteY = - Math.max(lane.rect.y - timeline.noteRowH / 2, - Math.min(lane.rect.y + lane.rect.h - timeline.noteRowH / 2, - noteY)) - } - - let noteX1 = Math.max(noteOrigX1, keyChXStart) - let noteX2 = Math.min(noteOrigX2, keyChXEnd) - - const cutStart = noteOrigX1 < noteX1 - const cutEnd = noteOrigX2 > noteX2 - - //if (!cutStart) noteX1 += 1 - //if (!cutEnd) noteX2 -= 1 - - noteX1 = 0.5 + Math.floor(noteX1) - noteX2 = 0.5 + Math.floor(noteX2) - - const noteW = Math.max(2, noteX2 - noteX1) - - return [ - new Rect(noteX1, noteY, noteW, timeline.noteRowH), - cutStart, - cutEnd] -} - - -function *iterNotesAndMarkersAtRegion( - timeline: Timeline.State, - project: Project.ImmutableRoot, - lane: Timeline.LayoutElementLaneNotes, - range: Range, - verticalRegion?: { y1: number, y2: number }) - : Generator -{ - for (const note of iterNotesAtRegion(timeline, project, lane, range, verticalRegion)) - yield note - - for (const marker of Timeline.iterMarkersForSelection(timeline, project, range)) - yield marker -} - - -function *iterNotesAtRegion( - timeline: Timeline.State, - project: Project.ImmutableRoot, - lane: Timeline.LayoutElementLaneNotes, - range: Range, - verticalRegion?: { y1: number, y2: number }) - : Generator -{ - for (const [note, keyChPair] of iterNotesAndKeyChanges(timeline, project, timeline.layout)) - { - if (!note.range.overlapsRange(range)) - continue - - if (verticalRegion !== undefined) - { - const [rect] = rectForNote( - timeline, - lane, - note.range, - rowForPitch(note.midiPitch, keyChPair.keyCh1.key), - keyChPair.x1, - keyChPair.x2, - false) - - if (verticalRegion.y1 > rect.y2 || - verticalRegion.y2 < rect.y1) - continue - } - - yield note.id - } -} \ No newline at end of file diff --git a/src/timeline/mouse_down.ts b/src/timeline/mouse_down.ts index 01c327a..523c078 100644 --- a/src/timeline/mouse_down.ts +++ b/src/timeline/mouse_down.ts @@ -37,10 +37,8 @@ export function mouseDown( timeline.mouse.downDate.getTime() - prevDownDate.getTime() < prefs.timeline.mouseDoubleClickThresholdMs - timeline.drag = - { - origin: - { + timeline.drag = { + origin: { point: { ...timeline.mouse.point }, range: null, timeScroll: timeline.timeScroll, @@ -91,15 +89,18 @@ export function mouseDown( timeline.cursor.laneIndex1 = timeline.cursor.laneIndex2 = timeline.mouse.point.laneIndex - /*if (doubleClick) + if (doubleClick) { const anchor = Timeline.findPreviousAnchor( - timeline, timeline.mouse.point.time, - timeline.mouse.point.trackIndex, timeline.mouse.point.trackIndex) + timeline, + project.root, + timeline.mouse.point.time, + timeline.mouse.point.laneIndex, + timeline.mouse.point.laneIndex) Timeline.cursorSetTime(timeline, anchor, anchor) Timeline.scrollTimeIntoView(timeline, anchor) - }*/ + } return } diff --git a/src/timeline/mouse_move.ts b/src/timeline/mouse_move.ts index 04cb6e8..539f979 100644 --- a/src/timeline/mouse_move.ts +++ b/src/timeline/mouse_move.ts @@ -15,7 +15,25 @@ export function mouseMove( if (!timeline.mouse.down) { timeline.hover = undefined - hoverRecursive(timeline, timeline.layout.elements, x, y) + hoverLanes(timeline, x, y) + } +} + + +function hoverLanes( + timeline: Timeline.State, + x: number, + y: number) +{ + for (const lane of timeline.layout.lanes) + { + if (x >= lane.rect.x && + x < lane.rect.x + lane.rect.w && + y >= lane.rect.y && + y < lane.rect.y + lane.rect.h) + { + hoverRecursive(timeline, lane.elements, x - lane.rect.x, y - lane.rect.y) + } } } @@ -38,7 +56,7 @@ function hoverRecursive( timeline.hover = elem if (elem.subElements) - hoverRecursive(timeline, elem.subElements, x, y) + hoverRecursive(timeline, elem.subElements, x - elem.rect.x, y - elem.rect.y) } } } \ No newline at end of file diff --git a/src/timeline/timeline.ts b/src/timeline/timeline.ts index 671bd97..dcbface 100644 --- a/src/timeline/timeline.ts +++ b/src/timeline/timeline.ts @@ -1,9 +1,11 @@ import * as Immutable from "immutable" import * as Project from "../project" import * as Timeline from "./index.ts" +import * as Theory from "../theory" import Rational from "../utils/rational.ts" import Range from "../utils/range.ts" import Rect from "../utils/rect.ts" +import * as MathUtils from "../utils/mathUtils.ts" export interface State @@ -300,11 +302,10 @@ export function pointAt( { const time = timeAtX(timeline, x) - const row = timeline.layout.laneNotes ? - Timeline.rowAtY(timeline, timeline.layout.laneNotes, y) : - 0 - const laneIndex = laneIndexAtY(timeline, y) + const lane = timeline.layout.lanes[laneIndex] + + const row = lane?.rowAtY(timeline, y) ?? 0 /*const trackPosY = pos.y - trackY(state, state.mouse.point.trackIndex) const trackPos = { x: pos.x, y: trackPosY } @@ -397,6 +398,17 @@ export function selectionAddAtCursor( } +export function rewind( + state: Timeline.State, + project: Project.ImmutableRoot) +{ + state.cursor.visible = true + state.cursor.time1 = state.cursor.time2 = project.range.start + //Playback.setStartTime(Project.global.project.range.start) + scrollTimeIntoView(state, state.cursor.time1) +} + + export function cursorSetTime( timeline: Timeline.State, time1: Rational | null, @@ -534,4 +546,166 @@ export function selectionResolveOverlappingAndDegenerate( } } } +} + + +export function insertNote( + timeline: Timeline.State, + project: Project.Mutable, + trackId: Project.ID, + time: Rational, + chroma: number) +{ + keyHandlePendingFinish(timeline, project) + + const insertOctave = Math.floor(timeline.insertion.nearMidiPitch / 12) + const possiblePitches = [-1, 0, 1].map(offset => { + const pitch = (insertOctave + offset) * 12 + (MathUtils.mod(chroma, 12)) + const delta = Math.abs(pitch - timeline.insertion.nearMidiPitch) + return { pitch, delta } + }) + + possiblePitches.sort((a, b) => a.delta - b.delta) + const chosenPitch = possiblePitches[0].pitch + + const range = new Range(time, time.add(timeline.insertion.duration)) + + const note = Project.makeNote( + trackId, + range, + chosenPitch) + + const id = project.root.nextId + project.root = Project.upsertElement(project.root, note) + project.root = Project.withRefreshedRange(project.root) + + timeline.insertion.nearMidiPitch = chosenPitch + + timeline.cursor.visible = false + cursorSetTime(timeline, range.end, range.end) + scrollTimeIntoView(timeline, range.end) + selectionClear(timeline) + selectionAdd(timeline, id) + //Playback.playNotePreview(noteBlock.parentId, chosenPitch, volumeDb, velocity) + selectionResolveOverlappingAndDegenerate(timeline, project) +} + + +export function findPreviousAnchor( + timeline: Timeline.State, + project: Project.ImmutableRoot, + time: Rational, + laneIndex1: number, + laneIndex2: number) + : Rational +{ + let prevAnchor: Rational | null = null + + const laneMin = Math.min(laneIndex1, laneIndex2) + const laneMax = Math.max(laneIndex1, laneIndex2) + + for (let i = Math.max(0, laneMin); i <= Math.min(timeline.layout.lanes.length - 1, laneMax); i++) + { + const anchor = timeline.layout.lanes[i].findPreviousAnchor(timeline, project, time) + if (!anchor) + continue + + prevAnchor = Rational.max(prevAnchor, anchor) + } + + if (!prevAnchor) + return project.range.start + + return prevAnchor +} + + +export function deleteRange( + timeline: Timeline.State, + project: Project.Mutable, + range: Range, + trackIndex1: number, + trackIndex2: number) +{ + const trackMin = Math.min(trackIndex1, trackIndex2) + const trackMax = Math.max(trackIndex1, trackIndex2) + + for (let tr = Math.max(0, trackMin); tr <= Math.min(timeline.layout.lanes.length - 1, trackMax); tr++) + timeline.layout.lanes[tr].deleteRange(timeline, project, range) +} + + +export function insertChord( + timeline: Timeline.State, + project: Project.Mutable, + trackId: Project.ID, + time: Rational, + chord: Theory.Chord) +{ + keyHandlePendingFinish(timeline, project) + + const range = new Range(time, time.add(timeline.insertion.duration)) + + const projChord = Project.makeChord( + trackId, + range, + chord) + + const id = project.root.nextId + project.root = Project.upsertElement(project.root, projChord) + project.root = Project.withRefreshedRange(project.root) + + timeline.cursor.visible = false + cursorSetTime(timeline, range.end, range.end) + scrollTimeIntoView(timeline, range.end) + selectionClear(timeline) + selectionAdd(timeline, id) + //Playback.playChordPreview(track.projectTrackId, chord, volumeDb, velocity) + selectionResolveOverlappingAndDegenerate(timeline, project) +} + + +export function deleteElems( + timeline: Timeline.State, + project: Project.Mutable, + elemIds: Iterable) +{ + const range = + Project.getRangeForElems(project.root, elemIds) ?? + new Range(timeline.cursor.time1, timeline.cursor.time1) + + for (const id of elemIds) + { + const elem = project.root.elems.get(id) + if (!elem) + continue + + if (elem.type == "track") + continue + + const removeElem = Project.elemModify(elem, { parentId: -1 }) + project.root = Project.upsertElement(project.root, removeElem) + } + + for (const id of elemIds) + { + const track = project.root.elems.get(id) + if (!track) + continue + + if (track.type != "track") + continue + + if (track.id === project.root.keyChangeTrackId || + track.id === project.root.meterChangeTrackId || + track.id === project.root.chordTrackId) + continue + + project.root = Project.upsertTrack(project.root, track, true) + } + + project.root = Project.withRefreshedRange(project.root) + timeline.cursor.visible = true + cursorSetTime(timeline, range.start, range.start) + scrollTimeIntoView(timeline, range.start) } \ No newline at end of file diff --git a/src/utils/canvasUtils.ts b/src/utils/canvasUtils.ts new file mode 100644 index 0000000..45a5ec7 --- /dev/null +++ b/src/utils/canvasUtils.ts @@ -0,0 +1,51 @@ +import * as Theory from "../theory" +import * as MathUtils from "./mathUtils" + + +const fillPatterns = new Map() + + +export function fillStyleForDegree(ctx: CanvasRenderingContext2D, degree: number, external: boolean): any +{ + degree = MathUtils.mod(degree, 7) + + const colorFn = external ? Theory.Utils.degreeToColorFaded : Theory.Utils.degreeToColor + + if (Math.floor(degree) === degree) + return colorFn(degree) + + const cacheKey = degree + (external ? 100 : 0) + + if (fillPatterns.has(cacheKey)) + return fillPatterns.get(cacheKey) + + const colorBefore = colorFn(MathUtils.mod(Math.floor(degree), 7)) + const colorAfter = colorFn(MathUtils.mod(Math.ceil(degree), 7)) + + const canvas = document.createElement("canvas") + canvas.width = 24 + canvas.height = 24 + canvas.style.display = "none" + document.body.appendChild(canvas) + + let ctxPatt = canvas.getContext("2d")! + ctxPatt.fillStyle = colorBefore + ctxPatt.fillRect(0, 0, 24, 24) + + ctxPatt.fillStyle = colorAfter + ctxPatt.beginPath() + ctxPatt.moveTo(12, 0) + ctxPatt.lineTo(24, 0) + ctxPatt.lineTo(0, 24) + ctxPatt.lineTo(-12, 24) + + ctxPatt.moveTo(24 + 12, 0) + ctxPatt.lineTo(24 + 24, 0) + ctxPatt.lineTo(24 + 0, 24) + ctxPatt.lineTo(24 - 12, 24) + ctxPatt.fill() + + const pattern = ctx.createPattern(canvas, "repeat") + fillPatterns.set(cacheKey, pattern) + return pattern +} \ No newline at end of file diff --git a/src/utils/rational.ts b/src/utils/rational.ts index 5db5f08..b18c222 100644 --- a/src/utils/rational.ts +++ b/src/utils/rational.ts @@ -12,7 +12,7 @@ export default class Rational constructor(numerator: number = 0, denominator: number = 1) { - if (denominator == 0) + if (denominator === 0) throw "denominator zero" if (!isFinite(numerator) || !isFinite(denominator)) @@ -145,12 +145,12 @@ export default class Rational stretch(offset: Rational, pivot: Rational, origin: Rational): Rational { - let dist = origin.subtract(pivot) - if (dist.numerator == 0) + const dist = origin.subtract(pivot) + if (dist.numerator === 0) return this - let p = this.subtract(pivot).divide(dist) - let move = origin.add(offset).subtract(pivot).divide(dist) + const p = this.subtract(pivot).divide(dist) + const move = origin.add(offset).subtract(pivot).divide(dist) return pivot.add(dist.multiply(p).multiply(move)) } @@ -158,14 +158,14 @@ export default class Rational isZero(): boolean { - return this.numerator == 0 + return this.numerator === 0 } compare(other: Rational): number { - let thisNumerator = this.numerator * other.denominator - let otherNumerator = other.numerator * this.denominator + const thisNumerator = this.numerator * other.denominator + const otherNumerator = other.numerator * this.denominator if (thisNumerator < otherNumerator) return -1 @@ -178,13 +178,13 @@ export default class Rational equalTo(other: Rational): boolean { - return this.compare(other) == 0 + return this.compare(other) === 0 } notEqualTo(other: Rational): boolean { - return this.compare(other) != 0 + return this.compare(other) !== 0 } @@ -223,7 +223,7 @@ export default class Rational if (b === null) return a - if (a.compare(b!) > 0) + if (a.compare(b) > 0) return a else return b @@ -241,20 +241,20 @@ export default class Rational if (b === null) return a - if (a.compare(b!) < 0) + if (a.compare(b) < 0) return a else return b } - max(other: Rational | null): Rational + max(other: Rational | null): Rational { return Rational.max(this, other)! } - min(other: Rational | null): Rational + min(other: Rational | null): Rational { return Rational.min(this, other)! } @@ -279,7 +279,7 @@ export default class Rational trySimplifyInPlaceBy(divider: number) { - while ((this.numerator % divider) == 0 && (this.denominator % divider) == 0) + while ((this.numerator % divider) === 0 && (this.denominator % divider) === 0) { this.numerator /= divider this.denominator /= divider @@ -289,10 +289,10 @@ export default class Rational toString(): string { - let integer = Math.floor(this.numerator / this.denominator) - let numerator = this.numerator % this.denominator + const integer = Math.floor(this.numerator / this.denominator) + const numerator = this.numerator % this.denominator - if (numerator == 0) + if (numerator === 0) return integer.toString() else return integer.toString() + " + " + numerator.toString() + "/" + this.denominator.toString() From fed33b271a1203da76c7464ebf52228063074bdb Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Mon, 22 Dec 2025 14:04:06 -0300 Subject: [PATCH 06/20] start chord inspector --- index.html | 9 +- src/inspector/Inspector.tsx | 305 +-------------------------- src/inspector/InspectorChord.tsx | 162 ++++++++++++++ src/inspector/InspectorInsert.tsx | 81 +++++++ src/inspector/InspectorKeyChange.tsx | 281 ++++++++++++++++++++++++ src/inspector/index.ts | 4 + src/main.tsx | 10 +- src/theory/index.ts | 3 +- src/theory/scale.ts | 7 + src/theory/utils.ts | 6 + src/timeline/draw.ts | 164 +++++++------- src/timeline/lane_notes.ts | 22 +- src/utils/canvasUtils.ts | 47 +++++ 13 files changed, 714 insertions(+), 387 deletions(-) create mode 100644 src/inspector/InspectorChord.tsx create mode 100644 src/inspector/InspectorInsert.tsx create mode 100644 src/inspector/InspectorKeyChange.tsx create mode 100644 src/inspector/index.ts diff --git a/index.html b/index.html index c406557..276b133 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,14 @@ TheoryTracker2 - + + + + diff --git a/src/inspector/Inspector.tsx b/src/inspector/Inspector.tsx index 6281473..a18a597 100644 --- a/src/inspector/Inspector.tsx +++ b/src/inspector/Inspector.tsx @@ -1,5 +1,6 @@ import * as Solid from "solid-js" import * as Global from "../state.ts" +import * as Inspector from "./index.ts" import * as Project from "../project" import * as Timeline from "../timeline" import * as Theory from "../theory" @@ -7,7 +8,7 @@ import Rect from "../utils/rect.ts" import { styled } from "solid-styled-components" -export function Inspector(props: {}) +export function InspectorRoot(props: {}) { const selectedIdsRaw = Solid.createMemo(() => { const timeline = Global.get().timeline @@ -46,313 +47,25 @@ export function Inspector(props: {}) const elem = firstElem() if (elem?.type === "keyChange") - return - return + return }) return
- { `${selectedIds().count()} selected` }
+
{ `${selectedIds().count()} selected` }
{ inspectorKind() }
-} - - -export function InspectorInsert(props: { -}) -{ - const makeInsertKeyChange = () => { - const key = Theory.Key.parse("C Major") - - const insert = () => { - const project = Global.get().project - const timeline = Global.get().timeline - const time = timeline.cursor.time1 - const id = project.root.nextId - const keyCh = Project.makeKeyChange(project.root.keyChangeTrackId, time, key) - project.root = Project.upsertElement(project.root, keyCh) - Timeline.selectionClear(timeline) - Timeline.selectionAdd(timeline, id) - Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) - Global.refresh() - } - - return - } - - - return <> - { makeInsertKeyChange() } - -} - - -export function InspectorKeyChange(props: { - value: Project.KeyChange, - setValue: (newValue: Project.KeyChange) => void, -}) -{ - const tonic = props.value.key.tonic - const scale = props.value.key.scale - - const circleOfFifthsOffset = scale.metadata?.circleOfFifthsOffset ?? 0 - - - const makeTonicButton = (circleOfFifthsIndex: number) => { - const letter = Theory.Utils.circleOfFifthsToLetter(circleOfFifthsIndex + circleOfFifthsOffset) - const accidental = Theory.Utils.circleOfFifthsToAccidental(circleOfFifthsIndex + circleOfFifthsOffset) - const letterStr = Theory.Utils.letterToStr(letter) - const accidentalStr = Theory.Utils.accidentalToStr(accidental) - const pitchName = new Theory.PitchName(letter, accidental) - const key = new Theory.Key(pitchName, props.value.key.scale) - - const apply = () => { - props.setValue({...props.value, key }) - } - - const angleArc = Math.PI * 2 / 12 - const angle1 = (circleOfFifthsIndex - 0.5) * angleArc - const angle2 = (circleOfFifthsIndex + 0.5) * angleArc - const trigX1 = Math.sin(angle1) - const trigX2 = Math.sin(angle2) - const trigY1 = -Math.cos(angle1) - const trigY2 = -Math.cos(angle2) - const radius1 = 50 - const radius2 = 100 - const angleMargin1 = 0.025 - const angleMargin2 = angleMargin1 * (radius1 / radius2) - const subdiv = 4 - - let path = "" - for (let i = 0; i <= subdiv; i++) - { - const t = i / subdiv - const angle = angle1 + (angle2 - angle1) * t + (angleMargin1 - angleMargin1 * 2 * t) - path += `${ i == 0 ? "M" : "L"} ${Math.sin(angle) * radius1} ${-Math.cos(angle) * radius1} ` - } - for (let i = 0; i <= subdiv; i++) - { - const t = 1 - i / subdiv - const angle = angle1 + (angle2 - angle1) * t + (angleMargin2 - angleMargin2 * 2 * t) - path += `L ${Math.sin(angle) * radius2} ${-Math.cos(angle) * radius2} ` - } - path += "Z" - - return - - - { letterStr }{ accidentalStr } - - - } - - - const applyScale = (scaleId: string) => { - const scale = Theory.Scale.fromId(scaleId) - const key = new Theory.Key(props.value.key.tonic, scale) - props.setValue({...props.value, key }) - } - - - const makeScaleOption = (scaleMeta: Theory.ScaleMetadata) => { - return -
- { scaleMeta.names[0] } - { " " } -
- - { (chroma, i) => { - const degree = i() - const chromaCMajor = Theory.Utils.degreeToChromaInCMajor(degree) - const accidental = chroma - chromaCMajor - const accidentalStr = Theory.Utils.accidentalToStr(accidental) - - return
0 ? "red" : - accidental < 0 ? "blue" : - undefined, - }}> - { `${accidentalStr}${(degree + 1).toString()} ` } -
- }} -
-
-
- } - - - const makeScaleOption2 = (scaleMeta: Theory.ScaleMetadata) => { - const isSelected = scaleMeta.id === scale.id - let button: HTMLButtonElement | undefined = undefined - - Solid.createEffect(() => { - if (isSelected && button) - (button as HTMLButtonElement).scrollIntoView({ behavior: "instant", block: "center" }) - }) - - return applyScale(scaleMeta.id) } - > - { scaleMeta.names[0] } - - - { (chroma, i) => { - const degree = i() - const chromaCMajor = Theory.Utils.degreeToChromaInCMajor(degree) - const accidental = chroma - chromaCMajor - const accidentalStr = Theory.Utils.accidentalToStr(accidental) - - return
0 ? "#f88" : - accidental < 0 ? "#88f" : - undefined, - }}> - { `${accidentalStr}${(degree + 1).toString()} ` } -
- }} -
-
-
- } - - - return <> -

Key Change

- - - - - - { (index, i) => makeTonicButton(index) } - - - - - - { (scaleMeta, i) => makeScaleOption2(scaleMeta) } - - - - {/* applyScale(ev.target.value) } - > - - - { (scaleMeta, i) => makeScaleOption(scaleMeta) } - - */} - - - -} - - -const Layout = styled.div` - display: grid; - grid-template: auto / auto auto; - justify-content: center; - column-gap: 1em; -` - - -const CircleOfFifthsPath = styled.path<{ - $selected: boolean, -}>` - cursor: pointer; - fill: #444; - - &:hover { - fill: #666; - } - - ${ props => props.$selected ? "fill: #06a;" : "" } -` - - -const ScaleList = styled.div` - width: 20em; - height: 15em; - overflow-x: hidden; - overflow-y: auto; - border-radius: 0.25em; -` - - -const ScaleButton = styled.div<{ - $selected: boolean, -}>` - display: grid; - grid-template: auto auto / auto; - justify-items: start; - justify-content: start; - user-select: none; - cursor: pointer; - - width: 100%; - margin: 0.25em; - padding: 0.25em; - border-radius: 0.25em; - background-color: #444; - - &:hover { - background-color: #666; - } - - ${ props => props.$selected ? "background-color: #06a;" : "" } -` - - -const StyledSelect = styled.select` - /*appearance: base-select; - - &::picker(select) { - appearance: base-select; - }*/ -` - - -const OptionScale = styled.option` - margin-top: 0.5em; - margin-bottom: 0.5em; -` \ No newline at end of file +} \ No newline at end of file diff --git a/src/inspector/InspectorChord.tsx b/src/inspector/InspectorChord.tsx new file mode 100644 index 0000000..a42deb3 --- /dev/null +++ b/src/inspector/InspectorChord.tsx @@ -0,0 +1,162 @@ +import * as Solid from "solid-js" +import * as Global from "../state.ts" +import * as Inspector from "./index.ts" +import * as Project from "../project" +import * as Timeline from "../timeline" +import * as Theory from "../theory" +import Rect from "../utils/rect.ts" +import * as CanvasUtils from "../utils/canvasUtils.ts" +import { styled } from "solid-styled-components" + + +export function InspectorChord(props: { + value?: Project.Chord, + setValue: (newValue: Project.Chord) => void, + key: Theory.Key, +}) +{ + const makeChordButton = (degree: number) => { + const root = props.key.midiForDegree(degree) + + let pitches = [0] + pitches.push(props.key.midiForDegree(degree + 2) - root) + pitches.push(props.key.midiForDegree(degree + 4) - root) + + /*if (baseChordType >= 7) + pitches.push(props.key.midiForDegree(degree + 6) - root) + + if (baseChordType >= 9) + pitches.push(props.key.midiForDegree(degree + 8) - root) + + if (baseChordType >= 11) + pitches.push(props.key.midiForDegree(degree + 10) - root) + + if (baseChordType >= 13) + pitches.push(props.key.midiForDegree(degree + 12) - root)*/ + + const kind = Theory.Chord.kindFromPitches(pitches) + const chord = new Theory.Chord(root, kind, 0, []) + + let canvas: HTMLCanvasElement = undefined! + + Solid.createEffect(() => { + const prefs = Global.get().prefs + const pixelRatio = window.devicePixelRatio + const rect = canvas.getBoundingClientRect() + canvas.width = Math.floor(rect.width * pixelRatio) + canvas.height = Math.floor(rect.height * pixelRatio) + const ctx = canvas.getContext("2d")! + CanvasUtils.drawChord( + ctx, + Rect.fromVertices(0, 0, canvas.width, canvas.height), + prefs, + chord, + props.key) + }) + + return + + + } + + return <> + +

Chord

+ + + + { (chroma, degree) => makeChordButton(degree()) } + + + +
+ +} + + +const Layout = styled.div` + display: grid; + grid-template: auto 1fr / auto auto; + width: 100%; + height: 100%; + min-height: 0; + justify-content: center; + justify-items: center; + align-content: center; + align-items: center; + column-gap: 1em; +` + + +const LayoutMainButtons = styled.div` + display: grid; + grid-template: auto / repeat(7, 1fr); + width: 100%; + height: 100%; + justify-content: center; + justify-items: center; + align-content: center; + align-items: center; + column-gap: 1em; +` + + +const ChordButton = styled.button<{ +}>` + border: 0; + margin: 0; + padding: 0; + background-color: transparent; +` + + +const ChordCanvas = styled.canvas<{ +}>` + width: 6em; + height: 3em; +` + + +const ScaleButton = styled.div<{ + $selected: boolean, +}>` + display: grid; + grid-template: auto auto / auto; + justify-items: start; + justify-content: start; + user-select: none; + cursor: pointer; + + width: 90%; + margin: 0.25em; + padding: 0.25em 0.5em; + border-radius: 0.25em; + background-color: var(--theme-buttonBkg); + + &:hover { + background-color: var(--theme-buttonBkgHover); + } + + &:active { + background-color: var(--theme-buttonBkgPress); + } + + ${ props => props.$selected ? "background-color: var(--theme-buttonBkgSelected);" : "" } +` + + +const StyledSelect = styled.select` + /*appearance: base-select; + + &::picker(select) { + appearance: base-select; + }*/ +` + + +const OptionScale = styled.option` + margin-top: 0.5em; + margin-bottom: 0.5em; +` \ No newline at end of file diff --git a/src/inspector/InspectorInsert.tsx b/src/inspector/InspectorInsert.tsx new file mode 100644 index 0000000..87ffbc0 --- /dev/null +++ b/src/inspector/InspectorInsert.tsx @@ -0,0 +1,81 @@ +import * as Solid from "solid-js" +import * as Global from "../state.ts" +import * as Inspector from "./index.ts" +import * as Project from "../project" +import * as Timeline from "../timeline" +import * as Theory from "../theory" +import Rect from "../utils/rect.ts" +import { styled } from "solid-styled-components" + + +export function InspectorInsert(props: { +}) +{ + const time = Solid.createMemo(() => { + const timeline = Global.get().timeline + return timeline.cursor.time1 + }) + + const key = Solid.createMemo(() => { + const project = Global.get().project + return Project.keyAt(project.root, project.root.noteTrackId, time()) + }) + + const insertKeyChange = () => { + const project = Global.get().project + const timeline = Global.get().timeline + const time = timeline.cursor.time1 + const id = project.root.nextId + const key = Theory.Key.parse("C Major") + const keyCh = Project.makeKeyChange(project.root.keyChangeTrackId, time, key) + project.root = Project.upsertElement(project.root, keyCh) + Timeline.selectionClear(timeline) + Timeline.selectionAdd(timeline, id) + Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) + timeline.cursor.visible = false + Global.refresh() + } + + const insertMeterChange = () => { + const project = Global.get().project + const timeline = Global.get().timeline + const time = timeline.cursor.time1 + const id = project.root.nextId + const meter = Theory.Meter.parse("4 / 4") + const meterCh = Project.makeMeterChange(project.root.meterChangeTrackId, time, meter) + project.root = Project.upsertElement(project.root, meterCh) + Timeline.selectionClear(timeline) + Timeline.selectionAdd(timeline, id) + Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) + timeline.cursor.visible = false + Global.refresh() + } + + return + + +
+ {} } + /> +
+} + + +const Layout = styled.div` + display: grid; + grid-template: auto 1fr / auto auto; + width: 100%; + height: 100%; + min-height: 0; + justify-content: center; + justify-items: center; + align-content: center; + align-items: center; + column-gap: 1em; +` \ No newline at end of file diff --git a/src/inspector/InspectorKeyChange.tsx b/src/inspector/InspectorKeyChange.tsx new file mode 100644 index 0000000..8c5f106 --- /dev/null +++ b/src/inspector/InspectorKeyChange.tsx @@ -0,0 +1,281 @@ +import * as Solid from "solid-js" +import * as Global from "../state.ts" +import * as Inspector from "./index.ts" +import * as Project from "../project" +import * as Timeline from "../timeline" +import * as Theory from "../theory" +import Rect from "../utils/rect.ts" +import { styled } from "solid-styled-components" + + +export function InspectorKeyChange(props: { + value: Project.KeyChange, + setValue: (newValue: Project.KeyChange) => void, +}) +{ + const tonic = props.value.key.tonic + const scale = props.value.key.scale + + const circleOfFifthsOffset = scale.metadata?.circleOfFifthsOffset ?? 0 + + + const makeTonicButton = (circleOfFifthsIndex: number) => { + const letter = Theory.Utils.circleOfFifthsToLetter(circleOfFifthsIndex + circleOfFifthsOffset) + const accidental = Theory.Utils.circleOfFifthsToAccidental(circleOfFifthsIndex + circleOfFifthsOffset) + const letterStr = Theory.Utils.letterToStr(letter) + const accidentalStr = Theory.Utils.accidentalToStr(accidental) + const pitchName = new Theory.PitchName(letter, accidental) + const key = new Theory.Key(pitchName, props.value.key.scale) + + const apply = () => { + props.setValue({...props.value, key }) + } + + const angleArc = Math.PI * 2 / 12 + const angle1 = (circleOfFifthsIndex - 0.5) * angleArc + const angle2 = (circleOfFifthsIndex + 0.5) * angleArc + const trigX1 = Math.sin(angle1) + const trigX2 = Math.sin(angle2) + const trigY1 = -Math.cos(angle1) + const trigY2 = -Math.cos(angle2) + const radius1 = 50 + const radius2 = 100 + const angleMargin1 = 0.025 + const angleMargin2 = angleMargin1 * (radius1 / radius2) + const subdiv = 4 + + let path = "" + for (let i = 0; i <= subdiv; i++) + { + const t = i / subdiv + const angle = angle1 + (angle2 - angle1) * t + (angleMargin1 - angleMargin1 * 2 * t) + path += `${ i == 0 ? "M" : "L"} ${Math.sin(angle) * radius1} ${-Math.cos(angle) * radius1} ` + } + for (let i = 0; i <= subdiv; i++) + { + const t = 1 - i / subdiv + const angle = angle1 + (angle2 - angle1) * t + (angleMargin2 - angleMargin2 * 2 * t) + path += `L ${Math.sin(angle) * radius2} ${-Math.cos(angle) * radius2} ` + } + path += "Z" + + return + + + { letterStr }{ accidentalStr } + + + } + + + const applyScale = (scaleId: string) => { + const scale = Theory.Scale.fromId(scaleId) + const key = new Theory.Key(props.value.key.tonic, scale) + props.setValue({...props.value, key }) + } + + + const makeScaleOption = (scaleMeta: Theory.ScaleMetadata) => { + return +
+ { scaleMeta.names[0] } + { " " } +
+ + { (chroma, i) => { + const degree = i() + const chromaCMajor = Theory.Utils.degreeToChromaInCMajor(degree) + const accidental = chroma - chromaCMajor + const accidentalStr = Theory.Utils.accidentalToStr(accidental) + + return
0 ? "red" : + accidental < 0 ? "blue" : + undefined, + }}> + { `${accidentalStr}${(degree + 1).toString()} ` } +
+ }} +
+
+
+ } + + + const makeScaleOption2 = (scaleMeta: Theory.ScaleMetadata) => { + const isSelected = scaleMeta.id === scale.id + let button: HTMLButtonElement | undefined = undefined + + Solid.createEffect(() => { + if (isSelected && button) + (button as HTMLButtonElement).scrollIntoView({ behavior: "instant", block: "center" }) + }) + + return applyScale(scaleMeta.id) } + > + { scaleMeta.names[0] } + + + { (chroma, i) => { + const degree = i() + const chromaCMajor = Theory.Utils.degreeToChromaInCMajor(degree) + const accidental = chroma - chromaCMajor + const accidentalStr = Theory.Utils.accidentalToStr(accidental) + + return
0 ? "#f88" : + accidental < 0 ? "#88f" : + undefined, + }}> + { `${accidentalStr}${(degree + 1).toString()} ` } +
+ }} +
+
+
+ } + + + return <> + +

Key Change

+ + + + { (index, i) => makeTonicButton(index) } + + + + + + { (scaleMeta, i) => makeScaleOption2(scaleMeta) } + + + + {/* applyScale(ev.target.value) } + > + + + { (scaleMeta, i) => makeScaleOption(scaleMeta) } + + */} + +
+ +} + + +const Layout = styled.div` + display: grid; + grid-template: auto 1fr / auto auto; + width: 100%; + height: 100%; + min-height: 0; + justify-content: center; + justify-items: center; + align-content: center; + align-items: center; + column-gap: 1em; +` + + +const CircleOfFifthsPath = styled.path<{ + $selected: boolean, +}>` + cursor: pointer; + fill: var(--theme-buttonBkg); + + &:hover { + fill: var(--theme-buttonBkgHover); + } + + &:active { + fill: var(--theme-buttonBkgPress); + } + + ${ props => props.$selected ? "fill: var(--theme-buttonBkgSelected);" : "" } +` + + +const ScaleList = styled.div` + width: 20em; + height: 100%; + min-height: 0; + overflow-x: hidden; + overflow-y: scroll; + scrollbar-gutter: stable; + border-radius: 0.25em; +` + + +const ScaleButton = styled.div<{ + $selected: boolean, +}>` + display: grid; + grid-template: auto auto / auto; + justify-items: start; + justify-content: start; + user-select: none; + cursor: pointer; + + width: 90%; + margin: 0.25em; + padding: 0.25em 0.5em; + border-radius: 0.25em; + background-color: var(--theme-buttonBkg); + + &:hover { + background-color: var(--theme-buttonBkgHover); + } + + &:active { + background-color: var(--theme-buttonBkgPress); + } + + ${ props => props.$selected ? "background-color: var(--theme-buttonBkgSelected);" : "" } +` + + +const StyledSelect = styled.select` + /*appearance: base-select; + + &::picker(select) { + appearance: base-select; + }*/ +` + + +const OptionScale = styled.option` + margin-top: 0.5em; + margin-bottom: 0.5em; +` \ No newline at end of file diff --git a/src/inspector/index.ts b/src/inspector/index.ts new file mode 100644 index 0000000..752dd6b --- /dev/null +++ b/src/inspector/index.ts @@ -0,0 +1,4 @@ +export { InspectorRoot } from "./Inspector.tsx" +export { InspectorInsert } from "./InspectorInsert.tsx" +export { InspectorKeyChange } from "./InspectorKeyChange.tsx" +export { InspectorChord } from "./InspectorChord.tsx" \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index e4a5a1a..3e871f9 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -3,7 +3,7 @@ import * as SolidWeb from "solid-js/web" import { styled } from "solid-styled-components" import * as State from "./state.ts" import * as Timeline from "./timeline" -import { Inspector } from "./inspector/Inspector.tsx" +import * as Inspector from "./inspector" function App() @@ -16,7 +16,7 @@ function App()
- + } @@ -28,9 +28,15 @@ const AppRoot = styled.div` width: 100%; height: 100%; min-height: 0; + box-sizing: border-box; background-color: #101215; color: #fff; font-family: Verdana; + + --theme-buttonBkg: #444; + --theme-buttonBkgHover: #555; + --theme-buttonBkgPress: #333; + --theme-buttonBkgSelected: #06a; ` diff --git a/src/theory/index.ts b/src/theory/index.ts index b81a51b..908eb3b 100644 --- a/src/theory/index.ts +++ b/src/theory/index.ts @@ -1,6 +1,7 @@ export { default as Pitch } from "./pitch.ts" export { default as PitchName } from "./pitchName.ts" -export { default as Scale, ScaleMetadata } from "./scale.ts" +export { default as Scale } from "./scale.ts" +export { ScaleMetadata } from "./scale.ts" export { default as Key } from "./key.ts" export { default as Meter } from "./meter.ts" export { default as Chord } from "./chord.ts" diff --git a/src/theory/scale.ts b/src/theory/scale.ts index b0bedf3..6b8094c 100644 --- a/src/theory/scale.ts +++ b/src/theory/scale.ts @@ -70,6 +70,13 @@ export const knownScales: ScaleMetadata[] = [ circleOfFifthsOffset: 4, }, + { + id: "harmaj", + names: ["Harmonic Major"], + chromas: [0, 2, 4, 5, 7, 8, 11], + mode: 0, + circleOfFifthsOffset: 0, + }, { id: "dharmaj", names: ["Double Harmonic Major"], diff --git a/src/theory/utils.ts b/src/theory/utils.ts index a17d370..ca061b5 100644 --- a/src/theory/utils.ts +++ b/src/theory/utils.ts @@ -39,6 +39,12 @@ export default class Utils static accidentalToStr(accidental: number, useUnicode: boolean = true): string { + if (useUnicode && accidental === 2) + return "𝄪" + + if (useUnicode && accidental === -2) + return "𝄫" + if (accidental < 0) return (useUnicode ? "\u{266d}" : "b").repeat(-accidental) else diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index 8d7198a..c65c0fc 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -4,6 +4,7 @@ import * as Prefs from "../prefs.ts" import * as Theory from "../theory" import Rational from "../utils/rational.ts" import * as CanvasUtils from "../utils/canvasUtils.ts" +import Rect from "../utils/rect.ts" export function draw( @@ -191,85 +192,63 @@ function drawElements( } else if (element.kind === "chord") - { - ctx.save() - ctx.beginPath() - ctx.roundRect( - element.rect.x, - element.rect.y, - element.rect.w, - element.rect.h, - 5) - ctx.clip() - - const x1 = element.rect.x + (element.cutStart ? -16 : 0) - const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) + drawChord(timeline, prefs, ctx, element) - const key = element.key - const mode = key.scale.metadata!.mode - const fillStyle = CanvasUtils.fillStyleForDegree( - ctx, - key.degreeForMidi(element.chord.chord.rootChroma) + mode, - false) - - ctx.fillStyle = fillStyle - ctx.beginPath() - ctx.roundRect( - x1, - element.rect.y, - x2 - x1, - element.rect.h, - 5) - ctx.fill() + else if (element.kind === "marker") + drawMarker(timeline, prefs, ctx, element) + } +} - const ornamentH = 6 - ctx.fillStyle = "#ddd" - ctx.fillRect( - x1, - element.rect.y + ornamentH, - x2 - x1, - element.rect.h - ornamentH * 2) - ctx.fillStyle = "#000" - ctx.font = `${prefs.timeline.fontWeightChord} ${element.rect.h * 0.65}px ${prefs.timeline.fontNameChord}` - ctx.textAlign = "center" - ctx.textBaseline = "middle" - ctx.fillText( - element.chord.chord.romanBase(element.key) + - element.chord.chord.romanSup(element.key) + - element.chord.chord.romanSub(element.key), - element.rect.xCenter, - element.rect.yCenter + element.rect.h * 0.05, - element.rect.w * 0.95) - - ctx.beginPath() - ctx.roundRect( - x1, - element.rect.y, - x2 - x1, - element.rect.h, - 5) - - if (timeline.hover?.id === element.id) - { - ctx.fillStyle = "#fff8" - ctx.fill() - } +function drawChord( + timeline: Timeline.State, + prefs: Prefs.Prefs, + ctx: CanvasRenderingContext2D, + element: Timeline.LayoutElementChord) +{ + ctx.save() + ctx.beginPath() + ctx.roundRect( + element.rect.x, + element.rect.y, + element.rect.w, + element.rect.h, + 5) + ctx.clip() - if (element.id !== undefined && - timeline.selection.has(element.id)) - { - ctx.strokeStyle = "#fff8" - ctx.lineWidth = 6 - ctx.stroke() - } + const x1 = element.rect.x + (element.cutStart ? -16 : 0) + const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) - ctx.restore() - } + CanvasUtils.drawChord( + ctx, + Rect.fromVertices(x1, element.rect.y, x2, element.rect.y2), + prefs, + element.chord.chord, + element.key) + + ctx.beginPath() + ctx.roundRect( + x1, + element.rect.y, + x2 - x1, + element.rect.h, + 5) + + if (timeline.hover?.id === element.id) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } - else if (element.kind === "marker") - drawMarker(timeline, prefs, ctx, element) + if (element.id !== undefined && + timeline.selection.has(element.id)) + { + ctx.strokeStyle = "#fff8" + ctx.lineWidth = 6 + ctx.stroke() } + + ctx.restore() } @@ -312,14 +291,18 @@ function drawMarker( ctx.textAlign = "left" ctx.textBaseline = "middle" ctx.lineWidth = 8 - ctx.strokeText( - text, - element.rect.x2 + 8, - element.rect.yCenter) - ctx.fillText( - text, - element.rect.x2 + 8, - element.rect.yCenter) + + if (element.rect.xCenter >= 0) + { + ctx.strokeText( + text, + element.rect.x2 + 8, + element.rect.yCenter) + ctx.fillText( + text, + element.rect.x2 + 8, + element.rect.yCenter) + } ctx.beginPath() ctx.moveTo(element.rect.x, element.rect.y) @@ -538,7 +521,26 @@ export function drawLaneBkgOctaves( const labelX = Math.max(x1 + 5, 5) if (needsOctaveLabels && labelX + 30 < x2) { - ctx.fillText(key.tonic.str + (i + 5).toString(), labelX, y - 1) + for (let j = 0; j < scaleLength; j += 1) + { + const pitchName = key.namedPitches[j] + const chroma = key.scale.chromas[j] + key.tonic.chroma + ((i + 5) * 12) + const octave = Math.floor(chroma / 12) + ctx.fillText( + pitchName.str, + labelX, + y - 1 - j * timeline.noteRowH) + + if (j === 0) + { + const letterMeasure = ctx.measureText(pitchName.str) + ctx.fillText( + octave.toString(), + labelX + Math.max(14, letterMeasure.width), + y - 1 - j * timeline.noteRowH) + } + } + drewOctaveLabels = true } diff --git a/src/timeline/lane_notes.ts b/src/timeline/lane_notes.ts index 2ab8aed..903d830 100644 --- a/src/timeline/lane_notes.ts +++ b/src/timeline/lane_notes.ts @@ -134,7 +134,7 @@ export class LaneNotes extends Timeline.Lane } } - let keyChPrev = timeline.layout.keyRegions[0].keyCh1 + let keyChCurrent = timeline.layout.keyRegions[0].keyCh1 for (const elem of iterMarkersForLayout(timeline, project, timeline.layout.range)) { @@ -144,6 +144,19 @@ export class LaneNotes extends Timeline.Lane elem.type === "keyChange" ? 0 : 1, elem.range.start) + + let keyCh: Project.KeyChange | undefined = undefined + let keyChPrev: Project.KeyChange | undefined = undefined + if (elem.type === "keyChange") + { + keyCh = elem + + if (keyCh.id !== keyChCurrent.id && + keyChCurrent.id >= 0) + keyChPrev = keyChCurrent + + keyChCurrent = keyCh + } this.add({ kind: "marker", @@ -152,8 +165,8 @@ export class LaneNotes extends Timeline.Lane rect, priority: 1, zIndex: 1, - keyCh: elem.type === "keyChange" ? elem : undefined, - keyChPrev: elem.type === "keyChange" ? keyChPrev : undefined, + keyCh, + keyChPrev, meterCh: elem.type === "meterChange" ? elem : undefined, }) @@ -162,9 +175,6 @@ export class LaneNotes extends Timeline.Lane keyCh: elem.type === "keyChange" ? elem : undefined, meterCh: elem.type === "meterChange" ? elem : undefined, }) - - if (elem.type === "keyChange") - keyChPrev = elem } } diff --git a/src/utils/canvasUtils.ts b/src/utils/canvasUtils.ts index 45a5ec7..5e85057 100644 --- a/src/utils/canvasUtils.ts +++ b/src/utils/canvasUtils.ts @@ -1,5 +1,7 @@ import * as Theory from "../theory" +import * as Prefs from "../prefs" import * as MathUtils from "./mathUtils" +import Rect from "./rect" const fillPatterns = new Map() @@ -48,4 +50,49 @@ export function fillStyleForDegree(ctx: CanvasRenderingContext2D, degree: number const pattern = ctx.createPattern(canvas, "repeat") fillPatterns.set(cacheKey, pattern) return pattern +} + + +export function drawChord( + ctx: CanvasRenderingContext2D, + rect: Rect, + prefs: Prefs.Prefs, + chord: Theory.Chord, + key: Theory.Key) +{ + const mode = key.scale.metadata!.mode + const fillStyle = fillStyleForDegree( + ctx, + key.degreeForMidi(chord.rootChroma) + mode, + false) + + ctx.fillStyle = fillStyle + ctx.beginPath() + ctx.roundRect( + rect.x, + rect.y, + rect.w, + rect.h, + 5) + ctx.fill() + + const ornamentH = 6 + ctx.fillStyle = "#ddd" + ctx.fillRect( + rect.x, + rect.y + ornamentH, + rect.w, + rect.h - ornamentH * 2) + + ctx.fillStyle = "#000" + ctx.font = `${prefs.timeline.fontWeightChord} ${rect.h * 0.65}px ${prefs.timeline.fontNameChord}` + ctx.textAlign = "center" + ctx.textBaseline = "middle" + ctx.fillText( + chord.romanBase(key) + + chord.romanSup(key) + + chord.romanSub(key), + rect.xCenter, + rect.yCenter + rect.h * 0.05, + rect.w * 0.95) } \ No newline at end of file From 592dabfe0a32d837847cd800719505da3ed89891 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Tue, 23 Dec 2025 21:22:03 -0300 Subject: [PATCH 07/20] revamp chord internals --- src/inspector/InspectorChord.tsx | 131 +++++--- src/main.tsx | 11 +- src/project/root.ts | 6 +- src/state.ts | 2 - src/theory/chord.ts | 504 +++++++++++++++++++++++++------ src/theory/key.ts | 6 +- src/theory/scale.ts | 2 + src/theory/utils.ts | 37 ++- src/timeline/Element.tsx | 6 +- src/timeline/draw.ts | 5 +- src/timeline/key_down.ts | 20 +- src/timeline/lane_chords.ts | 7 +- src/utils/canvasUtils.ts | 89 +++++- 13 files changed, 634 insertions(+), 192 deletions(-) diff --git a/src/inspector/InspectorChord.tsx b/src/inspector/InspectorChord.tsx index a42deb3..a9d422d 100644 --- a/src/inspector/InspectorChord.tsx +++ b/src/inspector/InspectorChord.tsx @@ -15,62 +15,94 @@ export function InspectorChord(props: { key: Theory.Key, }) { - const makeChordButton = (degree: number) => { - const root = props.key.midiForDegree(degree) - - let pitches = [0] - pitches.push(props.key.midiForDegree(degree + 2) - root) - pitches.push(props.key.midiForDegree(degree + 4) - root) + const [seventh, setSeventh] = Solid.createSignal( + !props.value ? false : props.value?.chord.add7 !== undefined) + + const [suspended2, setSuspended2] = Solid.createSignal( + !props.value ? false : + props.value?.chord.sus2 !== undefined && + props.value?.chord.add3 === undefined) + + const [suspended4, setSuspended4] = Solid.createSignal( + !props.value ? false : + props.value?.chord.sus4 !== undefined && + props.value?.chord.add3 === undefined) + + const makeChordButton = Solid.createMemo(() => { + const withAdded7 = seventh() + const withSus2 = suspended2() + const withSus4 = suspended4() - /*if (baseChordType >= 7) - pitches.push(props.key.midiForDegree(degree + 6) - root) - - if (baseChordType >= 9) - pitches.push(props.key.midiForDegree(degree + 8) - root) - - if (baseChordType >= 11) - pitches.push(props.key.midiForDegree(degree + 10) - root) - - if (baseChordType >= 13) - pitches.push(props.key.midiForDegree(degree + 12) - root)*/ - - const kind = Theory.Chord.kindFromPitches(pitches) - const chord = new Theory.Chord(root, kind, 0, []) - - let canvas: HTMLCanvasElement = undefined! - - Solid.createEffect(() => { - const prefs = Global.get().prefs - const pixelRatio = window.devicePixelRatio - const rect = canvas.getBoundingClientRect() - canvas.width = Math.floor(rect.width * pixelRatio) - canvas.height = Math.floor(rect.height * pixelRatio) - const ctx = canvas.getContext("2d")! - CanvasUtils.drawChord( - ctx, - Rect.fromVertices(0, 0, canvas.width, canvas.height), - prefs, - chord, - props.key) - }) - - return - - - } + return (degree: number) => { + let chord = Theory.Chord.fromDiatonicTriad(props.key, degree) + + if (withAdded7) + chord = chord.withAdded7(props.key) + + if (withSus2) + chord = chord.withSuspended2(props.key) + + if (withSus4) + chord = chord.withSuspended4(props.key) + + console.log(degree, chord) + + let canvas: HTMLCanvasElement = undefined! + + Solid.createEffect(() => { + const prefs = Global.get().prefs + const pixelRatio = window.devicePixelRatio + const rect = canvas.getBoundingClientRect() + canvas.width = Math.floor(rect.width * pixelRatio) + canvas.height = Math.floor(rect.height * pixelRatio) + const ctx = canvas.getContext("2d")! + CanvasUtils.drawChord( + ctx, + Rect.fromVertices(0, 0, canvas.width, canvas.height), + prefs, + chord, + props.key) + }) + + return + + + } + }) return <>

Chord

- - { (chroma, degree) => makeChordButton(degree()) } - + { props.key.chroma.map((chroma, degree) => + makeChordButton()(degree) + )} +
+ setSeventh(ev.target.checked) } + /> 7 +
+ setSuspended2(ev.target.checked) } + /> sus2 +
+ setSuspended4(ev.target.checked) } + /> sus4 +
+
+
} @@ -78,7 +110,7 @@ export function InspectorChord(props: { const Layout = styled.div` display: grid; - grid-template: auto 1fr / auto auto; + grid-template: auto 1fr / auto auto auto; width: 100%; height: 100%; min-height: 0; @@ -93,6 +125,7 @@ const Layout = styled.div` const LayoutMainButtons = styled.div` display: grid; grid-template: auto / repeat(7, 1fr); + grid-column: 1 / -1; width: 100%; height: 100%; justify-content: center; @@ -115,7 +148,7 @@ const ChordButton = styled.button<{ const ChordCanvas = styled.canvas<{ }>` width: 6em; - height: 3em; + height: 3.5em; ` diff --git a/src/main.tsx b/src/main.tsx index 3e871f9..e675aaa 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -8,13 +8,9 @@ import * as Inspector from "./inspector" function App() { + State.get() + return -
- Hello, world! { State.get().test }
- -
@@ -23,11 +19,12 @@ function App() const AppRoot = styled.div` display: grid; - grid-template: auto 1fr 1fr / 1fr; + grid-template: 1fr 1fr / 1fr; margin: auto; width: 100%; height: 100%; min-height: 0; + padding: 2em 0; box-sizing: border-box; background-color: #101215; color: #fff; diff --git a/src/project/root.ts b/src/project/root.ts index 7c1d9a2..8793024 100644 --- a/src/project/root.ts +++ b/src/project/root.ts @@ -87,13 +87,13 @@ export function makeTest(): ImmutableRoot project = upsertElement(project, Project.makeNote( project.noteTrackId, Range.fromStartDuration(new Rational(i, 4), new Rational(1, 4)), - Theory.Utils.midiMiddleC + i)) + Theory.Utils.midiMiddleC - 12 + i)) - for (let i = 0; i < 4; i++) + for (let i = 0; i < 7; i++) project = upsertElement(project, Project.makeChord( project.chordTrackId, Range.fromStartDuration(new Rational(i * 4, 4), new Rational(4, 4)), - new Theory.Chord(i, 0))) + Theory.Chord.fromDiatonicTriad(Theory.Key.parse("C Major"), i))) return project } diff --git a/src/state.ts b/src/state.ts index 2222368..47583fe 100644 --- a/src/state.ts +++ b/src/state.ts @@ -10,7 +10,6 @@ const [state, setState] = export interface State { - test: number prefs: Prefs.Prefs project: Project.Mutable timeline: Timeline.State @@ -20,7 +19,6 @@ export interface State export function makeNew(): State { return { - test: 0, prefs: Prefs.makeNew(), project: { root: Project.makeTest() }, timeline: Timeline.makeNew(), diff --git a/src/theory/chord.ts b/src/theory/chord.ts index fec63ac..ca8e96c 100644 --- a/src/theory/chord.ts +++ b/src/theory/chord.ts @@ -1,21 +1,147 @@ -import * as MathUtils from "../utils/mathUtils.ts" -import Key from "./key.ts" -import Utils from "./utils.ts" +import * as Theory from "./index.ts" interface ChordMetadata { - pitches: number[] id: string - symbol: [boolean, string, string | null] name: string - startGroup?: string + + add3?: number + add5?: number + add7?: number + add9?: number + add11?: number + add13?: number + + suspended?: boolean + + nameBase?: string + nameSup?: string + nameSub?: string + + romanSup?: string + romanSub?: string + roman7?: number } export const chordKinds: ChordMetadata[] = [ - { pitches: [0, 4, 7], id: "M", symbol: [false, "", null], name: "Major", startGroup: "Triads" }, + { + id: "M", + name: "Major", + add3: 0, + add5: 0, + }, + { + id: "m", + name: "Minor", + add3: -1, + add5: 0, + nameBase: "m", + }, + { + id: "+", + name: "Augmented", + add3: 0, + add5: 1, + nameSup: "+", + romanSup: "+", + }, + { + id: "o", + name: "Diminished", + add3: -1, + add5: -1, + nameSup: "o", + romanSup: "o", + }, + { + id: "oo", + name: "Doubly-diminished", + add3: -2, + add5: -1, + nameSup: "oo", + romanSup: "oo", + }, + { + id: "dom7", + name: "Dominant Seventh", + add3: 0, + add5: 0, + add7: -1, + nameBase: "7", + roman7: -1, + }, + { + id: "maj7", + name: "Major Seventh", + add3: 0, + add5: 0, + add7: 0, + nameBase: "maj7", + }, + { + id: "min7", + name: "Minor Seventh", + add3: -1, + add5: 0, + add7: -1, + nameBase: "m7", + roman7: -1, + }, + { + id: "minmaj7", + name: "Minor-major Seventh", + add3: -1, + add5: 0, + add7: 0, + nameBase: "mM7", + }, + { + id: "aug7", + name: "Augmented Seventh", + add3: 0, + add5: 1, + add7: -1, + nameBase: "7", + nameSup: "(\u{266f}5)", + romanSup: "+", + }, + { + id: "augmaj7", + name: "Augmented Major Seventh", + add3: 0, + add5: 1, + add7: 0, + nameBase: "maj7", + nameSup: "(\u{266f}5)", + romanSup: "+", + }, + { + id: "dim7", + name: "Diminished Seventh", + add3: -1, + add5: -1, + add7: -2, + nameSup: "o7", + romanSup: "o", + roman7: -2, + }, + { + id: "halfdim7", + name: "Half-diminished Seventh", + add3: -1, + add5: -1, + add7: -1, + nameBase: "m7", + nameSup: "(\u{266d}5)", + romanSup: "ø", + roman7: -1, + }, +] + +/* { pitches: [0, 4, 7], id: "M", symbol: [false, "", null], name: "Major", startGroup: "Triads" }, { pitches: [0, 3, 7], id: "m", symbol: [true, "", null], name: "Minor" }, { pitches: [0, 4, 8], id: "+", symbol: [false, "", "+"], name: "Augmented" }, { pitches: [0, 3, 6], id: "o", symbol: [true, "", "o"], name: "Diminished" }, @@ -47,7 +173,7 @@ export const chordKinds: ChordMetadata[] = { pitches: [0, 3, 6, 9, 13], id: "ob9", symbol: [true, "", "o♭9"], name: "Diminished Minor Ninth" }, { pitches: [0, 3, 6, 10, 14], id: "%9", symbol: [true, "", "ø9"], name: "Half-Diminished Ninth" }, { pitches: [0, 3, 6, 10, 13], id: "%b9", symbol: [true, "", "ø♭9"], name: "Half-Diminished Minor Ninth" }, -] +]*/ export interface ChordSuggestion @@ -64,23 +190,106 @@ export default class Chord rootChroma: number - kind: number + degree: number inversion: number - modifiers: any + + sus2?: number + add3?: number + sus4?: number + add5?: number + add7?: number + add9?: number + add11?: number + add13?: number - constructor(rootChroma: number, kind: number, inversion: number = 0, modifiers: any[] = []) + constructor(rootChroma: number, inversion: number = 0) { this.rootChroma = rootChroma - this.kind = kind this.inversion = inversion - this.modifiers = modifiers } + + + clone() + { + const cloned = Object.assign({}, this) + Object.setPrototypeOf(cloned, Chord.prototype) + return cloned + } + + + withRoot(newRootChroma: number, newDegree: number) + { + const cloned = this.clone() + cloned.rootChroma = newRootChroma + cloned.degree = newDegree + return cloned + } - withChanges(obj: any): Chord + /*withChanges(obj: any): Chord { return Object.assign(new Chord(this.rootChroma, this.kind, this.inversion, this.modifiers), obj) + }*/ + + + static fromDiatonicTriad(key: Theory.Key, rootDegree: number) + { + const rootChroma = (key.tonic.chroma + key.scale.chromas[(rootDegree + 0) % key.scale.chromas.length]) % 12 + const chord = new Chord(rootChroma) + chord.degree = rootDegree + chord.add3 = Chord.diatonicDegree(key, 2, rootChroma, rootDegree) + chord.add5 = Chord.diatonicDegree(key, 4, rootChroma, rootDegree) + return chord + } + + + static diatonicDegree( + key: Theory.Key, + degree: number, + rootChroma: number, + rootDegree: number) + { + const chroma = Theory.Utils.mod( + key.tonic.chroma + + key.scale.chromas[(rootDegree + degree) % key.scale.chromas.length], + 12) + + return Theory.Utils.modAccidental( + chroma - + (rootChroma + Theory.Scale.majorScale.chromas[degree])) + } + + + withSuspended2(key: Theory.Key) + { + const chord = this.clone() + chord.sus2 = Chord.diatonicDegree(key, 1, this.rootChroma, this.degree) + return chord + } + + + withRemoved3() + { + const chord = this.clone() + chord.add3 = undefined + return chord + } + + + withSuspended4(key: Theory.Key) + { + const chord = this.clone() + chord.sus4 = Chord.diatonicDegree(key, 3, this.rootChroma, this.degree) + return chord + } + + + withAdded7(key: Theory.Key) + { + const chord = this.clone() + chord.add7 = Chord.diatonicDegree(key, 6, this.rootChroma, this.degree) + return chord } @@ -90,7 +299,7 @@ export default class Chord } - static kindFromPitches(pitches: number[]): number + /*static kindFromPitches(pitches: number[]): number { return chordKinds.findIndex(k => k.pitches.length === pitches.length && @@ -142,115 +351,216 @@ export default class Chord //console.log("suggestions", pitches, suggestions) return suggestions.slice(0, 10) - } + }*/ - get kindId(): string + chordKind(): ChordMetadata | undefined { - return chordKinds[this.kind].id - } - - - romanBase(key: Key): string - { - const degree = key.degreeForMidi(this.rootChroma) - const chordKind = chordKinds[this.kind] || { symbol: [false, "", "?"] } - - let roman = Math.floor(degree) - let accidental = 0 - if (Math.floor(degree) != degree) + const compare = (a: number | undefined, b: number | undefined) => { + if (a === b) + return true + + if (a === undefined || + b === undefined) + return false + + return Theory.Utils.mod(a, 12) === Theory.Utils.mod(b, 12) + } + + for (const meta of chordKinds) { - roman = MathUtils.mod(roman + 1, 7) - accidental = -1 + if (compare(meta.add3, this.add3) && + compare(meta.add5, this.add5) && + compare(meta.add7, this.add7)) + { + return meta + } } - let baseStr = Utils.accidentalToStr(accidental, true) + Utils.degreeToRomanStr(roman) - if (chordKind.symbol[0]) - baseStr = baseStr.toLowerCase() - - return baseStr + chordKind.symbol[1] + return undefined } - - - romanSup(key: Key): string + + + accidentalStrForRoman(key: Theory.Key, degree: number, accidental: number) { - const chordKind = chordKinds[this.kind] || { symbol: [false, "", "?"] } - - let supStr = chordKind.symbol[2] || "" - - if (this.modifiers) - { - if (this.modifiers.add9) - supStr += "(add9)" - - if (this.modifiers.add11) - supStr += "(add11)" - - if (this.modifiers.add13) - supStr += "(add13)" - - if (this.modifiers.no3) - supStr += "(no3)" - - if (this.modifiers.no5) - supStr += "(no5)" - } - - return supStr + const chroma = key.chromaForDegree(this.degree + degree) + const chromaInCMajor = this.rootChroma + Theory.Scale.majorScale.chromas[degree] + return Theory.Utils.accidentalToStr( + Theory.Utils.modAccidental( + chroma - chromaInCMajor - accidental)) + } + + + static accidentalStrForName(accidental: number) + { + return Theory.Utils.accidentalToStr(Theory.Utils.modAccidental(accidental)) } - romanSub(key: Key): string + str(key: Theory.Key) { - let subStr = "" - - if (this.modifiers) + const kind = this.chordKind() ?? { + id: "custom", + name: "Custom", + } + + let roman = this.degree % key.scale.chromas.length + let romanChroma = key.chromaForDegree(roman) + let accidental = Theory.Utils.accidentalFor(this.rootChroma, romanChroma) + + if (accidental < -1 || accidental > 1) { - if (this.modifiers.sus2) + for (let r = 0; r < 7; r++) { - if (this.modifiers.sus4) - subStr += "sus24" - else - subStr += "sus2" + const newRoman = (this.degree + r) % key.scale.chromas.length + const newRomanChroma = key.chromaForDegree(newRoman) + const newAccidental = Theory.Utils.accidentalFor(this.rootChroma, newRomanChroma) + if (Math.abs(newAccidental) < Math.abs(accidental)) + { + roman = newRoman + romanChroma = newRomanChroma + accidental = newAccidental + } } - else if (this.modifiers.sus4) - subStr += "sus4" } + + let accidentalStr = Theory.Utils.accidentalToStr(accidental, true) + + const isLowercase = + kind !== undefined && + this.add3 !== undefined && + this.add3 < 0 - return subStr + let nameBase = + Theory.Utils.lowercaseIf( + key.nameForChroma(this.rootChroma).strUnicode, + isLowercase) + + (kind.nameBase ?? "") + + let nameSup = kind.nameSup ?? "" + let nameSub = kind.nameSub ?? "" + + let romanBase = + accidentalStr + + Theory.Utils.lowercaseIf( + Theory.Utils.degreeToRomanStr(roman), + isLowercase) + + let romanSup = kind.romanSup ?? "" + let romanSub = kind.romanSub ?? "" + + const isSuspended = + this.sus2 !== undefined || + this.sus4 !== undefined + + if (this.sus2 !== undefined && + this.sus4 !== undefined) + { + nameSub += `sus${ Chord.accidentalStrForName(this.sus2) }2${ Chord.accidentalStrForName(this.sus4) }4` + romanSub += `sus${ this.accidentalStrForRoman(key, 1, this.sus2) }2${ this.accidentalStrForRoman(key, 3, this.sus4) }4` + } + else if (this.sus2 !== undefined) + { + nameSub += `sus${ Chord.accidentalStrForName(this.sus2) }2` + romanSub += `sus${ this.accidentalStrForRoman(key, 1, this.sus2) }2` + } + else if (this.sus4 !== undefined) + { + nameSub += `sus${ Chord.accidentalStrForName(this.sus4) }4` + romanSub += `sus${ this.accidentalStrForRoman(key, 3, this.sus4) }4` + } + + if (kind.add3 === undefined) + { + if (this.add3 === undefined && + !isSuspended) + { + const no3Str = `(no3)` + nameSup += no3Str + romanSup += no3Str + } + else if (this.add3 !== undefined && + this.add3 !== 0) + { + nameSup += `(${ Chord.accidentalStrForName(this.add3) }3)` + romanSup += `(${ Chord.accidentalStrForName(this.add3) }3)` + } + } + + if (kind.add5 === undefined) + { + if (this.add5 === undefined) + { + const no5Str = `(no5)` + nameSup += no5Str + romanSup += no5Str + } + else if (this.add5 !== 0) + { + nameSup += `(${ Chord.accidentalStrForName(this.add5) }5)` + romanSup += `(${ Chord.accidentalStrForName(this.add5) }5)` + } + } + + if (this.add7 !== undefined) + { + if (kind.add7 === undefined) + { + nameSup += `(${ Chord.accidentalStrForName(this.add7) }7)` + romanSup += `(${ this.accidentalStrForRoman(key, 6, this.add7) }7)` + } + else + { + romanSup += `${ this.accidentalStrForRoman(key, 6, this.add7) }7` + } + } + + return { + nameBase, + nameSup, + nameSub, + romanBase, + romanSup, + romanSub, + } } - get pitches(): number[] + get pitchesRelativeToRoot(): number[] { - const chordData = chordKinds[this.kind] - if (!chordData) - return [] - - const rootMidi = Utils.mod(this.rootChroma, 12) - - const pitches: number[] = [] - for (let i = 0; i < chordData.pitches.length; i++) - pitches.push(rootMidi + chordData.pitches[i]) - - if (this.modifiers.sus2) - pitches[1] = rootMidi + 2 - - if (this.modifiers.sus4) - { - if (this.modifiers.sus2) - pitches.splice(2, 0, rootMidi + 5) - else - pitches[1] = rootMidi + 5 - } - + const pitches = [0] + + if (this.sus2 !== undefined) + pitches.push(this.sus2 + Theory.Scale.majorScale.chromas[1]) + + if (this.add3 !== undefined && + this.sus2 === undefined && + this.sus4 === undefined) + pitches.push(this.add3 + Theory.Scale.majorScale.chromas[2]) + + if (this.sus4 !== undefined) + pitches.push(this.sus4 + Theory.Scale.majorScale.chromas[3]) + + if (this.add5 !== undefined) + pitches.push(this.add5 + Theory.Scale.majorScale.chromas[4]) + + if (this.add7 !== undefined) + pitches.push(this.add7 + Theory.Scale.majorScale.chromas[6]) + return pitches } + get pitches(): number[] + { + const rootMidi = Theory.Utils.mod(this.rootChroma, 12) + return this.pitchesRelativeToRoot.map(p => p + rootMidi) + } + + get strummingPitches(): number[] { - const rootMidi = Utils.mod(this.rootChroma, 12) + const rootMidi = Theory.Utils.mod(this.rootChroma, 12) let pitches = this.pitches if (pitches.length == 0) return [] diff --git a/src/theory/key.ts b/src/theory/key.ts index 034e6e0..0d6f3d5 100644 --- a/src/theory/key.ts +++ b/src/theory/key.ts @@ -163,16 +163,16 @@ export default class Key { const degree = this.degreeForMidi(midi) - const letter1 = Utils.mod(this.tonic.letter + Math.floor(degree), 7) + const letter1 = Utils.mod(this.tonic.letter + Math.floor(degree), this.scale.chromas.length) const accidental1 = Utils.mod(midi - Utils.letterToChroma(letter1) + 6, 12) - 6 if (degree == Math.floor(degree)) return new PitchName(letter1, accidental1) - const letter2 = Utils.mod(letter1 + 1, 7) + const letter2 = Utils.mod(letter1 + 1, this.scale.chromas.length) const accidental2 = Utils.mod(midi - Utils.letterToChroma(letter2) + 6, 12) - 6 - const letter3 = Utils.mod(letter1 - 1, 7) + const letter3 = Utils.mod(letter1 - 1, this.scale.chromas.length) const accidental3 = Utils.mod(midi - Utils.letterToChroma(letter3) + 6, 12) - 6 const attempts = [ diff --git a/src/theory/scale.ts b/src/theory/scale.ts index 6b8094c..ce0aff2 100644 --- a/src/theory/scale.ts +++ b/src/theory/scale.ts @@ -99,6 +99,8 @@ export default class Scale { static list = knownScales + static majorScale = knownScales[0] + chromas: number[] metadata: ScaleMetadata | undefined diff --git a/src/theory/utils.ts b/src/theory/utils.ts index ca061b5..3fb7ec8 100644 --- a/src/theory/utils.ts +++ b/src/theory/utils.ts @@ -5,6 +5,30 @@ export default class Utils return (x % m + m) % m } + static modAccidental(accidental: number) + { + return Utils.mod(accidental + 6, 12) - 6 + } + + static accidentalFor(chroma: number, fromBaseChroma: number) + { + const accidental1 = chroma - fromBaseChroma + const accidental2 = chroma - fromBaseChroma - 12 + + if (Math.abs(accidental1) < Math.abs(accidental2)) + return accidental1 + else + return accidental2 + } + + static lowercaseIf(str: string, lowercase: boolean) + { + if (lowercase) + return str.toLowerCase() + + return str + } + static midiMiddleC = 60 static degreeToChromaInCMajor = (degree: number): number => [0, 2, 4, 5, 7, 9, 11][degree] @@ -27,10 +51,13 @@ export default class Utils static circleOfFifthsToAccidental = (index: number): number => Math.floor((index + 1) / 7) - static degreeToRomanStr = (degree: number): string => - ["I", "II", "III", "IV", "V", "VI", "VII"][degree] + static degreeToRomanStr = (degree: number): string => + ["I", "II", "III", "IV", "V", "VI", "VII"][Utils.mod(degree, 7)] + + static degreeToLetterStr = (degree: number): string => + Utils.letterToStr(Utils.mod(degree, 7)) - static degreeToColor = (degree: number): string => + static degreeToColor = (degree: number): string => ["#f00", "#f80", "#fd0", "#0d0", "#00f", "#80f", "#f0f"][degree] static degreeToColorFaded = (degree: number): string => @@ -39,8 +66,8 @@ export default class Utils static accidentalToStr(accidental: number, useUnicode: boolean = true): string { - if (useUnicode && accidental === 2) - return "𝄪" + //if (useUnicode && accidental === 2) + // return "𝄪" if (useUnicode && accidental === -2) return "𝄫" diff --git a/src/timeline/Element.tsx b/src/timeline/Element.tsx index 1e76463..5bf98d1 100644 --- a/src/timeline/Element.tsx +++ b/src/timeline/Element.tsx @@ -34,7 +34,7 @@ function canvasResize( canvas: HTMLCanvasElement, timeline: Timeline.State) { - const pixelRatio = window.devicePixelRatio || 1 + const pixelRatio = window.devicePixelRatio ?? 1 const domRect = div.getBoundingClientRect() const x = Math.floor(domRect.x) @@ -48,8 +48,8 @@ function canvasResize( timeline.renderRect.h === h) return - canvas.style.width = domRect.width + "px" - canvas.style.height = domRect.height + "px" + canvas.style.width = Math.floor(domRect.width) + "px" + canvas.style.height = Math.floor(domRect.height) + "px" canvas.width = w canvas.height = h diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index c65c0fc..d935a65 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -221,7 +221,7 @@ function drawChord( CanvasUtils.drawChord( ctx, - Rect.fromVertices(x1, element.rect.y, x2, element.rect.y2), + element.rect, prefs, element.chord.chord, element.key) @@ -588,6 +588,9 @@ function drawCursorBeam( const laneMin = timeline.layout.lanes[laneIndexMin] const laneMax = timeline.layout.lanes[laneIndexMax] + + if (!laneMin || !laneMax) + return const x = 0.5 + Math.floor(Timeline.xAtTime(timeline, time)) diff --git a/src/timeline/key_down.ts b/src/timeline/key_down.ts index 64742dd..cf47ac8 100644 --- a/src/timeline/key_down.ts +++ b/src/timeline/key_down.ts @@ -384,7 +384,7 @@ function handleUpDown( let playedPreview = false modifySelectedElems(timeline, project, (elem) => { - if (elem.type == "note") + if (elem.type === "note") { const track = Project.parentTrackFor(project.root, elem.parentId) const key = Project.keyAt(project.root, track.id, elem.range.start) @@ -404,19 +404,23 @@ function handleUpDown( return Project.elemModify(elem, { midiPitch: newPitch }) } - else if (elem.type == "chord") + else if (elem.type === "chord") { const track = Project.parentTrackFor(project.root, elem.parentId) const key = Project.keyAt(project.root, track.id, elem.range.start) const degree = key.octavedDegreeForMidi(elem.chord.rootChroma) - const newDegree = degree + degreeDelta + /*const newDegree = degree + degreeDelta const newRoot = pitchDelta != 0 ? elem.chord.rootChroma + pitchDelta : - key.midiForDegree(degreeDelta >= 0 ? Math.floor(newDegree) : Math.ceil(newDegree)) - - const newChord = new Theory.Chord( - newRoot, - elem.chord.kind, elem.chord.inversion, elem.chord.modifiers) + key.midiForDegree(degreeDelta >= 0 ? Math.floor(newDegree) : Math.ceil(newDegree))*/ + const newDegree = degreeDelta >= 0 ? + Math.floor(degree + degreeDelta) : + Math.ceil(degree + degreeDelta) + const newRoot = + key.chromaForDegree(newDegree) + + const newChord = elem.chord.withRoot(newRoot, newDegree) + console.log(newChord) if (!playedPreview) { diff --git a/src/timeline/lane_chords.ts b/src/timeline/lane_chords.ts index e5b8586..118530e 100644 --- a/src/timeline/lane_chords.ts +++ b/src/timeline/lane_chords.ts @@ -152,12 +152,7 @@ export class LaneChords extends Timeline.Lane const key = Project.keyAt(project.root, trackId, time) const root = key.midiForDegree(degree) - const pitches = [0] - pitches.push(key.midiForDegree(degree + 2) - root) - pitches.push(key.midiForDegree(degree + 4) - root) - - const kind = Theory.Chord.kindFromPitches(pitches) - const chord = new Theory.Chord(root, kind, 0, []) + const chord = Theory.Chord.fromDiatonicTriad(key, degree) Timeline.insertChord(timeline, project, trackId, time, chord) } } diff --git a/src/utils/canvasUtils.ts b/src/utils/canvasUtils.ts index 5e85057..20e719d 100644 --- a/src/utils/canvasUtils.ts +++ b/src/utils/canvasUtils.ts @@ -84,15 +84,88 @@ export function drawChord( rect.w, rect.h - ornamentH * 2) + const chordStr = chord.str(key) + + const maxWidth = rect.w * 0.9 + ctx.fillStyle = "#000" - ctx.font = `${prefs.timeline.fontWeightChord} ${rect.h * 0.65}px ${prefs.timeline.fontNameChord}` - ctx.textAlign = "center" + drawChordName( + ctx, + `${prefs.timeline.fontWeightChord} ${rect.h * 0.5}px ${prefs.timeline.fontNameChord}`, + `${prefs.timeline.fontWeightChord} ${rect.h * 0.25}px ${prefs.timeline.fontNameChord}`, + chordStr.romanBase, + chordStr.romanSup, + chordStr.romanSub, + rect.xCenter, + rect.yCenter + rect.h * (0.05 - 0.1), + rect.h * 0.5, + rect.h * 0.15, + maxWidth) + + drawChordName( + ctx, + `${prefs.timeline.fontWeightChord} ${rect.h * 0.2}px ${prefs.timeline.fontNameChord}`, + `${prefs.timeline.fontWeightChord} ${rect.h * 0.15}px ${prefs.timeline.fontNameChord}`, + chordStr.nameBase, + chordStr.nameSup, + chordStr.nameSub, + rect.xCenter, + rect.yCenter + rect.h * (0.05 + 0.22), + rect.h * 0.5, + rect.h * 0.05, + maxWidth) +} + + +function drawChordName( + ctx: CanvasRenderingContext2D, + fontBase: string, + fontSupSub: string, + strBase: string, + strSup: string, + strSub: string, + xCenter: number, + yCenter: number, + height: number, + supSubHeightOffset: number, + maxWidth: number) +{ + ctx.textAlign = "left" ctx.textBaseline = "middle" + + ctx.font = fontBase + const baseMetrics = ctx.measureText(strBase) + ctx.font = fontSupSub + const supMetrics = ctx.measureText(strSup) + const subMetrics = ctx.measureText(strSub) + + let baseWidth = baseMetrics.width + let supSubWidth = Math.max(supMetrics.width, subMetrics.width) + if (baseWidth + supSubWidth > maxWidth) + { + const supSubWidthProportion = supSubWidth / (baseWidth + supSubWidth) + baseWidth = maxWidth * (1 - supSubWidthProportion) + supSubWidth = maxWidth * supSubWidthProportion + } + + const strTotalWidth = baseWidth + supSubWidth + ctx.fillText( - chord.romanBase(key) + - chord.romanSup(key) + - chord.romanSub(key), - rect.xCenter, - rect.yCenter + rect.h * 0.05, - rect.w * 0.95) + strSup, + xCenter - strTotalWidth / 2 + baseWidth, + yCenter - supSubHeightOffset, + supSubWidth) + + ctx.fillText( + strSub, + xCenter - strTotalWidth / 2 + baseWidth, + yCenter + supSubHeightOffset, + supSubWidth) + + ctx.font = fontBase + ctx.fillText( + strBase, + xCenter - strTotalWidth / 2, + yCenter, + baseWidth) } \ No newline at end of file From 070929b9e3fa92b56aacb7c30c73c6a7e34a572d Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Wed, 24 Dec 2025 14:48:30 -0300 Subject: [PATCH 08/20] expand chord options --- src/inspector/InspectorChord.tsx | 191 +++++++++++- src/theory/chord.ts | 488 ++++++++++++++++++++++++++----- src/utils/canvasUtils.ts | 11 +- 3 files changed, 598 insertions(+), 92 deletions(-) diff --git a/src/inspector/InspectorChord.tsx b/src/inspector/InspectorChord.tsx index a9d422d..2fa7b24 100644 --- a/src/inspector/InspectorChord.tsx +++ b/src/inspector/InspectorChord.tsx @@ -9,14 +9,17 @@ import * as CanvasUtils from "../utils/canvasUtils.ts" import { styled } from "solid-styled-components" +type Stacking = 0 | 7 | 9 | 11 | 13 + + export function InspectorChord(props: { value?: Project.Chord, setValue: (newValue: Project.Chord) => void, key: Theory.Key, }) { - const [seventh, setSeventh] = Solid.createSignal( - !props.value ? false : props.value?.chord.add7 !== undefined) + const [stacking, setStacking] = Solid.createSignal( + !props.value ? 0 : props.value?.chord.add7 !== undefined ? 7 : 0) const [suspended2, setSuspended2] = Solid.createSignal( !props.value ? false : @@ -28,23 +31,120 @@ export function InspectorChord(props: { props.value?.chord.sus4 !== undefined && props.value?.chord.add3 === undefined) + const [add9, setAdd9] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add9 !== undefined) + + const [add11, setAdd11] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add11 !== undefined) + + const [add13, setAdd13] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add13 !== undefined) + + const [no3, setNo3] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add3 === undefined) + + const [no5, setNo5] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add5 === undefined) + + const [flat5, setFlat5] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add5 === -1) + + const [sharp5, setSharp5] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add5 === 1) + + const [flat9, setFlat9] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add9 === -1) + + const [sharp9, setSharp9] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add9 === 1) + + const [sharp11, setSharp11] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add11 === 1) + + const [flat13, setFlat13] = Solid.createSignal( + !props.value ? false : + props.value?.chord.add13 === -1) + const makeChordButton = Solid.createMemo(() => { - const withAdded7 = seventh() + const withStacking = stacking() const withSus2 = suspended2() const withSus4 = suspended4() + const withAdd9 = add9() + const withAdd11 = add11() + const withAdd13 = add13() + const withNo3 = no3() + const withNo5 = no5() + const withFlat5 = flat5() + const withSharp5 = sharp5() + const withFlat9 = flat9() + const withSharp9 = sharp9() + const withSharp11 = sharp11() + const withFlat13 = flat13() return (degree: number) => { let chord = Theory.Chord.fromDiatonicTriad(props.key, degree) - if (withAdded7) + if (withStacking >= 7) chord = chord.withAdded7(props.key) + if (withStacking >= 9) + chord = chord.withAdded9(props.key) + + if (withStacking >= 11) + chord = chord.withAdded11(props.key) + + if (withStacking >= 13) + chord = chord.withAdded13(props.key) + if (withSus2) chord = chord.withSuspended2(props.key) if (withSus4) chord = chord.withSuspended4(props.key) + if (withAdd9) + chord = chord.withAdded9(props.key) + + if (withAdd11) + chord = chord.withAdded11(props.key) + + if (withAdd13) + chord = chord.withAdded13(props.key) + + if (withFlat5) + chord = chord.withAdded5(props.key, -1) + + if (withSharp5) + chord = chord.withAdded5(props.key, 1) + + if (withFlat9) + chord = chord.withAdded9(props.key, -1) + + if (withSharp9) + chord = chord.withAdded9(props.key, 1) + + if (withSharp11) + chord = chord.withAdded11(props.key, 1) + + if (withFlat13) + chord = chord.withAdded13(props.key, -1) + + if (withNo3) + chord = chord.withNo3() + + if (withNo5) + chord = chord.withNo5() + console.log(degree, chord) let canvas: HTMLCanvasElement = undefined! @@ -85,22 +185,99 @@ export function InspectorChord(props: {
setSeventh(ev.target.checked) } + checked={ stacking() === 0 } + onChange={ ev => setStacking(0) } + /> Triad + setStacking(7) } /> 7 + setStacking(9) } + /> 9 + setStacking(11) } + /> 11 + setStacking(13) } + /> 13
setSuspended2(ev.target.checked) } /> sus2 -
setSuspended4(ev.target.checked) } /> sus4
+ setAdd9(ev.target.checked) } + /> add9 + setAdd11(ev.target.checked) } + /> add11 + setAdd13(ev.target.checked) } + /> add13 +
+ setNo3(ev.target.checked) } + /> no3 + setNo5(ev.target.checked) } + /> no5 + setFlat5(ev.target.checked) } + /> flat5 + setSharp5(ev.target.checked) } + /> sharp5 +
+ setFlat9(ev.target.checked) } + /> flat9 + setSharp9(ev.target.checked) } + /> sharp9 + setSharp11(ev.target.checked) } + /> sharp11 + setFlat13(ev.target.checked) } + /> flat13 +
diff --git a/src/theory/chord.ts b/src/theory/chord.ts index ca8e96c..9199e32 100644 --- a/src/theory/chord.ts +++ b/src/theory/chord.ts @@ -14,6 +14,7 @@ interface ChordMetadata add13?: number suspended?: boolean + suppress5?: boolean nameBase?: string nameSup?: string @@ -21,7 +22,6 @@ interface ChordMetadata romanSup?: string romanSub?: string - roman7?: number } @@ -45,6 +45,7 @@ export const chordKinds: ChordMetadata[] = name: "Augmented", add3: 0, add5: 1, + suppress5: true, nameSup: "+", romanSup: "+", }, @@ -53,6 +54,7 @@ export const chordKinds: ChordMetadata[] = name: "Diminished", add3: -1, add5: -1, + suppress5: true, nameSup: "o", romanSup: "o", }, @@ -61,6 +63,7 @@ export const chordKinds: ChordMetadata[] = name: "Doubly-diminished", add3: -2, add5: -1, + suppress5: true, nameSup: "oo", romanSup: "oo", }, @@ -71,7 +74,6 @@ export const chordKinds: ChordMetadata[] = add5: 0, add7: -1, nameBase: "7", - roman7: -1, }, { id: "maj7", @@ -88,7 +90,6 @@ export const chordKinds: ChordMetadata[] = add5: 0, add7: -1, nameBase: "m7", - roman7: -1, }, { id: "minmaj7", @@ -104,6 +105,7 @@ export const chordKinds: ChordMetadata[] = add3: 0, add5: 1, add7: -1, + suppress5: true, nameBase: "7", nameSup: "(\u{266f}5)", romanSup: "+", @@ -114,6 +116,7 @@ export const chordKinds: ChordMetadata[] = add3: 0, add5: 1, add7: 0, + suppress5: true, nameBase: "maj7", nameSup: "(\u{266f}5)", romanSup: "+", @@ -124,9 +127,9 @@ export const chordKinds: ChordMetadata[] = add3: -1, add5: -1, add7: -2, + suppress5: true, nameSup: "o7", romanSup: "o", - roman7: -2, }, { id: "halfdim7", @@ -134,10 +137,130 @@ export const chordKinds: ChordMetadata[] = add3: -1, add5: -1, add7: -1, + suppress5: true, nameBase: "m7", nameSup: "(\u{266d}5)", romanSup: "ø", - roman7: -1, + }, + { + id: "dom9", + name: "Dominant Ninth", + add3: 0, + add5: 0, + add7: -1, + add9: 0, + nameBase: "9", + }, + { + id: "maj9", + name: "Major Ninth", + add3: 0, + add5: 0, + add7: 0, + add9: 0, + nameBase: "maj9", + }, + { + id: "min9", + name: "Minor Ninth", + add3: -1, + add5: 0, + add7: -1, + add9: 0, + nameBase: "m9", + }, + { + id: "minmaj9", + name: "Minor-major Ninth", + add3: -1, + add5: 0, + add7: 0, + add9: 0, + nameBase: "mM9", + }, + { + id: "dom11", + name: "Dominant Eleventh", + add3: 0, + add5: 0, + add7: -1, + add9: 0, + add11: 0, + nameBase: "11", + }, + { + id: "maj11", + name: "Major Eleventh", + add3: 0, + add5: 0, + add7: 0, + add9: 0, + add11: 0, + nameBase: "maj11", + }, + { + id: "min11", + name: "Minor Eleventh", + add3: -1, + add5: 0, + add7: -1, + add9: 0, + add11: 0, + nameBase: "m11", + }, + { + id: "minmaj11", + name: "Minor-major Eleventh", + add3: -1, + add5: 0, + add7: 0, + add9: 0, + add11: 0, + nameBase: "mM11", + }, + { + id: "dom13", + name: "Dominant Thirteenth", + add3: 0, + add5: 0, + add7: -1, + add9: 0, + add11: 0, + add13: 0, + nameBase: "13", + }, + { + id: "maj13", + name: "Major Thirteenth", + add3: 0, + add5: 0, + add7: 0, + add9: 0, + add11: 0, + add13: 0, + nameBase: "maj13", + }, + { + id: "min13", + name: "Minor Thirteenth", + add3: -1, + add5: 0, + add7: -1, + add9: 0, + add11: 0, + add13: 0, + nameBase: "m13", + }, + { + id: "minmaj13", + name: "Minor-major Thirteenth", + add3: -1, + add5: 0, + add7: 0, + add9: 0, + add11: 0, + add13: 0, + nameBase: "mM13", }, ] @@ -190,13 +313,15 @@ export default class Chord rootChroma: number - degree: number + baseDegree: number inversion: number sus2?: number add3?: number + no3?: boolean sus4?: number add5?: number + no5?: boolean add7?: number add9?: number add11?: number @@ -222,22 +347,16 @@ export default class Chord { const cloned = this.clone() cloned.rootChroma = newRootChroma - cloned.degree = newDegree + cloned.baseDegree = newDegree return cloned } - - - /*withChanges(obj: any): Chord - { - return Object.assign(new Chord(this.rootChroma, this.kind, this.inversion, this.modifiers), obj) - }*/ static fromDiatonicTriad(key: Theory.Key, rootDegree: number) { const rootChroma = (key.tonic.chroma + key.scale.chromas[(rootDegree + 0) % key.scale.chromas.length]) % 12 const chord = new Chord(rootChroma) - chord.degree = rootDegree + chord.baseDegree = rootDegree chord.add3 = Chord.diatonicDegree(key, 2, rootChroma, rootDegree) chord.add5 = Chord.diatonicDegree(key, 4, rootChroma, rootDegree) return chord @@ -257,22 +376,22 @@ export default class Chord return Theory.Utils.modAccidental( chroma - - (rootChroma + Theory.Scale.majorScale.chromas[degree])) + (rootChroma + Theory.Scale.majorScale.chromas[degree % 7])) } withSuspended2(key: Theory.Key) { const chord = this.clone() - chord.sus2 = Chord.diatonicDegree(key, 1, this.rootChroma, this.degree) + chord.sus2 = Chord.diatonicDegree(key, 1, this.rootChroma, this.baseDegree) return chord } - withRemoved3() + withNo3() { const chord = this.clone() - chord.add3 = undefined + chord.no3 = true return chord } @@ -280,7 +399,23 @@ export default class Chord withSuspended4(key: Theory.Key) { const chord = this.clone() - chord.sus4 = Chord.diatonicDegree(key, 3, this.rootChroma, this.degree) + chord.sus4 = Chord.diatonicDegree(key, 3, this.rootChroma, this.baseDegree) + return chord + } + + + withAdded5(key: Theory.Key, accidental: number = 0) + { + const chord = this.clone() + chord.add5 = Chord.diatonicDegree(key, 4, this.rootChroma, this.baseDegree) + accidental + return chord + } + + + withNo5() + { + const chord = this.clone() + chord.no5 = true return chord } @@ -288,7 +423,31 @@ export default class Chord withAdded7(key: Theory.Key) { const chord = this.clone() - chord.add7 = Chord.diatonicDegree(key, 6, this.rootChroma, this.degree) + chord.add7 = Chord.diatonicDegree(key, 6, this.rootChroma, this.baseDegree) + return chord + } + + + withAdded9(key: Theory.Key, accidental: number = 0) + { + const chord = this.clone() + chord.add9 = Chord.diatonicDegree(key, 8, this.rootChroma, this.baseDegree) + accidental + return chord + } + + + withAdded11(key: Theory.Key, accidental: number = 0) + { + const chord = this.clone() + chord.add11 = Chord.diatonicDegree(key, 10, this.rootChroma, this.baseDegree) + accidental + return chord + } + + + withAdded13(key: Theory.Key, accidental: number = 0) + { + const chord = this.clone() + chord.add13 = Chord.diatonicDegree(key, 12, this.rootChroma, this.baseDegree) + accidental return chord } @@ -364,36 +523,79 @@ export default class Chord b === undefined) return false - return Theory.Utils.mod(a, 12) === Theory.Utils.mod(b, 12) + if (Theory.Utils.mod(a, 12) === Theory.Utils.mod(b, 12)) + return true + + return false } + let chosenKind: ChordMetadata | undefined = undefined + let highestScore = 0 + for (const meta of chordKinds) { + let score = + (compare(meta.add3, this.add3) ? 1 : 0) + + (compare(meta.add5, this.add5) ? 1 : 0) + + (compare(meta.add7, this.add7) ? 1 : 0) + + (this.add7 !== undefined && + compare(meta.add9, this.add9) ? 1 : 0) + + (this.add7 !== undefined && + this.add9 !== undefined && + compare(meta.add11, this.add11) ? 1 : 0) + + (this.add7 !== undefined && + this.add9 !== undefined && + this.add11 !== undefined && + compare(meta.add13, this.add13) ? 1 : 0) + + /*let score = 0 if (compare(meta.add3, this.add3) && - compare(meta.add5, this.add5) && - compare(meta.add7, this.add7)) + compare(meta.add5, this.add5)) + { + score += 1 + if (compare(meta.add7, this.add7)) + { + score += 1 + if (compare(meta.add9, this.add9)) + { + score += 1 + if (compare(meta.add11, this.add11)) + { + score += 1 + if (compare(meta.add13, this.add13)) + score += 1 + } + } + } + }*/ + + if (score > highestScore) { - return meta + highestScore = score + chosenKind = meta } } - return undefined + return chosenKind } - accidentalStrForRoman(key: Theory.Key, degree: number, accidental: number) + accidentalStrForRoman( + key: Theory.Key, + degree: number, + accidental: number) { - const chroma = key.chromaForDegree(this.degree + degree) - const chromaInCMajor = this.rootChroma + Theory.Scale.majorScale.chromas[degree] - return Theory.Utils.accidentalToStr( - Theory.Utils.modAccidental( - chroma - chromaInCMajor - accidental)) + const chroma = key.chromaForDegree(this.baseDegree + degree) + const chromaInCMajor = this.rootChroma + Theory.Scale.majorScale.chromas[degree % 7] + accidental + const finalAccidental = Theory.Utils.modAccidental(chromaInCMajor - chroma) + return Theory.Utils.accidentalToStr(finalAccidental) } static accidentalStrForName(accidental: number) { - return Theory.Utils.accidentalToStr(Theory.Utils.modAccidental(accidental)) + const finalAccidental = Theory.Utils.modAccidental(accidental) + return Theory.Utils.accidentalToStr(finalAccidental) } @@ -404,7 +606,7 @@ export default class Chord name: "Custom", } - let roman = this.degree % key.scale.chromas.length + let roman = this.baseDegree % key.scale.chromas.length let romanChroma = key.chromaForDegree(roman) let accidental = Theory.Utils.accidentalFor(this.rootChroma, romanChroma) @@ -412,7 +614,7 @@ export default class Chord { for (let r = 0; r < 7; r++) { - const newRoman = (this.degree + r) % key.scale.chromas.length + const newRoman = (this.baseDegree + r) % key.scale.chromas.length const newRomanChroma = key.chromaForDegree(newRoman) const newAccidental = Theory.Utils.accidentalFor(this.rootChroma, newRomanChroma) if (Math.abs(newAccidental) < Math.abs(accidental)) @@ -449,72 +651,185 @@ export default class Chord let romanSup = kind.romanSup ?? "" let romanSub = kind.romanSub ?? "" - const isSuspended = - this.sus2 !== undefined || - this.sus4 !== undefined - - if (this.sus2 !== undefined && - this.sus4 !== undefined) - { - nameSub += `sus${ Chord.accidentalStrForName(this.sus2) }2${ Chord.accidentalStrForName(this.sus4) }4` - romanSub += `sus${ this.accidentalStrForRoman(key, 1, this.sus2) }2${ this.accidentalStrForRoman(key, 3, this.sus4) }4` - } - else if (this.sus2 !== undefined) + if (this.sus2 !== undefined) { nameSub += `sus${ Chord.accidentalStrForName(this.sus2) }2` romanSub += `sus${ this.accidentalStrForRoman(key, 1, this.sus2) }2` } - else if (this.sus4 !== undefined) + + if (this.sus4 !== undefined) { nameSub += `sus${ Chord.accidentalStrForName(this.sus4) }4` romanSub += `sus${ this.accidentalStrForRoman(key, 3, this.sus4) }4` } - if (kind.add3 === undefined) + let add3Name = this.add3 + let add3Roman = this.add3 + let add5Name = this.add5 + let add5Roman = this.add5 + let add7Name = this.add7 + let add7Roman = this.add7 + let add9Name = this.add9 + let add9Roman = this.add9 + let add11Name = this.add11 + let add11Roman = this.add11 + let add13Name = this.add13 + let add13Roman = this.add13 + + if (kind.suppress5) { - if (this.add3 === undefined && - !isSuspended) - { - const no3Str = `(no3)` - nameSup += no3Str - romanSup += no3Str - } - else if (this.add3 !== undefined && - this.add3 !== 0) - { - nameSup += `(${ Chord.accidentalStrForName(this.add3) }3)` - romanSup += `(${ Chord.accidentalStrForName(this.add3) }3)` - } + add5Name = undefined + add5Roman = undefined } - if (kind.add5 === undefined) + if (kind.add5 === 0 && + this.add5 === 0) { - if (this.add5 === undefined) - { - const no5Str = `(no5)` - nameSup += no5Str - romanSup += no5Str - } - else if (this.add5 !== 0) - { - nameSup += `(${ Chord.accidentalStrForName(this.add5) }5)` - romanSup += `(${ Chord.accidentalStrForName(this.add5) }5)` - } + add5Name = undefined + add5Roman = undefined } - if (this.add7 !== undefined) + if (add7Roman === -1 && + add5Roman === -1 && + add3Roman === -1) { - if (kind.add7 === undefined) - { - nameSup += `(${ Chord.accidentalStrForName(this.add7) }7)` - romanSup += `(${ this.accidentalStrForRoman(key, 6, this.add7) }7)` - } - else + romanSup += `ø` + add5Roman = undefined + add3Roman = undefined + } + + if (add5Roman === -1 && + add3Roman === -2) + { + romanSup += `oo` + add5Roman = undefined + add3Roman = undefined + } + + if (add5Roman === -1 && + add3Roman === -1) + { + romanSup += `o` + add5Roman = undefined + add3Roman = undefined + } + + if (add5Roman === 1 && + add3Roman === 0) + { + romanSup += `+` + add5Roman = undefined + } + + if (add13Roman !== undefined && + add11Roman !== undefined && + add9Roman !== undefined && + add7Roman !== undefined) + { + romanSup += `${ this.accidentalStrForRoman(key, 12, add13Roman) }13` + add13Roman = undefined + add11Roman = undefined + add9Roman = undefined + add7Roman = undefined + } + + if (add11Roman !== undefined && + add9Roman !== undefined && + add7Roman !== undefined) + { + romanSup += `${ this.accidentalStrForRoman(key, 10, add11Roman) }11` + add11Roman = undefined + add9Roman = undefined + add7Roman = undefined + } + + if (add9Roman !== undefined && + add7Roman !== undefined) + { + romanSup += `${ this.accidentalStrForRoman(key, 8, add9Roman) }9` + add9Roman = undefined + add7Roman = undefined + } + + if (add7Roman !== undefined) + { + romanSup += `${ this.accidentalStrForRoman(key, 6, add7Roman) }7` + add7Roman = undefined + } + + if (this.no3) + romanSup += `(no3)` + + if (this.no5) + romanSup += `(no5)` + + if (!this.no5 && + add5Roman !== undefined && + (kind.add5 === undefined || add5Roman !== kind.add5)) + { + const accidentalStr = Chord.accidentalStrForName(add5Roman) + if (accidentalStr !== "") { - romanSup += `${ this.accidentalStrForRoman(key, 6, this.add7) }7` + romanSup += `(${ accidentalStr }5)` + add5Roman = undefined } } + + if (this.no3) + nameSup += `(no3)` + + if (this.no5) + nameSup += `(no5)` + + if (!this.no5 && + add5Name !== undefined && + (kind.add5 === undefined || add5Name !== kind.add5)) + { + nameSup += `(${ Chord.accidentalStrForName(add5Name) }5)` + add5Name = undefined + } + + if (add7Name !== undefined && + (kind.add7 === undefined || add7Name !== kind.add7)) + nameSup += `(${ Chord.accidentalStrForName(add7Name) }7)` + + if (add7Roman !== undefined) + romanSup += `(${ this.accidentalStrForRoman(key, 6, add7Roman) }7)` + + const hasAdd9 = + this.add7 === undefined + + const hasAdd11 = + this.add7 === undefined || + this.add9 === undefined + + const hasAdd13 = + this.add7 === undefined || + this.add9 === undefined || + this.add11 === undefined + + if (add9Name !== undefined && + (kind.add9 === undefined || add9Name !== kind.add9)) + nameSup += `(${ hasAdd9 ? "add" : ""}${ Chord.accidentalStrForName(add9Name) }9)` + + if (add9Roman !== undefined) + romanSup += `(${ hasAdd9 ? "add" : ""}${ this.accidentalStrForRoman(key, 8, add9Roman) }9)` + + if (add11Name !== undefined && + (kind.add11 === undefined || add11Name !== kind.add11)) + nameSup += `(${ hasAdd11 ? "add" : ""}${ Chord.accidentalStrForName(add11Name) }11)` + + if (add11Roman !== undefined) + romanSup += `(${ hasAdd11 ? "add" : ""}${ this.accidentalStrForRoman(key, 10, add11Roman) }11)` + + if (add13Name !== undefined && + (kind.add13 === undefined || add13Name !== kind.add13)) + nameSup += `(${ hasAdd13 ? "add" : ""}${ Chord.accidentalStrForName(add13Name) }13)` + + if (add13Roman !== undefined) + romanSup += `(${ hasAdd13 ? "add" : ""}${ this.accidentalStrForRoman(key, 12, add13Roman) }13)` + return { nameBase, nameSup, @@ -534,6 +849,7 @@ export default class Chord pitches.push(this.sus2 + Theory.Scale.majorScale.chromas[1]) if (this.add3 !== undefined && + !this.no3 && this.sus2 === undefined && this.sus4 === undefined) pitches.push(this.add3 + Theory.Scale.majorScale.chromas[2]) @@ -541,12 +857,22 @@ export default class Chord if (this.sus4 !== undefined) pitches.push(this.sus4 + Theory.Scale.majorScale.chromas[3]) - if (this.add5 !== undefined) + if (this.add5 !== undefined && + !this.no5) pitches.push(this.add5 + Theory.Scale.majorScale.chromas[4]) if (this.add7 !== undefined) pitches.push(this.add7 + Theory.Scale.majorScale.chromas[6]) + if (this.add9 !== undefined) + pitches.push(12 + this.add9 + Theory.Scale.majorScale.chromas[1]) + + if (this.add11 !== undefined) + pitches.push(12 + this.add11 + Theory.Scale.majorScale.chromas[3]) + + if (this.add13 !== undefined) + pitches.push(12 + this.add13 + Theory.Scale.majorScale.chromas[5]) + return pitches } diff --git a/src/utils/canvasUtils.ts b/src/utils/canvasUtils.ts index 20e719d..447c6a5 100644 --- a/src/utils/canvasUtils.ts +++ b/src/utils/canvasUtils.ts @@ -99,7 +99,8 @@ export function drawChord( rect.xCenter, rect.yCenter + rect.h * (0.05 - 0.1), rect.h * 0.5, - rect.h * 0.15, + rect.h * -0.15, + rect.h * 0.05, maxWidth) drawChordName( @@ -112,6 +113,7 @@ export function drawChord( rect.xCenter, rect.yCenter + rect.h * (0.05 + 0.22), rect.h * 0.5, + rect.h * -0.05, rect.h * 0.05, maxWidth) } @@ -127,7 +129,8 @@ function drawChordName( xCenter: number, yCenter: number, height: number, - supSubHeightOffset: number, + supHeightOffset: number, + subHeightOffset: number, maxWidth: number) { ctx.textAlign = "left" @@ -153,13 +156,13 @@ function drawChordName( ctx.fillText( strSup, xCenter - strTotalWidth / 2 + baseWidth, - yCenter - supSubHeightOffset, + yCenter + supHeightOffset, supSubWidth) ctx.fillText( strSub, xCenter - strTotalWidth / 2 + baseWidth, - yCenter + supSubHeightOffset, + yCenter + subHeightOffset, supSubWidth) ctx.font = fontBase From 681a3e021218efde6e748fc804e89eb0a318c757 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Wed, 24 Dec 2025 15:53:15 -0300 Subject: [PATCH 09/20] add chord insertion and alteration --- src/inspector/Inspector.tsx | 26 ++++++--- src/inspector/InspectorChord.tsx | 48 ++++++++++++---- src/inspector/InspectorInsert.tsx | 17 +++++- src/inspector/InspectorKeyChange.tsx | 86 +++++++++++++++++----------- src/project/root.ts | 20 ++++--- src/timeline/draw.ts | 5 ++ src/utils/canvasUtils.ts | 27 ++++++++- 7 files changed, 168 insertions(+), 61 deletions(-) diff --git a/src/inspector/Inspector.tsx b/src/inspector/Inspector.tsx index a18a597..b066201 100644 --- a/src/inspector/Inspector.tsx +++ b/src/inspector/Inspector.tsx @@ -5,6 +5,7 @@ import * as Project from "../project" import * as Timeline from "../timeline" import * as Theory from "../theory" import Rect from "../utils/rect.ts" +import Rational from "../utils/rational.ts" import { styled } from "solid-styled-components" @@ -20,9 +21,9 @@ export function InspectorRoot(props: {}) return ids }) - const firstElem = Solid.createMemo(() => { + const firstElemId = Solid.createMemo(() => { if (selectedIds().count() !== 1) - return null + return undefined const project = Global.get().project @@ -34,22 +35,33 @@ export function InspectorRoot(props: {}) break } - return firstElem + return firstElem?.id }) + const project = Global.get().project + const inspectorKind = Solid.createMemo(() => { - const setValue = (elem: Project.Element) => { - const project = Global.get().project + const upsertElem = (elem: Project.Element) => { + console.log(elem) project.root = Project.upsertElement(project.root, elem) Global.refresh() } - const elem = firstElem() + const elemId = firstElemId() + const elem = Project.getElem(project.root, elemId) + const key = Project.keyAt(project.root, project.root.keyChangeTrackId, elem?.range.start ?? new Rational(0)) if (elem?.type === "keyChange") return + + if (elem?.type === "chord") + return return diff --git a/src/inspector/InspectorChord.tsx b/src/inspector/InspectorChord.tsx index 2fa7b24..779b27a 100644 --- a/src/inspector/InspectorChord.tsx +++ b/src/inspector/InspectorChord.tsx @@ -14,42 +14,55 @@ type Stacking = 0 | 7 | 9 | 11 | 13 export function InspectorChord(props: { value?: Project.Chord, - setValue: (newValue: Project.Chord) => void, + insertElem?: (newValue: Theory.Chord) => void, + upsertElem?: (newValue: Project.Chord) => void, key: Theory.Key, }) { const [stacking, setStacking] = Solid.createSignal( - !props.value ? 0 : props.value?.chord.add7 !== undefined ? 7 : 0) + !props.value ? 0 : + props.value?.chord.add7 !== undefined ? + props.value?.chord.add9 !== undefined ? + props.value?.chord.add11 !== undefined ? + props.value?.chord.add13 !== undefined ? 13 : + 11 : + 9 : + 7 : + 0) const [suspended2, setSuspended2] = Solid.createSignal( !props.value ? false : - props.value?.chord.sus2 !== undefined && - props.value?.chord.add3 === undefined) + props.value?.chord.sus2 !== undefined) const [suspended4, setSuspended4] = Solid.createSignal( !props.value ? false : - props.value?.chord.sus4 !== undefined && - props.value?.chord.add3 === undefined) + props.value?.chord.sus4 !== undefined) const [add9, setAdd9] = Solid.createSignal( !props.value ? false : - props.value?.chord.add9 !== undefined) + props.value?.chord.add7 === undefined && + props.value?.chord.add9 === 0) const [add11, setAdd11] = Solid.createSignal( !props.value ? false : - props.value?.chord.add11 !== undefined) + props.value?.chord.add7 === undefined && + props.value?.chord.add9 === undefined && + props.value?.chord.add11 === 0) const [add13, setAdd13] = Solid.createSignal( !props.value ? false : - props.value?.chord.add13 !== undefined) + props.value?.chord.add7 === undefined && + props.value?.chord.add9 === undefined && + props.value?.chord.add11 === undefined && + props.value?.chord.add13 === 0) const [no3, setNo3] = Solid.createSignal( !props.value ? false : - props.value?.chord.add3 === undefined) + !!props.value?.chord.no3) const [no5, setNo5] = Solid.createSignal( !props.value ? false : - props.value?.chord.add5 === undefined) + !!props.value?.chord.no5) const [flat5, setFlat5] = Solid.createSignal( !props.value ? false : @@ -75,6 +88,15 @@ export function InspectorChord(props: { !props.value ? false : props.value?.chord.add13 === -1) + const applyChord = (chord: Theory.Chord) => { + //setCurrKey(key) + props.insertElem?.(chord) + const project = Global.get().project + const projChord = Project.getTypedElem(project.root, props.value?.id, "chord") + if (projChord) + props.upsertElem?.({...projChord, chord }) + } + const makeChordButton = Solid.createMemo(() => { const withStacking = stacking() const withSus2 = suspended2() @@ -164,7 +186,9 @@ export function InspectorChord(props: { props.key) }) - return + return applyChord(chord) } + > diff --git a/src/inspector/InspectorInsert.tsx b/src/inspector/InspectorInsert.tsx index 87ffbc0..9e9e6c0 100644 --- a/src/inspector/InspectorInsert.tsx +++ b/src/inspector/InspectorInsert.tsx @@ -51,6 +51,21 @@ export function InspectorInsert(props: { Global.refresh() } + const insertChord = (chord: Theory.Chord) => { + const project = Global.get().project + const timeline = Global.get().timeline + const time = timeline.cursor.time1 + const id = project.root.nextId + const trackId = project.root.chordTrackId + Timeline.insertChord(timeline, project, trackId, time, chord) + Timeline.selectionClear(timeline) + Timeline.selectionAdd(timeline, id) + Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) + Timeline.selectionClear(timeline) + timeline.cursor.visible = true + Global.refresh() + } + return
@@ -340,16 +250,24 @@ const LayoutMainButtons = styled.div` const ChordButton = styled.button<{ }>` border: 0; + border-radius: 5px; margin: 0; padding: 0; - background-color: transparent; + width: 6em; + height: 3.5em; + background-color: #fff; + cursor: pointer; ` const ChordCanvas = styled.canvas<{ }>` - width: 6em; - height: 3.5em; + width: 100%; + height: 100%; + + &:hover { + opacity: 0.5; + } ` diff --git a/src/prefs.ts b/src/prefs.ts index 8ccc2c1..b4c556d 100644 --- a/src/prefs.ts +++ b/src/prefs.ts @@ -7,6 +7,9 @@ export interface Prefs bkgInactiveOverlayColor: string trackVBorderColor: string trackHBorderColor: string + + outOfBoundsColor1: string + outOfBoundsColor2: string selectionCursorColor: string selectionBkgColor: string @@ -66,6 +69,9 @@ export function makeNew(): Prefs trackVBorderColor: "#888", trackHBorderColor: "#888", + outOfBoundsColor1: "#161719", + outOfBoundsColor2: "#141416", + selectionCursorColor: "#0af", selectionBkgColor: "#8cf4", playbackCursorColor: "#f00", diff --git a/src/project/root.ts b/src/project/root.ts index 91bb069..e84cf1a 100644 --- a/src/project/root.ts +++ b/src/project/root.ts @@ -95,7 +95,7 @@ export function makeTest(): ImmutableRoot Range.fromStartDuration(new Rational(i * 4, 4), new Rational(4, 4)), Theory.Chord.fromDiatonicTriad(Theory.Key.parse("C Major"), i))) - return project + return withRefreshedRange(project) } @@ -278,8 +278,8 @@ export function withRefreshedRange(project: ImmutableRoot): ImmutableRoot range = range.merge(list.getTotalRange()) } - if (range.start.compare(project.range.start) == 0 && - range.end.compare(project.range.end) == 0) + if (range.start.compare(project.range.start) === 0 && + range.end.compare(project.range.end) === 0) return project return { ...project, range } diff --git a/src/theory/chord.ts b/src/theory/chord.ts index 9199e32..9414703 100644 --- a/src/theory/chord.ts +++ b/src/theory/chord.ts @@ -335,7 +335,25 @@ export default class Chord } - clone() + isEqual(other: Chord): boolean + { + return this.rootChroma === other.rootChroma && + this.baseDegree === other.baseDegree && + this.inversion === other.inversion && + this.sus2 === other.sus2 && + this.add3 === other.add3 && + this.no3 === other.no3 && + this.sus4 === other.sus4 && + this.add5 === other.add5 && + this.no5 === other.no5 && + this.add7 === other.add7 && + this.add9 === other.add9 && + this.add11 === other.add11 && + this.add13 === other.add13 + } + + + clone(): Chord { const cloned = Object.assign({}, this) Object.setPrototypeOf(cloned, Chord.prototype) diff --git a/src/theory/chordOptions.ts b/src/theory/chordOptions.ts new file mode 100644 index 0000000..df088e9 --- /dev/null +++ b/src/theory/chordOptions.ts @@ -0,0 +1,175 @@ +import * as Theory from "./index.ts" + + +export type ChordStacking = 0 | 7 | 9 | 11 | 13 + + +export interface ChordOptions +{ + withStacking: ChordStacking + withSus2: boolean + withSus4: boolean + withAdd9: boolean + withAdd11: boolean + withAdd13: boolean + withNo3: boolean + withNo5: boolean + withFlat5: boolean + withSharp5: boolean + withFlat9: boolean + withSharp9: boolean + withSharp11: boolean + withFlat13: boolean +} + + +export namespace ChordOptions +{ + export function makeEmpty(): ChordOptions + { + return { + withStacking: 0, + withSus2: false, + withSus4: false, + withAdd9: false, + withAdd11: false, + withAdd13: false, + withNo3: false, + withNo5: false, + withFlat5: false, + withSharp5: false, + withFlat9: false, + withSharp9: false, + withSharp11: false, + withFlat13: false, + } + } + + + export function buildChord( + key: Theory.Key, + rootDegree: number, + opts: ChordOptions) + { + let chord = Theory.Chord.fromDiatonicTriad(key, rootDegree) + + if (opts.withStacking >= 7) + chord = chord.withAdded7(key) + + if (opts.withStacking >= 9) + chord = chord.withAdded9(key) + + if (opts.withStacking >= 11) + chord = chord.withAdded11(key) + + if (opts.withStacking >= 13) + chord = chord.withAdded13(key) + + if (opts.withSus2) + chord = chord.withSuspended2(key) + + if (opts.withSus4) + chord = chord.withSuspended4(key) + + if (opts.withAdd9) + chord = chord.withAdded9(key) + + if (opts.withAdd11) + chord = chord.withAdded11(key) + + if (opts.withAdd13) + chord = chord.withAdded13(key) + + if (opts.withFlat5) + chord = chord.withAdded5(key, -1) + + if (opts.withSharp5) + chord = chord.withAdded5(key, 1) + + if (opts.withFlat9) + chord = chord.withAdded9(key, -1) + + if (opts.withSharp9) + chord = chord.withAdded9(key, 1) + + if (opts.withSharp11) + chord = chord.withAdded11(key, 1) + + if (opts.withFlat13) + chord = chord.withAdded13(key, -1) + + if (opts.withNo3) + chord = chord.withNo3() + + if (opts.withNo5) + chord = chord.withNo5() + + return chord + } + + + export function makeFromChord( + key: Theory.Key, + chord: Theory.Chord) + : ChordOptions + { + for (const withStacking of [0, 7, 9, 11, 13] satisfies ChordStacking[]) + { + for (let degree = 0; degree < 7; degree++) + { + const testOpts: ChordOptions = { ...makeEmpty(), withStacking } + if (chord.isEqual(buildChord(key, degree, testOpts))) + return testOpts + } + } + + const opts = makeEmpty() + + if (chord.add7 !== undefined) + { + opts.withStacking = 7 + if (chord.add9 !== undefined) + { + opts.withStacking = 9 + if (chord.add11 !== undefined) + { + opts.withStacking = 11 + if (chord.add13 !== undefined) + opts.withStacking = 13 + } + } + } + + if (chord.sus2 !== undefined) + opts.withSus2 = true + + if (chord.sus4 !== undefined) + opts.withSus4 = true + + if (chord.no3) + opts.withNo3 = true + + if (chord.no5) + opts.withNo3 = true + + if (chord.add5 === -1) + opts.withFlat5 = true + + if (chord.add5 === 1) + opts.withSharp5 = true + + if (chord.add9 === -1) + opts.withFlat9 = true + + if (chord.add9 === 1) + opts.withSharp9 = true + + if (chord.add11 === 1) + opts.withSharp11 = true + + if (chord.add13 === -1) + opts.withFlat13 = true + + return opts + } +} \ No newline at end of file diff --git a/src/theory/index.ts b/src/theory/index.ts index 908eb3b..9f9ab56 100644 --- a/src/theory/index.ts +++ b/src/theory/index.ts @@ -5,4 +5,5 @@ export { ScaleMetadata } from "./scale.ts" export { default as Key } from "./key.ts" export { default as Meter } from "./meter.ts" export { default as Chord } from "./chord.ts" +export * from "./chordOptions.ts" export { default as Utils } from "./utils.ts" \ No newline at end of file diff --git a/src/theory/utils.ts b/src/theory/utils.ts index 3fb7ec8..7f44f64 100644 --- a/src/theory/utils.ts +++ b/src/theory/utils.ts @@ -61,7 +61,7 @@ export default class Utils ["#f00", "#f80", "#fd0", "#0d0", "#00f", "#80f", "#f0f"][degree] static degreeToColorFaded = (degree: number): string => - ["#400", "#420", "#430", "#030", "#004", "#204", "#404"][degree] + ["#400", "#420", "#430", "#030", "#004", "#2c0c4c", "#404"][degree] static accidentalToStr(accidental: number, useUnicode: boolean = true): string diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index aaa542b..9b16046 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -50,21 +50,21 @@ function drawLane( lane.rect.h) ctx.clip() + ctx.translate(lane.rect.x, lane.rect.y) + drawLaneBkgSolid(timeline, prefs, ctx, lane) + drawLaneBkgOutOfBounds(timeline, prefs, ctx, lane) drawLaneBkgMeasures(timeline, prefs, ctx, lane, false) drawLaneBkgMeasures(timeline, prefs, ctx, lane, true) drawCursorBkg(timeline, prefs, ctx, lane) - - ctx.save() - ctx.translate(lane.rect.x, lane.rect.y) drawElements(timeline, prefs, ctx, lane.elements) - ctx.restore() - + ctx.save() ctx.globalAlpha = 0.05 drawLaneBkgMeasures(timeline, prefs, ctx, lane, false) drawLaneBkgMeasures(timeline, prefs, ctx, lane, true) ctx.restore() + drawLaneFrgOutline(timeline, prefs, ctx, lane) ctx.restore() @@ -81,15 +81,16 @@ function drawLane( lane.rect.h) ctx.clip() + ctx.translate(lane.rect.x, lane.rect.y) + drawLaneBkgSolid(timeline, prefs, ctx, lane) + drawLaneBkgOutOfBounds(timeline, prefs, ctx, lane) + drawLaneBkgChordTones(timeline, prefs, ctx, lane) drawLaneBkgOctaves(timeline, prefs, ctx, lane, false) drawLaneBkgMeasures(timeline, prefs, ctx, lane, false) drawLaneBkgOctaves(timeline, prefs, ctx, lane, true) drawLaneBkgMeasures(timeline, prefs, ctx, lane, true) drawCursorBkg(timeline, prefs, ctx, lane) - - ctx.save() - ctx.translate(lane.rect.x, lane.rect.y) drawElements(timeline, prefs, ctx, lane.elements) for (const tuple of lane.tupleIndicators) @@ -113,8 +114,6 @@ function drawLane( tuple.rect.y2 + 8) } - ctx.restore() - drawLaneFrgOutline(timeline, prefs, ctx, lane) ctx.restore() @@ -163,7 +162,7 @@ function drawElements( const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) const key = element.key - const mode = key.scale.metadata!.mode + const mode = key.scale.metadata?.mode ?? 0 const fillStyle = CanvasUtils.fillStyleForDegree( ctx, key.degreeForMidi(element.note.midiPitch) + mode, @@ -362,8 +361,8 @@ export function drawLaneBkgSolid( { ctx.fillStyle = prefs.timeline.bkgColor ctx.fillRect( - lane.rect.x, - lane.rect.y, + 0, + 0, lane.rect.w, lane.rect.h) @@ -381,13 +380,60 @@ export function drawLaneBkgSolid( ctx.fillRect( x1, - lane.rect.y, + 0, x2 - x1, lane.rect.h) } } +export function drawLaneBkgChordTones( + timeline: Timeline.State, + prefs: Prefs.Prefs, + ctx: CanvasRenderingContext2D, + lane: Timeline.Lane) +{ + const rowAtTop = Timeline.rowAtY(timeline, lane, 0) + const rowAtBottom = Timeline.rowAtY(timeline, lane, lane.rect.h) + + const octaveAtTop = Math.ceil(rowAtTop / 7) + 1 + const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1 + + // Render alternating measure background and sub-measure dividers. + for (const chordRegion of timeline.layout.chordRegions) + { + const key = chordRegion.key + const scaleLength = key.scale.chromas.length + + for (const tone of chordRegion.tones) + { + const mode = key.scale.metadata?.mode ?? 0 + const fillStyle = CanvasUtils.fillStyleForDegree( + ctx, + tone.degree + mode, + true) + + for (let i = octaveAtBottom; i <= octaveAtTop; i++) + { + const y = Math.floor( + Timeline.yForRow(timeline, lane, tone.row + (5 + i) * scaleLength) + + timeline.noteRowH) + + ctx.fillStyle = fillStyle + ctx.beginPath() + ctx.roundRect( + chordRegion.x1, + y, + chordRegion.x2 - chordRegion.x1, + timeline.noteRowH, + timeline.noteRowH / 4) + ctx.fill() + } + } + } +} + + export function drawLaneFrgOutline( timeline: Timeline.State, prefs: Prefs.Prefs, @@ -397,14 +443,46 @@ export function drawLaneFrgOutline( ctx.strokeStyle = prefs.timeline.measureColor ctx.lineWidth = 1 ctx.beginPath() - ctx.moveTo(lane.rect.x, lane.rect.y) - ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y) - ctx.moveTo(lane.rect.x, lane.rect.y + lane.rect.h) - ctx.lineTo(lane.rect.x + lane.rect.w, lane.rect.y + lane.rect.h) + ctx.moveTo(0, 0) + ctx.lineTo(lane.rect.w, 0) + ctx.moveTo(0, lane.rect.h) + ctx.lineTo(lane.rect.w, lane.rect.h) ctx.stroke() } +export function drawLaneBkgOutOfBounds( + timeline: Timeline.State, + prefs: Prefs.Prefs, + ctx: CanvasRenderingContext2D, + lane: Timeline.Lane) +{ + ctx.fillStyle = CanvasUtils.fillStyleForOutOfBounds(ctx, prefs) + + const leftX2 = Math.floor(Timeline.xAtTime(timeline, timeline.layout.inBoundsRange.start)) + + if (leftX2 > 0) + { + ctx.fillRect( + 0, + 0, + leftX2, + lane.rect.h) + } + + const rightX1 = Math.floor(Timeline.xAtTime(timeline, timeline.layout.inBoundsRange.end)) + + if (rightX1 < lane.rect.w) + { + ctx.fillRect( + rightX1, + 0, + lane.rect.w - rightX1, + lane.rect.h) + } +} + + export function drawLaneBkgMeasures( timeline: Timeline.State, prefs: Prefs.Prefs, @@ -427,8 +505,8 @@ export function drawLaneBkgMeasures( ctx.strokeStyle = prefs.timeline.measureColor ctx.lineWidth = 2 ctx.beginPath() - ctx.moveTo(x1 + 0.5, lane.rect.y) - ctx.lineTo(x1 + 0.5, lane.rect.y + lane.rect.h) + ctx.moveTo(x1 + 0.5, 0) + ctx.lineTo(x1 + 0.5, lane.rect.h) ctx.stroke() } @@ -445,8 +523,8 @@ export function drawLaneBkgMeasures( if (submeasureX >= x2) break - ctx.moveTo(submeasureX, lane.rect.y) - ctx.lineTo(submeasureX, lane.rect.y + lane.rect.h) + ctx.moveTo(submeasureX, 0) + ctx.lineTo(submeasureX, lane.rect.h) } ctx.stroke() @@ -467,8 +545,8 @@ export function drawLaneBkgMeasures( ctx.strokeStyle = color ctx.lineWidth = 2 ctx.beginPath() - ctx.moveTo(x + 0.5, lane.rect.y) - ctx.lineTo(x + 0.5, lane.rect.y + lane.rect.h) + ctx.moveTo(x + 0.5, 0) + ctx.lineTo(x + 0.5, lane.rect.h) ctx.stroke() } } @@ -482,8 +560,8 @@ export function drawLaneBkgOctaves( lane: Timeline.Lane, mainLinePass: boolean) { - const rowAtTop = Timeline.rowAtY(timeline, lane, lane.rect.y) - const rowAtBottom = Timeline.rowAtY(timeline, lane, lane.rect.y + lane.rect.h) + const rowAtTop = Timeline.rowAtY(timeline, lane, 0) + const rowAtBottom = Timeline.rowAtY(timeline, lane, lane.rect.h) const octaveAtTop = Math.ceil(rowAtTop / 7) + 1 const octaveAtBottom = Math.floor(rowAtBottom / 7) - 1 @@ -519,7 +597,8 @@ export function drawLaneBkgOctaves( for (let i = octaveAtBottom; i <= octaveAtTop; i++) { const y = Math.floor( - Timeline.yForRow(timeline, lane, tonicRowOffset + i * scaleLength) + timeline.noteRowH) + Timeline.yForRow(timeline, lane, tonicRowOffset + i * scaleLength) + + timeline.noteRowH) if (mainLinePass) { @@ -647,8 +726,8 @@ function drawCursorBkg( laneIndexMax < lane.laneIndex) return - const y1 = Math.floor(lane.rect.y) - const y2 = Math.floor(lane.rect.y2) + const y1 = 0 + const y2 = Math.floor(lane.rect.h) const x1 = Timeline.xAtTime(timeline, timeMin) const x2 = Timeline.xAtTime(timeline, timeMax) diff --git a/src/timeline/layout.ts b/src/timeline/layout.ts index a4d9b8b..86d0847 100644 --- a/src/timeline/layout.ts +++ b/src/timeline/layout.ts @@ -102,8 +102,26 @@ export interface KeyRegion { keyCh1: Project.KeyChange keyCh2: Project.KeyChange + range: Range + x1: number + x2: number +} + + +export interface ChordRegionTone +{ + row: number + degree: number +} + + +export interface ChordRegion +{ + key: Theory.Key + chord: Theory.Chord x1: number x2: number + tones: ChordRegionTone[] } @@ -118,10 +136,12 @@ export interface Marker export class Layout { range: Range + inBoundsRange: Range lanes: Timeline.Lane[] = [] measures: Project.Measure[] = [] keyRegions: KeyRegion[] = [] + chordRegions: ChordRegion[] = [] markers: Marker[] = [] @@ -158,8 +178,10 @@ export function layout( timeline.layout = layout layout.range = Timeline.visibleTimeRange(timeline) + layout.inBoundsRange = project.range layout.measures = [...Project.iterMeasuresAtRange(project, layout.range)] layout.keyRegions = [...iterKeyChangePairsAtRange(timeline, project, layout.range)] + layout.chordRegions = [...iterChordRegions(timeline, project, layout.keyRegions)] layout.markers = [] @@ -213,6 +235,10 @@ function *iterKeyChangePairsAtRange( const keyCh2 = pair[1] as Project.KeyChange ?? Project.makeKeyChange(-1, range.end, defaultKey) + + const regionRange = new Range( + keyCh1.range.start.max(range.start), + keyCh2.range.start.min(range.end)) const x1 = Timeline.xAtTime(timeline, keyCh1.range.start) const x2 = Timeline.xAtTime(timeline, keyCh2.range.start) @@ -220,8 +246,50 @@ function *iterKeyChangePairsAtRange( yield { keyCh1, keyCh2, + range: regionRange, x1, x2, } } +} + + +function *iterChordRegions( + timeline: Timeline.State, + project: Project.ImmutableRoot, + keyRegions: KeyRegion[]) + : Generator +{ + const chordTrackElems = project.lists.get(project.chordTrackId) + if (!chordTrackElems) + return + + for (const keyRegion of keyRegions) + { + const key = keyRegion.keyCh1.key + + for (const elem of chordTrackElems.iterAtRange(keyRegion.range)) + { + const chord = elem as Project.Chord + const x1 = Timeline.xAtTime(timeline, chord.range.start.max(keyRegion.range.start)) + const x2 = Timeline.xAtTime(timeline, chord.range.end.min(keyRegion.range.end)) + + const tones: ChordRegionTone[] = chord.chord.pitches.map(pitch => { + const row = Timeline.rowForPitch(pitch, key) + const degree = key.degreeForMidi(pitch) + return { + row, + degree, + } + }) + + yield { + key: keyRegion.keyCh1.key, + chord: chord.chord, + x1, + x2, + tones, + } + } + } } \ No newline at end of file diff --git a/src/timeline/mouse_up.ts b/src/timeline/mouse_up.ts index 23723fe..7c61456 100644 --- a/src/timeline/mouse_up.ts +++ b/src/timeline/mouse_up.ts @@ -18,5 +18,6 @@ export function mouseUp( const origProject = project.root Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) + project.root = Project.withRefreshedRange(project.root) return project.root !== origProject } \ No newline at end of file diff --git a/src/utils/canvasUtils.ts b/src/utils/canvasUtils.ts index 989efcf..8a9bd70 100644 --- a/src/utils/canvasUtils.ts +++ b/src/utils/canvasUtils.ts @@ -4,26 +4,18 @@ import * as MathUtils from "./mathUtils" import Rect from "./rect" -const fillPatterns = new Map() +const fillPatterns = new Map() -export function fillStyleForDegree(ctx: CanvasRenderingContext2D, degree: number, external: boolean): any +function createStripedPattern( + cacheKey: string, + ctx: CanvasRenderingContext2D, + color1: string, + color2: string) { - degree = MathUtils.mod(degree, 7) - - const colorFn = external ? Theory.Utils.degreeToColorFaded : Theory.Utils.degreeToColor - - if (Math.floor(degree) === degree) - return colorFn(degree) - - const cacheKey = degree + (external ? 100 : 0) - if (fillPatterns.has(cacheKey)) return fillPatterns.get(cacheKey) - const colorBefore = colorFn(MathUtils.mod(Math.floor(degree), 7)) - const colorAfter = colorFn(MathUtils.mod(Math.ceil(degree), 7)) - const canvas = document.createElement("canvas") canvas.width = 24 canvas.height = 24 @@ -31,10 +23,10 @@ export function fillStyleForDegree(ctx: CanvasRenderingContext2D, degree: number document.body.appendChild(canvas) let ctxPatt = canvas.getContext("2d")! - ctxPatt.fillStyle = colorBefore + ctxPatt.fillStyle = color1 ctxPatt.fillRect(0, 0, 24, 24) - ctxPatt.fillStyle = colorAfter + ctxPatt.fillStyle = color2 ctxPatt.beginPath() ctxPatt.moveTo(12, 0) ctxPatt.lineTo(24, 0) @@ -47,12 +39,52 @@ export function fillStyleForDegree(ctx: CanvasRenderingContext2D, degree: number ctxPatt.lineTo(24 - 12, 24) ctxPatt.fill() - const pattern = ctx.createPattern(canvas, "repeat") + const pattern = ctx.createPattern(canvas, "repeat")! fillPatterns.set(cacheKey, pattern) return pattern } +export function fillStyleForDegree(ctx: CanvasRenderingContext2D, degree: number, external: boolean): any +{ + degree = MathUtils.mod(degree, 7) + + const colorFn = external ? + Theory.Utils.degreeToColorFaded : + Theory.Utils.degreeToColor + + if (Math.floor(degree) === degree) + return colorFn(degree) + + const cacheKey = degree.toString() + (external ? ".ext" : 0) + + if (fillPatterns.has(cacheKey)) + return fillPatterns.get(cacheKey) + + const color1 = colorFn(MathUtils.mod(Math.floor(degree), 7)) + const color2 = colorFn(MathUtils.mod(Math.ceil(degree), 7)) + + return createStripedPattern( + cacheKey, + ctx, + color1, + color2) +} + + +export function fillStyleForOutOfBounds( + ctx: CanvasRenderingContext2D, + prefs: Prefs.Prefs) + : any +{ + return createStripedPattern( + "oob", + ctx, + prefs.timeline.outOfBoundsColor1, + prefs.timeline.outOfBoundsColor2) +} + + export function drawChord( ctx: CanvasRenderingContext2D, rect: Rect, From 1a293e8d0395011b112aeb8b55de39292e73950f Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Thu, 25 Dec 2025 22:55:57 -0300 Subject: [PATCH 11/20] improve chord inspector --- src/components/Checkbox.tsx | 79 +++++++++ src/components/index.ts | 1 + src/inspector/InspectorChord.tsx | 256 +++++++++++++++------------ src/inspector/InspectorInsert.tsx | 48 +++-- src/inspector/InspectorKeyChange.tsx | 2 +- src/main.tsx | 1 + src/theory/chord.ts | 4 +- src/theory/chordOptions.ts | 9 + src/theory/utils.ts | 9 +- src/timeline/draw.ts | 3 +- src/utils/canvasUtils.ts | 2 +- 11 files changed, 282 insertions(+), 132 deletions(-) create mode 100644 src/components/Checkbox.tsx create mode 100644 src/components/index.ts diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx new file mode 100644 index 0000000..0e9169b --- /dev/null +++ b/src/components/Checkbox.tsx @@ -0,0 +1,79 @@ +import * as Solid from "solid-js" +import { styled } from "solid-styled-components" + + +export function Checkbox(props: { + children?: Solid.JSXElement, + label?: Solid.JSXElement, + checked?: boolean, + onChange?: (newValue: boolean) => void, + groupStart?: boolean, + groupMiddle?: boolean, + groupEnd?: boolean, +}) +{ + return props.onChange?.(!props.checked) } + > + { props.label ?? props.children } + +} + + +const StyledButton = styled.button<{ + "data-checked": boolean, + "data-group-start": boolean, + "data-group-middle": boolean, + "data-group-end": boolean, +}>` + display: inline-block; + justify-self: stretch; + align-self: center; + user-select: none; + cursor: pointer; + + margin: 0.25em; + padding: 0.25em 0.5em; + border: 0; + border-radius: var(--theme-buttonBorderRadius); + background-color: var(--theme-buttonBkg); + color: inherit; + font-family: inherit; + + &:hover { + background-color: var(--theme-buttonBkgHover); + } + + &:active { + background-color: var(--theme-buttonBkgPress); + } + + &[data-checked=true] { + background-color: var(--theme-buttonBkgSelected); + } + + &[data-group-start=true] { + margin-left: 0.25em; + margin-right: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + &[data-group-middle=true] { + margin-left: 0; + margin-right: 0; + border-radius: 0; + } + + &[data-group-end=true] { + margin-left: 0; + margin-right: 0.25em; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +` +//${ props => props.$checked ? "background-color: var(--theme-buttonBkgSelected);" : "" } \ No newline at end of file diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..7687ffc --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1 @@ +export * from "./Checkbox.tsx" \ No newline at end of file diff --git a/src/inspector/InspectorChord.tsx b/src/inspector/InspectorChord.tsx index 977fbc1..bbbb158 100644 --- a/src/inspector/InspectorChord.tsx +++ b/src/inspector/InspectorChord.tsx @@ -7,6 +7,7 @@ import * as Theory from "../theory" import Rect from "../utils/rect.ts" import * as CanvasUtils from "../utils/canvasUtils.ts" import { styled } from "solid-styled-components" +import { Checkbox } from "../components" export function InspectorChord(props: { @@ -108,111 +109,131 @@ export function InspectorChord(props: { return <> -

Chord

- - + { props.key.chroma.map((chroma, degree) => makeChordButton()(degree) )} - - -
- setChordOptions(opts => ({ ...opts, withStacking: 0 })) } - /> Triad - setChordOptions(opts => ({ ...opts, withStacking: 7 })) } - /> 7 - setChordOptions(opts => ({ ...opts, withStacking: 9 })) } - /> 9 - setChordOptions(opts => ({ ...opts, withStacking: 11 })) } - /> 11 - setChordOptions(opts => ({ ...opts, withStacking: 13 })) } - /> 13 -
- setChordOptions(opts => ({ ...opts, withSus2: ev.target.checked })) } - /> sus2 - setChordOptions(opts => ({ ...opts, withSus4: ev.target.checked })) } - /> sus4 -
- setChordOptions(opts => ({ ...opts, withAdd9: ev.target.checked })) } - /> add9 - setChordOptions(opts => ({ ...opts, withAdd11: ev.target.checked })) } - /> add11 - setChordOptions(opts => ({ ...opts, withAdd13: ev.target.checked })) } - /> add13 -
- setChordOptions(opts => ({ ...opts, withNo3: ev.target.checked })) } - /> no3 - setChordOptions(opts => ({ ...opts, withNo5: ev.target.checked })) } - /> no5 - setChordOptions(opts => ({ ...opts, withFlat5: ev.target.checked })) } - /> flat5 - setChordOptions(opts => ({ ...opts, withSharp5: ev.target.checked })) } - /> sharp5 -
- setChordOptions(opts => ({ ...opts, withFlat9: ev.target.checked })) } - /> flat9 - setChordOptions(opts => ({ ...opts, withSharp9: ev.target.checked })) } - /> sharp9 - setChordOptions(opts => ({ ...opts, withSharp11: ev.target.checked })) } - /> sharp11 - setChordOptions(opts => ({ ...opts, withFlat13: ev.target.checked })) } - /> flat13 -
-
+ + + +
+ setChordOptions(opts => ({ ...opts, withStacking: 0 })) } + /> + setChordOptions(opts => ({ ...opts, withStacking: ev ? 7 : 0 })) } + /> + setChordOptions(opts => ({ ...opts, withStacking: ev ? 9 : 0 })) } + /> + setChordOptions(opts => ({ ...opts, withStacking: ev ? 11 : 0 })) } + /> + setChordOptions(opts => ({ ...opts, withStacking: ev ? 13 : 0 })) } + /> +
+
+ setChordOptions(opts => ({ ...opts, withSus2: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withSus4: ev })) } + /> +
+
+ setChordOptions(opts => ({ ...opts, withAdd9: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withAdd11: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withAdd13: ev })) } + /> +
+
+ setChordOptions(opts => ({ ...opts, withNo3: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withNo5: ev })) } + /> +
+
+ setChordOptions(opts => ({ ...opts, withFlat5: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withSharp5: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withFlat9: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withSharp9: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withSharp11: ev })) } + /> +
+ setChordOptions(opts => ({ ...opts, withFlat13: ev })) } + /> +
+
@@ -221,28 +242,39 @@ export function InspectorChord(props: { const Layout = styled.div` display: grid; - grid-template: auto 1fr / auto auto auto; + grid-template: auto / auto auto; width: 100%; height: 100%; min-height: 0; justify-content: center; justify-items: center; - align-content: center; - align-items: center; + align-content: start; + align-items: start; column-gap: 1em; ` -const LayoutMainButtons = styled.div` +const LayoutChordButtons = styled.div` display: grid; - grid-template: auto / repeat(7, 1fr); - grid-column: 1 / -1; + grid-template: 1fr / repeat(7, 1fr); width: 100%; height: 100%; justify-content: center; justify-items: center; - align-content: center; - align-items: center; + align-content: start; + align-items: start; + column-gap: 0.5em; +` + + +const LayoutChordOptions = styled.div` + display: grid; + grid-template: repeat(6, auto) / repeat(3, auto); + justify-content: start; + justify-items: start; + align-content: start; + align-items: start; + row-gap: 0.5em; column-gap: 1em; ` @@ -250,10 +282,10 @@ const LayoutMainButtons = styled.div` const ChordButton = styled.button<{ }>` border: 0; - border-radius: 5px; + border-radius: var(--theme-buttonBorderRadius); margin: 0; padding: 0; - width: 6em; + width: 5em; height: 3.5em; background-color: #fff; cursor: pointer; diff --git a/src/inspector/InspectorInsert.tsx b/src/inspector/InspectorInsert.tsx index 9e9e6c0..2aeaa65 100644 --- a/src/inspector/InspectorInsert.tsx +++ b/src/inspector/InspectorInsert.tsx @@ -21,6 +21,25 @@ export function InspectorInsert(props: { return Project.keyAt(project.root, project.root.noteTrackId, time()) }) + const insertionKind = Solid.createMemo(() => { + const timeline = Global.get().timeline + if (timeline.selection.size !== 0) + return null + + if (timeline.cursor.laneIndex1 !== timeline.cursor.laneIndex2) + return null + + const lane = timeline.layout.lanes[timeline.cursor.laneIndex1] + + if (lane instanceof Timeline.LaneChords) + return "chord" + + if (lane instanceof Timeline.LaneNotes) + return "note" + + return null + }) + const insertKeyChange = () => { const project = Global.get().project const timeline = Global.get().timeline @@ -67,24 +86,29 @@ export function InspectorInsert(props: { } return - - -
- + +
+ + +
+
+ + +
} const Layout = styled.div` display: grid; - grid-template: auto 1fr / auto auto; + grid-template: auto 1fr / auto; width: 100%; height: 100%; min-height: 0; diff --git a/src/inspector/InspectorKeyChange.tsx b/src/inspector/InspectorKeyChange.tsx index b2a2a3e..5f51d5e 100644 --- a/src/inspector/InspectorKeyChange.tsx +++ b/src/inspector/InspectorKeyChange.tsx @@ -273,7 +273,7 @@ const ScaleButton = styled.div<{ width: 90%; margin: 0.25em; padding: 0.25em 0.5em; - border-radius: 0.25em; + border-radius: var(--theme-buttonBorderRadius); background-color: var(--theme-buttonBkg); &:hover { diff --git a/src/main.tsx b/src/main.tsx index e675aaa..8ea0f4c 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -34,6 +34,7 @@ const AppRoot = styled.div` --theme-buttonBkgHover: #555; --theme-buttonBkgPress: #333; --theme-buttonBkgSelected: #06a; + --theme-buttonBorderRadius: 0.25em; ` diff --git a/src/theory/chord.ts b/src/theory/chord.ts index 9414703..bc62676 100644 --- a/src/theory/chord.ts +++ b/src/theory/chord.ts @@ -605,7 +605,7 @@ export default class Chord { const chroma = key.chromaForDegree(this.baseDegree + degree) const chromaInCMajor = this.rootChroma + Theory.Scale.majorScale.chromas[degree % 7] + accidental - const finalAccidental = Theory.Utils.modAccidental(chromaInCMajor - chroma) + const finalAccidental = Theory.Utils.modRomanAccidental(chromaInCMajor - chroma) return Theory.Utils.accidentalToStr(finalAccidental) } @@ -785,7 +785,7 @@ export default class Chord add5Roman !== undefined && (kind.add5 === undefined || add5Roman !== kind.add5)) { - const accidentalStr = Chord.accidentalStrForName(add5Roman) + const accidentalStr = this.accidentalStrForRoman(key, 4, add5Roman) if (accidentalStr !== "") { romanSup += `(${ accidentalStr }5)` diff --git a/src/theory/chordOptions.ts b/src/theory/chordOptions.ts index df088e9..de9e13f 100644 --- a/src/theory/chordOptions.ts +++ b/src/theory/chordOptions.ts @@ -161,15 +161,24 @@ export namespace ChordOptions if (chord.add9 === -1) opts.withFlat9 = true + if (chord.add9 === 0) + opts.withAdd9 = true + if (chord.add9 === 1) opts.withSharp9 = true + if (chord.add11 === 0) + opts.withAdd11 = true + if (chord.add11 === 1) opts.withSharp11 = true if (chord.add13 === -1) opts.withFlat13 = true + if (chord.add13 === 0) + opts.withAdd13 = true + return opts } } \ No newline at end of file diff --git a/src/theory/utils.ts b/src/theory/utils.ts index 7f44f64..39a82c8 100644 --- a/src/theory/utils.ts +++ b/src/theory/utils.ts @@ -10,6 +10,11 @@ export default class Utils return Utils.mod(accidental + 6, 12) - 6 } + static modRomanAccidental(accidental: number) + { + return Utils.mod(accidental + 4, 7) - 4 + } + static accidentalFor(chroma: number, fromBaseChroma: number) { const accidental1 = chroma - fromBaseChroma @@ -73,8 +78,8 @@ export default class Utils return "𝄫" if (accidental < 0) - return (useUnicode ? "\u{266d}" : "b").repeat(-accidental) + return (useUnicode ? "♭" : "b").repeat(-accidental) else - return (useUnicode ? "\u{266f}" : "#").repeat(accidental) + return (useUnicode ? "♯" : "#").repeat(accidental) } } \ No newline at end of file diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index 9b16046..0a6c64f 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -416,8 +416,7 @@ export function drawLaneBkgChordTones( for (let i = octaveAtBottom; i <= octaveAtTop; i++) { const y = Math.floor( - Timeline.yForRow(timeline, lane, tone.row + (5 + i) * scaleLength) + - timeline.noteRowH) + Timeline.yForRow(timeline, lane, tone.row + (5 + i) * scaleLength)) ctx.fillStyle = fillStyle ctx.beginPath() diff --git a/src/utils/canvasUtils.ts b/src/utils/canvasUtils.ts index 8a9bd70..575b019 100644 --- a/src/utils/canvasUtils.ts +++ b/src/utils/canvasUtils.ts @@ -155,7 +155,7 @@ export function drawChord( rect.yCenter + rect.h * (0.05 - 0.1), rect.h * 0.5, rect.h * -0.15, - rect.h * 0.05, + rect.h * 0.075, maxWidth) drawChordName( From 45ca263d442bda2b6dabc05051207cb7c7ca8750 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Fri, 26 Dec 2025 15:41:48 -0300 Subject: [PATCH 12/20] add playback --- src/main.tsx | 2 + src/playback/eventStream.ts | 287 +++++++++++++++++++++++ src/playback/index.ts | 4 + src/playback/instrument.ts | 61 +++++ src/playback/instrumentBasic.ts | 284 +++++++++++++++++++++++ src/playback/manager.ts | 387 ++++++++++++++++++++++++++++++++ src/prefs.ts | 2 +- src/shortcuts.ts | 62 +++++ src/state.ts | 3 + src/timeline/Element.tsx | 23 +- src/timeline/draw.ts | 65 +++++- src/timeline/mouse_down.ts | 2 + src/timeline/timeline.ts | 4 + 13 files changed, 1174 insertions(+), 12 deletions(-) create mode 100644 src/playback/eventStream.ts create mode 100644 src/playback/index.ts create mode 100644 src/playback/instrument.ts create mode 100644 src/playback/instrumentBasic.ts create mode 100644 src/playback/manager.ts create mode 100644 src/shortcuts.ts diff --git a/src/main.tsx b/src/main.tsx index 8ea0f4c..96e9672 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -4,11 +4,13 @@ import { styled } from "solid-styled-components" import * as State from "./state.ts" import * as Timeline from "./timeline" import * as Inspector from "./inspector" +import { setupKeyboardShortcuts } from "./shortcuts.ts" function App() { State.get() + setupKeyboardShortcuts() return diff --git a/src/playback/eventStream.ts b/src/playback/eventStream.ts new file mode 100644 index 0000000..493ccef --- /dev/null +++ b/src/playback/eventStream.ts @@ -0,0 +1,287 @@ +import * as Playback from "./index" +import * as Project from "../project" +import * as Theory from "../theory" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" +import * as MathUtils from "../utils/mathUtils.ts" + + +export interface NoteEvent +{ + project: Project.ImmutableRoot, + trackId: Project.ID + + startMs: number + endMs: number + + midiPitchSeq: TimeVariableProperty[] + volumeSeq: TimeVariableProperty[] + velocitySeq: TimeVariableProperty[] +} + + +export interface TimeVariableProperty +{ + timeMs: number + value: number +} + + +export function queryNoteEvents( + project: Project.ImmutableRoot, + range: Range, + isStart: boolean) + : NoteEvent[] +{ + const noteEvents: NoteEvent[] = [] + + for (const [track, note] of iterNotesAtRange(project, range)) + { + if (range.overlapsPoint(note.range.start) || + (isStart && note.range.overlapsPoint(range.start))) + { + noteEvents.push(makeNoteEvent( + project, + track.id, + note.range, + note.midiPitch, + 0,//note.volumeDb, + 1))//note.velocity) + } + } + + const chordTrack = Project.getTrack(project, project.chordTrackId, "chords") + const chordList = project.lists.get(project.chordTrackId) + if (chordTrack && chordList) + { + for (const chord of chordList.iterAtRange(range)) + { + if (range.overlapsPoint(chord.range.start) || + (isStart && chord.range.overlapsPoint(range.start))) + { + playChord( + project, + chordTrack, + noteEvents, + range, + chord as Project.Chord) + } + } + } + + return noteEvents +} + + +function makeNoteEvent( + project: Project.ImmutableRoot, + trackId: Project.ID, + noteRange: Range, + midiPitch: number, + volumeDb: number, + velocity: number) + : Playback.NoteEvent +{ + const startMs = + Project.getMillisecondsAt(project, noteRange.start) + + const endMs = + Project.getMillisecondsAt(project, noteRange.end) + + return { + project, + trackId, + + startMs: startMs, + endMs: endMs, + + midiPitchSeq: [{ timeMs: startMs, value: midiPitch }], + volumeSeq: [{ timeMs: startMs, value: volumeDb }], + velocitySeq: [{ timeMs: startMs, value: velocity }], + } +} + + +function *iterNotesAtRange( + project: Project.ImmutableRoot, + range: Range) + : Generator<[Project.TrackNotes, Project.Note], void, void> +{ + for (const track of project.tracks) + { + if (track.trackType !== "notes") + continue + + const noteList = project.lists.get(track.id) + if (!noteList) + continue + + for (const elem of noteList.iterAtRange(range)) + { + if (elem.range.duration.isZero()) + continue + + if (!elem.range.overlapsRange(range)) + continue + + yield [track, elem as Project.Note] + } + } +} + + +function playChord( + project: Project.ImmutableRoot, + chordTrack: Project.TrackChords, + noteEvents: NoteEvent[], + range: Range, + chord: Project.Chord) +{ + const addNoteEvent = (start: Rational, duration: Rational, midiPitch: number, volume: number) => { + if (start.add(duration).compare(range.start) <= 0) + return + + noteEvents.push(makeNoteEvent( + project, + chordTrack.id, + Range.fromStartDuration(start, duration), + midiPitch, + MathUtils.linearGainToDb(volume), + 1)) + } + + /*if (chord.range.end.compare(startTick) <= 0) + continue*/ + + const pitches = chord.chord.strummingPitches + + /*if (!useChordPatterns) + { + for (let j = 0; j < pitches.length; j++) + addNoteEvent(chord.range.start, chord.range.duration, pitches[j], chordVolumeMul) + + continue + }*/ + + const measures = Project.iterMeasuresAtRange(project, chord.range) + for (const measure of measures) + { + const meter = measure.meterCh.meter + const meterBeatLength = new Rational(1, meter.denominator) + const pattern = getChordStrummingPattern(meter) + + let tick = measure.time1 + const endTime = chord.range.end.min(measure.time2) + + let mustPlayFirstBeat = false + let skipTick = new Rational(0) + let patternIndex = 0 + + while (tick.compare(endTime) < 0) + { + const patternBeat = pattern[patternIndex] + const patternBeatKind = patternBeat[0] + let patternBeatLength = patternBeat[1].multiply(meterBeatLength) + patternIndex = (patternIndex + 1) % pattern.length + + let nextTick = tick.add(patternBeatLength) + if (nextTick.compare(endTime) > 0) + { + nextTick = endTime + patternBeatLength = nextTick.subtract(tick) + } + + // Handle beats after the first one. + if (tick.compare(chord.range.start) > 0 && + skipTick.compare(new Rational(0)) <= 0) + { + if (mustPlayFirstBeat) + { + mustPlayFirstBeat = false + for (let j = 0; j < pitches.length; j++) + addNoteEvent(chord.range.start, tick.subtract(chord.range.start), pitches[j], 1) + } + + switch (patternBeatKind) + { + case 0: + { + for (let j = 0; j < pitches.length; j++) + addNoteEvent(tick, patternBeatLength, pitches[j], 0.9) + break + } + case 1: + { + for (let j = 1; j < pitches.length; j++) + addNoteEvent(tick, patternBeatLength, pitches[j], 0.5) + break + } + case 2: + { + addNoteEvent(tick, patternBeatLength, pitches[0], 0.5) + break + } + } + } + + skipTick = skipTick.subtract(patternBeatLength) + + if (tick.compare(chord.range.start) <= 0 && + nextTick.compare(chord.range.start) > 0) + { + mustPlayFirstBeat = true + + if (tick.compare(chord.range.start) !== 0 || + patternBeatKind !== 0) + skipTick = pattern[0][1].multiply(meterBeatLength) + } + + tick = nextTick + } + + if (mustPlayFirstBeat) + { + mustPlayFirstBeat = false + for (let j = 0; j < pitches.length; j++) + addNoteEvent(chord.range.start, tick.subtract(chord.range.start), pitches[j], 0.7) + } + } +} + + +function getChordStrummingPattern(meter: Theory.Meter) +{ + // [[beat kind, duration], ...] + // Beat kinds: + // 0: Full chord + // 1: Full chord minus bass + // 2: Only bass + const one: [number, Rational][] = + [[0, new Rational(1)]] + + const two: [number, Rational][] = + [[0, new Rational(1)], [1, new Rational(1, 2)], [2, new Rational(1, 2)]] + + const three: [number, Rational][] = + [[0, new Rational(1)], [1, new Rational(1) ], [1, new Rational(1) ]] + + switch (meter.numerator) + { + case 2: return two + case 3: return three + case 4: return two.concat(two) + case 5: return three.concat(two) + case 6: return three.concat(three) + case 7: return three.concat(two).concat(two) + case 8: return two.concat(two).concat(two).concat(two) + case 9: return three.concat(three).concat(three) + + default: + { + let pattern: [number, Rational][] = [] + for (let i = 0; i < meter.numerator; i++) + pattern = pattern.concat(one) + return pattern + } + } +} \ No newline at end of file diff --git a/src/playback/index.ts b/src/playback/index.ts new file mode 100644 index 0000000..70c787d --- /dev/null +++ b/src/playback/index.ts @@ -0,0 +1,4 @@ +export * from "./manager.ts" +export * from "./eventStream.ts" +export * from "./instrument.ts" +export * from "./instrumentBasic.ts" \ No newline at end of file diff --git a/src/playback/instrument.ts b/src/playback/instrument.ts new file mode 100644 index 0000000..480e5b0 --- /dev/null +++ b/src/playback/instrument.ts @@ -0,0 +1,61 @@ +import * as Playback from "./index" +import * as Project from "../project" +import * as MathUtils from "../utils/mathUtils.ts" +import Range from "../utils/range.ts" + + +export class Instrument +{ + manager: Playback.Manager + gainNode: GainNode + + + constructor(manager: Playback.Manager) + { + this.manager = manager + + this.gainNode = this.manager.audioCtx!.createGain() + this.gainNode.gain.value = 1//trackIsMuted ? 0 : MathUtils.dbToLinearGain(0) + this.gainNode.connect(this.manager.nodeGlobalVolume!) + } + + + async prepare(noteEvent: Playback.NoteEvent) + { + + } + + + async destroy() + { + + } + + + isFinished() + { + return true + } + + + playNote( + noteEvent: Playback.NoteEvent, + audioCtxTimestampMs: number) + { + + } + + + stopAll() + { + + } + + + process( + audioCtxTimestampMs: number, + deltaTimeMs: number) + { + + } +} \ No newline at end of file diff --git a/src/playback/instrumentBasic.ts b/src/playback/instrumentBasic.ts new file mode 100644 index 0000000..ec0ef10 --- /dev/null +++ b/src/playback/instrumentBasic.ts @@ -0,0 +1,284 @@ +import * as Playback from "./index" +import * as Project from "../project" +import * as MathUtils from "../utils/mathUtils.ts" +import Range from "../utils/range.ts" + + +interface Sample +{ + frequency: number + buffer: AudioBuffer | null +} + + +interface Note +{ + voices: Voice[] +} + + +interface Voice +{ + nodeSrc: AudioBufferSourceNode + nodeEnvelope: GainNode + nodeVolume: GainNode + endMs: number +} + + +const releaseDurationMs = 100 + + +const sampleDefs = [ + { frequency: 55.0, src: "audio/piano/a1.mp3" }, + { frequency: 110.0, src: "audio/piano/a2.mp3" }, + { frequency: 220.0, src: "audio/piano/a3.mp3" }, + { frequency: 440.0, src: "audio/piano/a4.mp3" }, + { frequency: 880.0, src: "audio/piano/a5.mp3" }, + { frequency: 1760.0, src: "audio/piano/a6.mp3" }, + //{ frequency: 3520.0, src: "audio/piano/a7.mp3" }, +] + + +export class InstrumentBasic extends Playback.Instrument +{ + samples: (Sample | undefined)[] + notes: Note[] + + + constructor(manager: Playback.Manager) + { + super(manager) + + this.samples = [] + for (const _ of sampleDefs) + this.samples.push(undefined) + + this.notes = [] + } + + + override async prepare(noteEvent: Playback.NoteEvent) + { + const neededSamples = this.getNeededSamples(noteEvent) + + for (const neededSample of neededSamples) + { + const index = neededSample.sampleIndex + + if (this.samples[index]) + continue + + this.samples[index] = { frequency: 0, buffer: null } + this.samples[index] = await this.load(sampleDefs[index]) + } + } + + + async load(sampleDef: typeof sampleDefs[0]): Promise + { + const sample: Sample = { + buffer: null, + frequency: sampleDef.frequency, + } + + const src = sampleDef.src + + console.log(`load audio <${ src }>...`) + + return new Promise((resolve, reject) => { + fetch(src) + .then(res => res.arrayBuffer()) + .then(arrayBuf => { + this.manager.audioCtx!.decodeAudioData( + arrayBuf, + (audioBuf: AudioBuffer) => { + sample.buffer = audioBuf + resolve(sample) + }, + () => { + console.error(`error loading audio <${ src }>`) + reject() + }) + }) + }) + } + + + override isFinished() + { + return this.notes.length === 0 + } + + + getNeededSamples(noteEvent: Playback.NoteEvent) + { + const desiredFreq = MathUtils.midiToHertz(noteEvent.midiPitchSeq[0].value) + + // Find the primary sample whose frequency is nearest to the desired frequency. + let sampleIndex1 = 0 + let sample1Dist = Math.abs(sampleDefs[0].frequency - desiredFreq) + for (let i = 1; i < sampleDefs.length; i++) + { + const dist = Math.abs(sampleDefs[i].frequency - desiredFreq) + if (dist < sample1Dist) + { + sampleIndex1 = i + sample1Dist = dist + } + } + + // Find the sample whose frequency is second nearest to the desired frequency, + // unless the primary sample is already exactly a match. + // Then, calculate a cross-fade between the two. + // TODO: Probably should use an equal-power (logarithmic) cross-fade, + // but this seems good enough for now. + let sampleIndex2 = null + + let volume1 = 1 + let volume2 = 0 + + if (sampleDefs[sampleIndex1].frequency < desiredFreq) + { + if (sampleIndex1 + 1 < sampleDefs.length) + { + sampleIndex2 = sampleIndex1 + 1 + + const t = + (desiredFreq - sampleDefs[sampleIndex1].frequency) / + (sampleDefs[sampleIndex2].frequency - sampleDefs[sampleIndex1].frequency) + + volume1 = 1 - t + volume2 = t + } + } + else if (sampleDefs[sampleIndex1].frequency > desiredFreq) + { + if (sampleIndex1 - 1 >= 0) + { + sampleIndex2 = sampleIndex1 - 1 + + const t = + (desiredFreq - sampleDefs[sampleIndex2].frequency) / + (sampleDefs[sampleIndex1].frequency - sampleDefs[sampleIndex2].frequency) + + volume1 = t + volume2 = 1 - t + } + } + + const samples = [{ + sampleIndex: sampleIndex1, + volume: volume1, + }] + + if (sampleIndex2 !== null) + { + samples.push({ + sampleIndex: sampleIndex2, + volume: volume2, + }) + } + + return samples + } + + + override playNote( + noteEvent: Playback.NoteEvent, + audioCtxTimestamp: number) + { + const neededSamples = this.getNeededSamples(noteEvent) + + const voices: Voice[] = [] + for (const neededSample of neededSamples) + { + const sample = this.samples[neededSample.sampleIndex] + if (!sample) + continue + + voices.push(this.playVoice( + noteEvent, + audioCtxTimestamp, + sample, + noteEvent.midiPitchSeq[0].value, + neededSample.volume * noteEvent.velocitySeq[0].value)) + } + + this.notes.push({ + voices, + }) + } + + + playVoice( + noteEvent: Playback.NoteEvent, + audioCtxTimestamp: number, + sample: Sample, + midiPitch: number, + volume: number) + : Voice + { + const sourceNode = this.manager.audioCtx!.createBufferSource() + sourceNode.buffer = sample.buffer + sourceNode.playbackRate.value = + MathUtils.midiToHertz(midiPitch) / sample.frequency + + const startMs = noteEvent.startMs + audioCtxTimestamp + const endMs = noteEvent.endMs + audioCtxTimestamp + + const envelopeNode = this.manager.audioCtx!.createGain() + envelopeNode.gain.value = 1 + envelopeNode.gain.setValueAtTime(1, endMs / 1000) + envelopeNode.gain.linearRampToValueAtTime(0, (endMs + 100) / 1000) + + const volumeNode = this.manager.audioCtx!.createGain() + volumeNode.gain.value = volume + + sourceNode.connect(envelopeNode) + envelopeNode.connect(volumeNode) + volumeNode.connect(this.gainNode) + + sourceNode.start(startMs / 1000) + + return { + nodeSrc: sourceNode, + nodeEnvelope: envelopeNode, + nodeVolume: volumeNode, + endMs: endMs + 100, + } + } + + + stopNote(note: Note) + { + for (const voice of note.voices) + { + voice.nodeEnvelope.gain.cancelScheduledValues(0) + voice.nodeEnvelope.disconnect() + voice.nodeVolume.gain.cancelScheduledValues(0) + voice.nodeVolume.disconnect() + voice.nodeSrc.stop() + voice.nodeSrc.disconnect() + voice.endMs = 0 + } + } + + + override stopAll() + { + for (const note of this.notes) + this.stopNote(note) + + this.notes = [] + } + + + override process( + audioCtxTimestampMs: number, + deltaTimeMs: number) + { + this.notes = this.notes.filter(note => + note.voices.some(v => audioCtxTimestampMs < v.endMs)) + } +} \ No newline at end of file diff --git a/src/playback/manager.ts b/src/playback/manager.ts new file mode 100644 index 0000000..6b39056 --- /dev/null +++ b/src/playback/manager.ts @@ -0,0 +1,387 @@ +import * as Global from "../state.ts" +import * as Playback from "./index" +import * as Project from "../project" +import * as MathUtils from "../utils/mathUtils.ts" +import Rational from "../utils/rational.ts" +import Range from "../utils/range.ts" + + +export const eventPlaybackRefresh = "playbackRefresh" + + +export class Manager +{ + audioCtx?: BaseAudioContext + nodeCompressor?: DynamicsCompressorNode + nodeGlobalVolume?: GainNode + + instruments: Playback.Instrument[] + + loading: number + playing: boolean + playingProject: Project.ImmutableRoot | undefined + firstPlayingFrame: boolean + startTime: Rational + startTimeMs: number + nextStartTime: Rational + playTimeFloat: number + playTime: Rational + preloadTime: Rational + refreshTimeMs: number + + audioCtxTimestamp: number + requestAnimationFrameId: number + requestAnimationFrameTimestamp: number + requestAnimationFrameDate: Date + setIntervalId: number + + + constructor()//toBuffer?: boolean, bufferLen?: number, bufferSampleRate?: number) + { + this.instruments = [] + + this.loading = 0 + this.playing = false + this.playingProject = undefined + this.firstPlayingFrame = false + this.startTime = new Rational(0) + this.startTimeMs = 0 + this.nextStartTime = new Rational(0) + this.playTimeFloat = 0 + this.playTime = new Rational(0) + this.preloadTime = new Rational(0) + this.refreshTimeMs = 0 + + this.requestAnimationFrameId = 0 + this.requestAnimationFrameTimestamp = 0 + this.requestAnimationFrameDate = new Date() + this.setIntervalId = 0 + + /*if (toBuffer) + { + this.audioCtx = new OfflineAudioContext(2, bufferLen!, bufferSampleRate!) + } + else + { + this.audioCtx = new AudioContext() + } + + this.nodeGlobalVolume = this.audioCtx.createGain() + this.nodeGlobalVolume.gain.value = 0.1 + + this.nodeCompressor = this.audioCtx.createDynamicsCompressor() + this.nodeCompressor.threshold.value = -10 + this.nodeCompressor.knee.value = 12 + this.nodeCompressor.ratio.value = 12 + this.nodeCompressor.attack.value = 0 + this.nodeCompressor.release.value = 0.05 + + this.nodeGlobalVolume.connect(this.nodeCompressor) + this.nodeCompressor.connect(this.audioCtx.destination)*/ + } + + + async start() + { + this.loading += 1 + + try + { + if (this.audioCtx) + return + + this.audioCtx = new AudioContext() + + this.nodeGlobalVolume = this.audioCtx.createGain() + this.nodeGlobalVolume.gain.value = 0.1 + + this.nodeCompressor = this.audioCtx.createDynamicsCompressor() + this.nodeCompressor.threshold.value = -10 + this.nodeCompressor.knee.value = 12 + this.nodeCompressor.ratio.value = 12 + this.nodeCompressor.attack.value = 0 + this.nodeCompressor.release.value = 0.05 + + this.nodeGlobalVolume.connect(this.nodeCompressor) + this.nodeCompressor.connect(this.audioCtx.destination) + } + finally + { + this.loading -= 1 + } + } + + + async prepare( + project: Project.ImmutableRoot, + range: Range, + isStart: boolean) + { + this.loading += 1 + + try + { + const tasks: Promise[] = [] + + for (const noteEvent of Playback.queryNoteEvents(project, range, isStart)) + { + const instrument = await this.prepareInstrument(noteEvent) + tasks.push(instrument.prepare(noteEvent)) + } + + await Promise.all(tasks) + } + finally + { + this.loading -= 1 + } + } + + + async prepareInstrument(noteEvent: Playback.NoteEvent) + { + if (this.instruments.length > 0) + return this.instruments[0] + + const instrument = new Playback.InstrumentBasic(this) + + this.instruments.push(instrument) + return instrument + } + + + async destroy() + { + if (this.audioCtx instanceof AudioContext) + await this.audioCtx.close() + } + + + isFinished() + { + for (const instrument of this.instruments) + { + if (!instrument.isFinished()) + return false + } + + return true + } + + + play() + { + + } + + + stopAll() + { + for (const instrument of this.instruments) + instrument.stopAll() + } + + + process( + audioCtxTimestampMs: number, + deltaTimeMs: number) + { + for (const instrument of this.instruments) + instrument.process(audioCtxTimestampMs, deltaTimeMs) + } + + + async playNote( + noteEvent: Playback.NoteEvent, + audioCtxOffsetMs: number) + { + const instrument = await this.prepareInstrument(noteEvent) + if (!instrument) + return + + instrument.playNote(noteEvent, audioCtxOffsetMs) + } + + + preloadNextBlock(isStart: boolean) + { + const preloadTimeNext = this.preloadTime.add(new Rational(4, 4)) + + const range = new Range( + this.preloadTime, + preloadTimeNext) + + this.prepare( + this.playingProject!, + range, + isStart) + + this.preloadTime = preloadTimeNext + } + + + processFrame(canRedrawScreen: boolean) + { + if (!this.playingProject) + return + + if (this.loading > 0) + return + + const audioCtxTimestampPrev = this.audioCtxTimestamp + this.audioCtxTimestamp = this.audioCtx?.currentTime ?? 0 + const deltaTimeMs = (this.audioCtxTimestamp - audioCtxTimestampPrev) * 1000 + + if (deltaTimeMs > 100) + return + + this.preloadNextBlock(false) + + const audioCtxOffsetMs = 15 + this.audioCtxTimestamp * 1000 + + const measuresPerSecond = (this.playingProject.baseBpm / 4 / 60) + + const playTimeFloatNext = this.playTimeFloat + deltaTimeMs / 1000 * measuresPerSecond + const playTimeNext = Rational.fromFloat(playTimeFloatNext, Project.MAX_RATIONAL_DENOMINATOR) + + this.process(audioCtxOffsetMs, deltaTimeMs) + + const range = new Range( + this.playTime, + playTimeNext, + true, + false) + + const noteEvents = Playback.queryNoteEvents( + this.playingProject, + range, + this.firstPlayingFrame) + + this.firstPlayingFrame = false + + for (const noteEvent of noteEvents) + { + noteEvent.startMs = Math.max(0, noteEvent.startMs - this.startTimeMs) + noteEvent.endMs = Math.max(0, noteEvent.endMs - this.startTimeMs) + this.playNote(noteEvent, audioCtxOffsetMs) + } + + //if (noteEvents.length > 0) + // console.log(noteEvents) + + this.playTimeFloat = playTimeFloatNext + this.playTime = playTimeNext + this.startTimeMs += deltaTimeMs + + this.refreshTimeMs += deltaTimeMs + if (canRedrawScreen) + { + this.refreshTimeMs = 0 + window.dispatchEvent(new CustomEvent(eventPlaybackRefresh)) + } + + if (this.playTime.compare(this.playingProject.range.end) > 0 && + this.isFinished()) + { + this.setPlaying(false, this.playingProject) + window.dispatchEvent(new CustomEvent(eventPlaybackRefresh)) + } + } + + + processAnimationFrame(timestamp: number) + { + const prevTimestamp = this.requestAnimationFrameTimestamp + this.requestAnimationFrameTimestamp = timestamp + + this.requestAnimationFrameDate = new Date() + + //const deltaTimeMs = (prevTimestamp < 0 ? 0 : timestamp - prevTimestamp) + + this.processFrame(true) + + if (this.playing) + { + this.requestAnimationFrameId = + requestAnimationFrame(timestamp => this.processAnimationFrame(timestamp)) + } + } + + + processInterval(deltaTimeMs: number) + { + // Take over from requestAnimationFrame and + // process playback on the setInterval callback only if + // requestAnimationFrame was blocked (by e.g. being in the background) + + this.processFrame(false) + + /*const msSinceLastRequestAnimationFrame = + (new Date().getTime()) - + this.requestAnimationFrameDate.getTime() + + if (msSinceLastRequestAnimationFrame > 250 && + deltaTimeMs > 0 && deltaTimeMs < 250) + { + this.processFrame(false) + }*/ + } + + + setPlaying( + playing: boolean, + playingProject: Project.ImmutableRoot) + { + if (this.requestAnimationFrameId !== 0) + { + this.stopAll() + + cancelAnimationFrame(this.requestAnimationFrameId) + this.requestAnimationFrameId = 0 + + clearInterval(this.setIntervalId) + this.setIntervalId = 0 + } + + this.playing = playing + this.playingProject = playingProject + this.firstPlayingFrame = true + this.startTime = this.nextStartTime + this.startTimeMs = Project.getMillisecondsAt(playingProject, this.startTime) + this.playTime = this.nextStartTime + this.playTimeFloat = this.nextStartTime.asFloat() + this.preloadTime = this.nextStartTime + this.refreshTimeMs = 0 + this.audioCtxTimestamp = this.audioCtx?.currentTime ?? 0 + + if (playing) + { + this.start() + this.preloadNextBlock(true) + + this.requestAnimationFrameId = + requestAnimationFrame(timestamp => this.processAnimationFrame(timestamp)) + + this.requestAnimationFrameTimestamp = 0 + this.requestAnimationFrameDate = new Date() + + this.setIntervalId = + +setInterval(() => this.processInterval(1000 / 60), 1000 / 60) + } + } + + + setStartTime(startTime: Rational) + { + this.nextStartTime = startTime + } + + + togglePlaying( + playingProject: Project.ImmutableRoot) + { + this.setPlaying( + !this.playing, + playingProject) + } +} \ No newline at end of file diff --git a/src/prefs.ts b/src/prefs.ts index b4c556d..8da1c6f 100644 --- a/src/prefs.ts +++ b/src/prefs.ts @@ -74,7 +74,7 @@ export function makeNew(): Prefs selectionCursorColor: "#0af", selectionBkgColor: "#8cf4", - playbackCursorColor: "#f00", + playbackCursorColor: "#0c4", trackSeparatorColor: "#aaa", measureColor: "#040404", diff --git a/src/shortcuts.ts b/src/shortcuts.ts new file mode 100644 index 0000000..2bff880 --- /dev/null +++ b/src/shortcuts.ts @@ -0,0 +1,62 @@ +import * as Solid from "solid-js" +import * as Global from "./state.ts" +import * as Timeline from "./timeline" +import * as Inspector from "./inspector" +import * as Playback from "./playback" + + +export function setupKeyboardShortcuts() +{ + window.addEventListener("keydown", handleKeyDown) + + Solid.onCleanup(() => window.removeEventListener("keydown", handleKeyDown)) +} + + +function handleKeyDown(ev: KeyboardEvent) +{ + if (document.activeElement && + document.activeElement.tagName === "INPUT") + return + + const key = ev.key.toLowerCase() + + if (key === " ") + { + const project = Global.get().project + const timeline = Global.get().timeline + const playback = Global.get().playback + playback.setStartTime(timeline.playbackStartTime) + playback.togglePlaying(project.root) + } + + /*for (const command of Command.allCommands) + { + if (!command.shortcut) + continue + + if (command.isShortcutAvailable && !command.isShortcutAvailable()) + continue + + if (command.isAvailable && !command.isAvailable({})) + continue + + for (const shortcut of command.shortcut) + { + if (!!shortcut.ctrl !== ev.ctrlKey) + continue + + if (!!shortcut.shift !== ev.shiftKey) + continue + + if (key !== shortcut.key) + continue + + //console.log("handled keyboard command: ", command.name) + command.func({}) + ev.preventDefault() + ev.stopPropagation() + return + } + }*/ +} \ No newline at end of file diff --git a/src/state.ts b/src/state.ts index 47583fe..69c6a7b 100644 --- a/src/state.ts +++ b/src/state.ts @@ -1,6 +1,7 @@ import * as Solid from "solid-js" import * as Project from "./project" import * as Timeline from "./timeline" +import * as Playback from "./playback" import * as Prefs from "./prefs" @@ -13,6 +14,7 @@ export interface State prefs: Prefs.Prefs project: Project.Mutable timeline: Timeline.State + playback: Playback.Manager } @@ -22,6 +24,7 @@ export function makeNew(): State prefs: Prefs.makeNew(), project: { root: Project.makeTest() }, timeline: Timeline.makeNew(), + playback: new Playback.Manager(), } } diff --git a/src/timeline/Element.tsx b/src/timeline/Element.tsx index 5bf98d1..34cf981 100644 --- a/src/timeline/Element.tsx +++ b/src/timeline/Element.tsx @@ -1,6 +1,7 @@ import * as Solid from "solid-js" import * as Global from "../state.ts" import * as Timeline from "./index.ts" +import * as Playback from "../playback" import Rect from "../utils/rect.ts" @@ -95,6 +96,14 @@ function registerHandlers( "inherit" } + const draw = () => { + const timeline = Global.get().timeline + const project = Global.get().project + const prefs = Global.get().prefs + const playback = Global.get().playback + Timeline.draw(timeline, playback, prefs, ctx) + } + const onResize = () => { const timeline = Global.get().timeline const project = Global.get().project @@ -102,7 +111,7 @@ function registerHandlers( canvasResize(div, canvas, timeline) Timeline.layout(timeline, project.root, prefs) - Timeline.draw(timeline, prefs, ctx) + draw() } const onMouseMove = (ev: MouseEvent) => { @@ -121,7 +130,7 @@ function registerHandlers( Global.refresh() } - Timeline.draw(timeline, prefs, ctx) + draw() setCursor() } @@ -135,7 +144,7 @@ function registerHandlers( Timeline.mouseMove(timeline, project.root, mouse.x, mouse.y) Timeline.mouseDown(timeline, project, prefs, ev.button !== 0) - Timeline.draw(timeline, prefs, ctx) + draw() Global.refresh() setCursor() } @@ -153,7 +162,7 @@ function registerHandlers( if (Timeline.mouseUp(timeline, project, ev.button !== 0)) Timeline.layout(timeline, project.root, prefs) - Timeline.draw(timeline, prefs, ctx) + draw() Global.refresh() setCursor() } @@ -167,7 +176,7 @@ function registerHandlers( Timeline.mouseWheel(timeline, ev.deltaX, ev.deltaY) Timeline.layout(timeline, project.root, prefs) - Timeline.draw(timeline, prefs, ctx) + draw() Global.refresh() } @@ -178,7 +187,7 @@ function registerHandlers( Timeline.keyDown(timeline, project, prefs, ev.key.toLowerCase()) Timeline.layout(timeline, project.root, prefs) - Timeline.draw(timeline, prefs, ctx) + draw() Global.refresh() } @@ -195,6 +204,7 @@ function registerHandlers( onResize() + window.addEventListener(Playback.eventPlaybackRefresh, draw) window.addEventListener("resize", onResize) window.addEventListener("mousemove", onMouseMove) canvas.addEventListener("mousedown", onMouseDown) @@ -205,6 +215,7 @@ function registerHandlers( window.addEventListener("keyup", onKeyUp) return () => { + window.removeEventListener(Playback.eventPlaybackRefresh, draw) window.removeEventListener("resize", onResize) window.removeEventListener("mousemove", onMouseMove) canvas.removeEventListener("mousedown", onMouseDown) diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index 0a6c64f..72bab34 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -1,5 +1,5 @@ -import * as State from "../state.ts" import * as Timeline from "./index.ts" +import * as Playback from "../playback" import * as Prefs from "../prefs.ts" import * as Theory from "../theory" import Rational from "../utils/rational.ts" @@ -9,6 +9,7 @@ import Rect from "../utils/rect.ts" export function draw( timeline: Timeline.State, + playback: Playback.Manager, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D) { @@ -19,7 +20,7 @@ export function draw( ctx.clearRect(0, 0, timeline.renderRect.w, timeline.renderRect.h) for (const lane of timeline.layout.lanes) - drawLane(ctx, timeline, prefs, lane) + drawLane(ctx, timeline, playback, prefs, lane) if (timeline.cursor.visible) { @@ -29,6 +30,11 @@ export function draw( drawCursorBeam(timeline, prefs, ctx, timeMax, true) } + if (playback.playing) + { + drawPlaybackBeam(timeline, prefs, ctx, playback.playTime) + } + ctx.restore() } @@ -36,6 +42,7 @@ export function draw( function drawLane( ctx: CanvasRenderingContext2D, timeline: Timeline.State, + playback: Playback.Manager, prefs: Prefs.Prefs, lane: Timeline.Lane) { @@ -57,7 +64,7 @@ function drawLane( drawLaneBkgMeasures(timeline, prefs, ctx, lane, false) drawLaneBkgMeasures(timeline, prefs, ctx, lane, true) drawCursorBkg(timeline, prefs, ctx, lane) - drawElements(timeline, prefs, ctx, lane.elements) + drawElements(timeline, playback, prefs, ctx, lane.elements) ctx.save() ctx.globalAlpha = 0.05 @@ -91,7 +98,7 @@ function drawLane( drawLaneBkgOctaves(timeline, prefs, ctx, lane, true) drawLaneBkgMeasures(timeline, prefs, ctx, lane, true) drawCursorBkg(timeline, prefs, ctx, lane) - drawElements(timeline, prefs, ctx, lane.elements) + drawElements(timeline, playback, prefs, ctx, lane.elements) for (const tuple of lane.tupleIndicators) { @@ -123,6 +130,7 @@ function drawLane( function drawElements( timeline: Timeline.State, + playback: Playback.Manager, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, elements: Timeline.LayoutElement[]) @@ -183,6 +191,13 @@ function drawElements( ctx.fillStyle = "#fff8" ctx.fill() } + + if (playback.playing && + element.note.range.overlapsPoint(playback.playTime)) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } if (element.id !== undefined && timeline.selection.has(element.id)) @@ -196,7 +211,7 @@ function drawElements( } else if (element.kind === "chord") - drawChord(timeline, prefs, ctx, element) + drawChord(timeline, playback, prefs, ctx, element) else if (element.kind === "marker") drawMarker(timeline, prefs, ctx, element) @@ -206,6 +221,7 @@ function drawElements( function drawChord( timeline: Timeline.State, + playback: Playback.Manager, prefs: Prefs.Prefs, ctx: CanvasRenderingContext2D, element: Timeline.LayoutElementChord) @@ -243,6 +259,13 @@ function drawChord( ctx.fillStyle = "#fff8" ctx.fill() } + + if (playback.playing && + element.chord.range.overlapsPoint(playback.playTime)) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } if (element.id !== undefined && timeline.selection.has(element.id)) @@ -733,4 +756,36 @@ function drawCursorBkg( ctx.fillStyle = prefs.timeline.selectionBkgColor ctx.fillRect(x1, y1, x2 - x1, y2 - y1) +} + + +function drawPlaybackBeam( + timeline: Timeline.State, + prefs: Prefs.Prefs, + ctx: CanvasRenderingContext2D, + time: Rational) +{ + const laneMin = timeline.layout.lanes[0] + const laneMax = timeline.layout.lanes[timeline.layout.lanes.length - 1] + + if (!laneMin || !laneMax) + return + + const x = 0.5 + Math.floor(Timeline.xAtTime(timeline, time)) + + ctx.strokeStyle = prefs.timeline.playbackCursorColor + ctx.fillStyle = prefs.timeline.playbackCursorColor + ctx.lineCap = "square" + ctx.lineWidth = 2 + + //const headYSize = 10 + //const headXSize = headYSize * (tipOffsetSide ? -1 : 1) + + const y1 = Math.floor(laneMin.rect.y) + const y2 = Math.floor(laneMax.rect.y2) + + ctx.beginPath() + ctx.moveTo(x, y1 + 1) + ctx.lineTo(x, y2 - 1) + ctx.stroke() } \ No newline at end of file diff --git a/src/timeline/mouse_down.ts b/src/timeline/mouse_down.ts index 523c078..de4d3a3 100644 --- a/src/timeline/mouse_down.ts +++ b/src/timeline/mouse_down.ts @@ -102,6 +102,8 @@ export function mouseDown( Timeline.scrollTimeIntoView(timeline, anchor) } + timeline.playbackStartTime = timeline.cursor.time1 + return } diff --git a/src/timeline/timeline.ts b/src/timeline/timeline.ts index dcbface..ef4d3c6 100644 --- a/src/timeline/timeline.ts +++ b/src/timeline/timeline.ts @@ -89,6 +89,8 @@ export interface State needsKeyFinish: boolean rangeSelectOriginTrackIndex: number + + playbackStartTime: Rational } @@ -215,6 +217,8 @@ export function makeNew(): State needsKeyFinish: false, rangeSelectOriginTrackIndex: -1, + + playbackStartTime: new Rational(0), } } From b13e58604c448f05225f9c9b91982ee8cc620538 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Sat, 27 Dec 2025 00:14:14 -0300 Subject: [PATCH 13/20] add chord borrowing --- src/components/Checkbox.tsx | 1 + src/components/Select.tsx | 59 ++++++++++++++++++ src/components/index.ts | 3 +- src/inspector/InspectorChord.tsx | 101 ++++++++++++++++++------------- src/theory/chord.ts | 2 +- src/theory/chordOptions.ts | 2 + 6 files changed, 123 insertions(+), 45 deletions(-) create mode 100644 src/components/Select.tsx diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 0e9169b..253e1e9 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -43,6 +43,7 @@ const StyledButton = styled.button<{ background-color: var(--theme-buttonBkg); color: inherit; font-family: inherit; + font-size: inherit; &:hover { background-color: var(--theme-buttonBkgHover); diff --git a/src/components/Select.tsx b/src/components/Select.tsx new file mode 100644 index 0000000..8eaeded --- /dev/null +++ b/src/components/Select.tsx @@ -0,0 +1,59 @@ +import * as Solid from "solid-js" +import { styled } from "solid-styled-components" + + +export function Select(props: { + children?: Solid.JSXElement, + label?: Solid.JSXElement, + value?: string, + onChange?: (newValue: string) => void, +}) +{ + return props.onChange?.(ev.target.value) } + > + + { props.children } + +} + + +const StyledSelect = styled.select<{ +}>` + appearance: base-select; + + &::picker(select) { + /*appearance: base-select;*/ + border: 0; + border-radius: var(--theme-buttonBorderRadius); + background-color: var(--theme-buttonBkg); + color: inherit; + font-family: inherit; + font-size: inherit; + } + + display: inline-block; + justify-self: stretch; + align-self: center; + user-select: none; + cursor: pointer; + + margin: 0.25em; + padding: 0.25em 0.5em; + border: 0; + border-radius: var(--theme-buttonBorderRadius); + background-color: var(--theme-buttonBkg); + color: inherit; + font-family: inherit; + font-size: inherit; + + &:hover { + background-color: var(--theme-buttonBkgHover); + } + + &:active { + background-color: var(--theme-buttonBkgPress); + } +` +//${ props => props.$checked ? "background-color: var(--theme-buttonBkgSelected);" : "" } \ No newline at end of file diff --git a/src/components/index.ts b/src/components/index.ts index 7687ffc..204ee33 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1 +1,2 @@ -export * from "./Checkbox.tsx" \ No newline at end of file +export * from "./Checkbox.tsx" +export * from "./Select.tsx" \ No newline at end of file diff --git a/src/inspector/InspectorChord.tsx b/src/inspector/InspectorChord.tsx index bbbb158..ee21785 100644 --- a/src/inspector/InspectorChord.tsx +++ b/src/inspector/InspectorChord.tsx @@ -7,7 +7,7 @@ import * as Theory from "../theory" import Rect from "../utils/rect.ts" import * as CanvasUtils from "../utils/canvasUtils.ts" import { styled } from "solid-styled-components" -import { Checkbox } from "../components" +import { Checkbox, Select } from "../components" export function InspectorChord(props: { @@ -58,8 +58,8 @@ export function InspectorChord(props: { const makeChordButton = Solid.createMemo(() => { const chOpts = chordOptions() - return (degree: number) => { - const chord = Theory.ChordOptions.buildChord(props.key, degree, chOpts) + return (key: Theory.Key, degree: number) => { + const chord = Theory.ChordOptions.buildChord(key, degree, chOpts) const isSelected = props.value && currChord()?.isEqual(chord) console.log(degree, chord) @@ -107,12 +107,51 @@ export function InspectorChord(props: { } }) + const makeChordButtons = Solid.createMemo(() => { + const chOpts = chordOptions() + const scaleId = chOpts.borrowFromScaleId ?? props.key.scale.id! + const borrowedKey = new Theory.Key(props.key.tonic, Theory.Scale.fromId(scaleId)) + + return borrowedKey.chroma.map((chroma, degree) => + makeChordButton()(borrowedKey, degree) + ) + }) + + const makeScaleOption = (scaleMeta: Theory.ScaleMetadata) => { + return +
+ { scaleMeta.names[0] } + | +
+ + { (chroma, i) => { + const degree = i() + const borrowedKey = new Theory.Key(props.key.tonic, Theory.Scale.fromId(scaleMeta.id)) + const chord = Theory.Chord.fromDiatonicTriad(borrowedKey, degree) + const chordStr = chord.str(props.key) + + return
+ { chordStr.romanBase } + {chordStr.romanSup } + {chordStr.romanSub } + { " " } +
+ }} +
+
+
+ } + return <> - { props.key.chroma.map((chroma, degree) => - makeChordButton()(degree) - )} + { makeChordButtons() } @@ -233,6 +272,19 @@ export function InspectorChord(props: { onChange={ ev => setChordOptions(opts => ({ ...opts, withFlat13: ev })) } />
+
+ +
@@ -303,43 +355,6 @@ const ChordCanvas = styled.canvas<{ ` -const ScaleButton = styled.div<{ - $selected: boolean, -}>` - display: grid; - grid-template: auto auto / auto; - justify-items: start; - justify-content: start; - user-select: none; - cursor: pointer; - - width: 90%; - margin: 0.25em; - padding: 0.25em 0.5em; - border-radius: 0.25em; - background-color: var(--theme-buttonBkg); - - &:hover { - background-color: var(--theme-buttonBkgHover); - } - - &:active { - background-color: var(--theme-buttonBkgPress); - } - - ${ props => props.$selected ? "background-color: var(--theme-buttonBkgSelected);" : "" } -` - - -const StyledSelect = styled.select` - /*appearance: base-select; - - &::picker(select) { - appearance: base-select; - }*/ -` - - const OptionScale = styled.option` margin-top: 0.5em; margin-bottom: 0.5em; diff --git a/src/theory/chord.ts b/src/theory/chord.ts index bc62676..1ac6678 100644 --- a/src/theory/chord.ts +++ b/src/theory/chord.ts @@ -605,7 +605,7 @@ export default class Chord { const chroma = key.chromaForDegree(this.baseDegree + degree) const chromaInCMajor = this.rootChroma + Theory.Scale.majorScale.chromas[degree % 7] + accidental - const finalAccidental = Theory.Utils.modRomanAccidental(chromaInCMajor - chroma) + const finalAccidental = Theory.Utils.modAccidental(chromaInCMajor - chroma) return Theory.Utils.accidentalToStr(finalAccidental) } diff --git a/src/theory/chordOptions.ts b/src/theory/chordOptions.ts index de9e13f..7d2441b 100644 --- a/src/theory/chordOptions.ts +++ b/src/theory/chordOptions.ts @@ -20,6 +20,7 @@ export interface ChordOptions withSharp9: boolean withSharp11: boolean withFlat13: boolean + borrowFromScaleId?: string } @@ -42,6 +43,7 @@ export namespace ChordOptions withSharp9: false, withSharp11: false, withFlat13: false, + borrowFromScaleId: undefined, } } From a5a336c51edf3924df219e6cfa57dc2f0d50815b Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Sat, 27 Dec 2025 15:10:07 -0300 Subject: [PATCH 14/20] add tempo changes --- src/components/Button.tsx | 79 ++++++++++++++ src/components/Checkbox.tsx | 3 +- src/components/index.ts | 1 + src/inspector/Inspector.tsx | 6 ++ src/inspector/InspectorInsert.tsx | 26 ++++- src/inspector/InspectorTempoChange.tsx | 136 +++++++++++++++++++++++++ src/inspector/index.ts | 1 + src/playback/manager.ts | 14 +-- src/prefs.ts | 6 +- src/project/elem.ts | 46 ++++++++- src/project/index.ts | 3 +- src/project/measures.ts | 7 +- src/project/root.ts | 81 ++++++--------- src/project/tempo.ts | 129 +++++++++++++++++++++++ src/timeline/Element.tsx | 4 + src/timeline/draw.ts | 123 ++++++++++++---------- src/timeline/lane_notes.ts | 56 +++++----- src/timeline/layout.ts | 5 +- 18 files changed, 571 insertions(+), 155 deletions(-) create mode 100644 src/components/Button.tsx create mode 100644 src/inspector/InspectorTempoChange.tsx create mode 100644 src/project/tempo.ts diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 0000000..5f2c859 --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,79 @@ +import * as Solid from "solid-js" +import { styled } from "solid-styled-components" + + +export function Button(props: { + children?: Solid.JSXElement, + label?: Solid.JSXElement, + checked?: boolean, + onClick?: () => void, + groupStart?: boolean, + groupMiddle?: boolean, + groupEnd?: boolean, +}) +{ + return + { props.label ?? props.children } + +} + + +const StyledButton = styled.button<{ + "data-checked": boolean, + "data-group-start": boolean, + "data-group-middle": boolean, + "data-group-end": boolean, +}>` + display: inline-block; + justify-self: stretch; + align-self: center; + user-select: none; + cursor: pointer; + + margin: 0.25em; + padding: 0.25em 0.5em; + border: 0; + border-radius: var(--theme-buttonBorderRadius); + background-color: var(--theme-buttonBkg); + color: inherit; + font-family: inherit; + font-size: inherit; + + &:hover { + background-color: var(--theme-buttonBkgHover); + } + + &:active { + background-color: var(--theme-buttonBkgPress); + } + + &[data-checked=true] { + background-color: var(--theme-buttonBkgSelected); + } + + &[data-group-start=true] { + margin-left: 0.25em; + margin-right: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + &[data-group-middle=true] { + margin-left: 0; + margin-right: 0; + border-radius: 0; + } + + &[data-group-end=true] { + margin-left: 0; + margin-right: 0.25em; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +` \ No newline at end of file diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 253e1e9..f535cc1 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -76,5 +76,4 @@ const StyledButton = styled.button<{ border-top-left-radius: 0; border-bottom-left-radius: 0; } -` -//${ props => props.$checked ? "background-color: var(--theme-buttonBkgSelected);" : "" } \ No newline at end of file +` \ No newline at end of file diff --git a/src/components/index.ts b/src/components/index.ts index 204ee33..9f677a0 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,2 +1,3 @@ +export * from "./Button.tsx" export * from "./Checkbox.tsx" export * from "./Select.tsx" \ No newline at end of file diff --git a/src/inspector/Inspector.tsx b/src/inspector/Inspector.tsx index b066201..1832914 100644 --- a/src/inspector/Inspector.tsx +++ b/src/inspector/Inspector.tsx @@ -51,6 +51,12 @@ export function InspectorRoot(props: {}) const elem = Project.getElem(project.root, elemId) const key = Project.keyAt(project.root, project.root.keyChangeTrackId, elem?.range.start ?? new Rational(0)) + if (elem?.type === "tempoChange") + return + if (elem?.type === "keyChange") return { + const project = Global.get().project + const timeline = Global.get().timeline + const time = timeline.cursor.time1 + const id = project.root.nextId + const tempoCh = Project.makeTempoChange(project.root.tempoChangeTrackId, time, 120) + project.root = Project.upsertElement(project.root, tempoCh) + Timeline.selectionClear(timeline) + Timeline.selectionAdd(timeline, id) + Timeline.selectionResolveOverlappingAndDegenerate(timeline, project) + timeline.cursor.visible = false + Global.refresh() + } + const insertKeyChange = () => { const project = Global.get().project const timeline = Global.get().timeline @@ -88,12 +103,15 @@ export function InspectorInsert(props: { return
- + - + +
diff --git a/src/inspector/InspectorTempoChange.tsx b/src/inspector/InspectorTempoChange.tsx new file mode 100644 index 0000000..bb98863 --- /dev/null +++ b/src/inspector/InspectorTempoChange.tsx @@ -0,0 +1,136 @@ +import * as Solid from "solid-js" +import * as Global from "../state.ts" +import * as Inspector from "./index.ts" +import * as Project from "../project" +import * as Timeline from "../timeline" +import * as Theory from "../theory" +import Rect from "../utils/rect.ts" +import { styled } from "solid-styled-components" + + +export function InspectorTempoChange(props: { + value: Project.TempoChange, + upsertElem: (newValue: Project.TempoChange) => void, +}) +{ + const [currTempo, setCurrTempo] = Solid.createSignal(props.value.bpm) + + + const applyTempo = (bpm: number) => { + setCurrTempo(bpm) + const project = Global.get().project + const tempoCh = Project.getTypedElem(project.root, props.value.id, "tempoChange") + if (tempoCh) + props.upsertElem({...tempoCh, bpm }) + } + + + const parseTempo = (bpmStr: string) => { + let bpm = parseInt(bpmStr) + if (!isFinite(bpm)) + return + + bpm = Math.max(1, Math.min(999, bpm)) + applyTempo(bpm) + } + + + return <> + +

Tempo Change

+ + parseTempo(ev.target.value) } + onBlur={ ev => parseTempo(ev.target.value) } + /> bpm + +
+ +} + + +const Layout = styled.div` + display: grid; + grid-template: auto auto / auto; + width: 100%; + height: 100%; + min-height: 0; + justify-content: center; + justify-items: center; + align-content: start; + align-items: start; + column-gap: 1em; +` + + +const CircleOfFifthsPath = styled.path<{ + $selected: boolean, +}>` + cursor: pointer; + fill: var(--theme-buttonBkg); + + &:hover { + fill: var(--theme-buttonBkgHover); + } + + &:active { + fill: var(--theme-buttonBkgPress); + } + + ${ props => props.$selected ? "fill: var(--theme-buttonBkgSelected);" : "" } +` + + +const ScaleList = styled.div` + width: 20em; + height: 100%; + min-height: 0; + overflow-x: hidden; + overflow-y: scroll; + scrollbar-gutter: stable; + border-radius: 0.25em; +` + + +const ScaleButton = styled.div<{ + $selected: boolean, +}>` + display: grid; + grid-template: auto auto / auto; + justify-items: start; + justify-content: start; + user-select: none; + cursor: pointer; + + width: 90%; + margin: 0.25em; + padding: 0.25em 0.5em; + border-radius: var(--theme-buttonBorderRadius); + background-color: var(--theme-buttonBkg); + + &:hover { + background-color: var(--theme-buttonBkgHover); + } + + &:active { + background-color: var(--theme-buttonBkgPress); + } + + ${ props => props.$selected ? "background-color: var(--theme-buttonBkgSelected);" : "" } +` + + +const StyledSelect = styled.select` + /*appearance: base-select; + + &::picker(select) { + appearance: base-select; + }*/ +` + + +const OptionScale = styled.option` + margin-top: 0.5em; + margin-bottom: 0.5em; +` \ No newline at end of file diff --git a/src/inspector/index.ts b/src/inspector/index.ts index 752dd6b..e014d32 100644 --- a/src/inspector/index.ts +++ b/src/inspector/index.ts @@ -1,4 +1,5 @@ export { InspectorRoot } from "./Inspector.tsx" export { InspectorInsert } from "./InspectorInsert.tsx" +export { InspectorTempoChange } from "./InspectorTempoChange.tsx" export { InspectorKeyChange } from "./InspectorKeyChange.tsx" export { InspectorChord } from "./InspectorChord.tsx" \ No newline at end of file diff --git a/src/playback/manager.ts b/src/playback/manager.ts index 6b39056..11812b9 100644 --- a/src/playback/manager.ts +++ b/src/playback/manager.ts @@ -24,7 +24,6 @@ export class Manager startTime: Rational startTimeMs: number nextStartTime: Rational - playTimeFloat: number playTime: Rational preloadTime: Rational refreshTimeMs: number @@ -47,7 +46,6 @@ export class Manager this.startTime = new Rational(0) this.startTimeMs = 0 this.nextStartTime = new Rational(0) - this.playTimeFloat = 0 this.playTime = new Rational(0) this.preloadTime = new Rational(0) this.refreshTimeMs = 0 @@ -239,11 +237,11 @@ export class Manager const audioCtxOffsetMs = 15 + this.audioCtxTimestamp * 1000 - const measuresPerSecond = (this.playingProject.baseBpm / 4 / 60) - - const playTimeFloatNext = this.playTimeFloat + deltaTimeMs / 1000 * measuresPerSecond - const playTimeNext = Rational.fromFloat(playTimeFloatNext, Project.MAX_RATIONAL_DENOMINATOR) + const startTimeNext = this.startTimeMs + deltaTimeMs + const playTimeNext = + Project.getTimeAtMilliseconds(this.playingProject, startTimeNext) + this.process(audioCtxOffsetMs, deltaTimeMs) const range = new Range( @@ -269,9 +267,8 @@ export class Manager //if (noteEvents.length > 0) // console.log(noteEvents) - this.playTimeFloat = playTimeFloatNext this.playTime = playTimeNext - this.startTimeMs += deltaTimeMs + this.startTimeMs = startTimeNext this.refreshTimeMs += deltaTimeMs if (canRedrawScreen) @@ -349,7 +346,6 @@ export class Manager this.startTime = this.nextStartTime this.startTimeMs = Project.getMillisecondsAt(playingProject, this.startTime) this.playTime = this.nextStartTime - this.playTimeFloat = this.nextStartTime.asFloat() this.preloadTime = this.nextStartTime this.refreshTimeMs = 0 this.audioCtxTimestamp = this.audioCtx?.currentTime ?? 0 diff --git a/src/prefs.ts b/src/prefs.ts index 8da1c6f..d40da45 100644 --- a/src/prefs.ts +++ b/src/prefs.ts @@ -23,8 +23,9 @@ export interface Prefs measureLabelColor: string octaveLabelColor: string - meterChangeColor: string + tempoChangeColor: string keyChangeColor: string + meterChangeColor: string noteVelocityMarkerColor: string noteVelocityMarkerInactiveColor: string @@ -84,8 +85,9 @@ export function makeNew(): Prefs measureLabelColor: "#aaa", octaveLabelColor: "#aaa", - meterChangeColor: "#0cf", + tempoChangeColor: "#d98", keyChangeColor: "#f0c", + meterChangeColor: "#0cf", noteVelocityMarkerColor: "#0c4", noteVelocityMarkerInactiveColor: "#063", diff --git a/src/project/elem.ts b/src/project/elem.ts index 273a544..ceabe03 100644 --- a/src/project/elem.ts +++ b/src/project/elem.ts @@ -27,6 +27,12 @@ export interface TrackBase extends ElementBase } +export interface TrackTempoChanges extends TrackBase +{ + trackType: "tempoChanges" +} + + export interface TrackKeyChanges extends TrackBase { trackType: "keyChanges" @@ -56,12 +62,20 @@ export interface TrackNotes extends TrackBase export type Track = + TrackTempoChanges | TrackKeyChanges | TrackMeterChanges | TrackChords | TrackNotes +export interface TempoChange extends ElementBase +{ + type: "tempoChange" + bpm: number +} + + export interface KeyChange extends ElementBase { type: "keyChange" @@ -92,6 +106,7 @@ export interface Chord extends ElementBase export type Element = Track | + TempoChange | KeyChange | MeterChange | Note | @@ -144,6 +159,19 @@ export function trackDisplayName(track: Track): string } +export function makeTrackTempoChanges(): TrackTempoChanges +{ + return { + type: "track", + trackType: "tempoChanges", + id: -1, + parentId: 0, + range: Range.dummy(), + name: "Tempo Changes", + } +} + + export function makeTrackKeyChanges(): TrackKeyChanges { return { @@ -170,14 +198,14 @@ export function makeTrackMeterChanges(): TrackMeterChanges } -export function makeMeterChange(parentId: ID, time: Rational, meter: Theory.Meter): MeterChange +export function makeTempoChange(parentId: ID, time: Rational, bpm: number): TempoChange { return { - type: "meterChange", + type: "tempoChange", id: -1, parentId, range: Range.fromPoint(time), - meter, + bpm, } } @@ -194,6 +222,18 @@ export function makeKeyChange(parentId: ID, time: Rational, key: Theory.Key): Ke } +export function makeMeterChange(parentId: ID, time: Rational, meter: Theory.Meter): MeterChange +{ + return { + type: "meterChange", + id: -1, + parentId, + range: Range.fromPoint(time), + meter, + } +} + + export function makeNote( parentId: ID, range: Range, diff --git a/src/project/index.ts b/src/project/index.ts index 04c1d40..17d40fc 100644 --- a/src/project/index.ts +++ b/src/project/index.ts @@ -1,7 +1,8 @@ //export * from "./_global" export * from "./root" -export * from "./measures" export * from "./elem" +export * from "./measures" +export * from "./tempo" //export * from "./midiImport" //export * from "./midiExport" //export * from "./jsonExport" diff --git a/src/project/measures.ts b/src/project/measures.ts index 6ea7ff8..b18966b 100644 --- a/src/project/measures.ts +++ b/src/project/measures.ts @@ -25,8 +25,9 @@ let lastMeterCh: Project.MeterChange | null = null export function ensureMeasureCacheRefreshed(project: Project.ImmutableRoot) { - const meterChangeTrackId = Project.meterChangeTrackId(project) - const meterChangeList = project.lists.get(meterChangeTrackId)! + const meterChangeList = project.lists.get(project.meterChangeTrackId) + if (!meterChangeList) + return if (meterChangeList === measureCacheKey) return @@ -51,7 +52,7 @@ export function ensureMeasureCacheRefreshed(project: Project.ImmutableRoot) continue const meterCh1 = elem1 as Project.MeterChange - const meterCh2 = elem2 as (Project.MeterChange | null) + const meterCh2 = elem2 as Project.MeterChange let numLocal = 0 diff --git a/src/project/root.ts b/src/project/root.ts index e84cf1a..a2dfa48 100644 --- a/src/project/root.ts +++ b/src/project/root.ts @@ -20,11 +20,11 @@ export interface ImmutableRoot { nextId: Project.ID range: Range - baseBpm: number tracks: Project.Track[] lists: Immutable.Map> elems: Immutable.Map + tempoChangeTrackId: number keyChangeTrackId: number meterChangeTrackId: number chordTrackId: number @@ -37,10 +37,10 @@ export function makeEmpty(): ImmutableRoot return { nextId: 1, range: new Range(new Rational(0), new Rational(4)), - baseBpm: 120, tracks: [], lists: Immutable.Map>(), elems: Immutable.Map(), + tempoChangeTrackId: -1, keyChangeTrackId: -1, meterChangeTrackId: -1, chordTrackId: -1, @@ -53,26 +53,28 @@ export function makeNew(): ImmutableRoot { let project = makeEmpty() - const track1Id = project.nextId - project.keyChangeTrackId = track1Id + project.tempoChangeTrackId = project.nextId + project = upsertTrack(project, Project.makeTrackTempoChanges()) + + project.keyChangeTrackId = project.nextId project = upsertTrack(project, Project.makeTrackKeyChanges()) - const track2Id = project.nextId - project.meterChangeTrackId = track2Id + project.meterChangeTrackId = project.nextId project = upsertTrack(project, Project.makeTrackMeterChanges()) + project = upsertElement(project, Project.makeTempoChange( + project.tempoChangeTrackId, new Rational(0), 120)) + project = upsertElement(project, Project.makeKeyChange( - track1Id, new Rational(0), Theory.Key.parse("C Major"))) + project.keyChangeTrackId, new Rational(0), Theory.Key.parse("C Major"))) project = upsertElement(project, Project.makeMeterChange( - track2Id, new Rational(0), new Theory.Meter(4, 4))) + project.meterChangeTrackId, new Rational(0), new Theory.Meter(4, 4))) - const track3Id = project.nextId - project.chordTrackId = track3Id + project.chordTrackId = project.nextId project = upsertTrack(project, Project.makeTrackChords()) - const track4Id = project.nextId - project.noteTrackId = track4Id + project.noteTrackId = project.nextId project = upsertTrack(project, Project.makeTrackNotes()) return project @@ -168,7 +170,7 @@ export function upsertElement(project: ImmutableRoot, elem: Project.Element): Im } const prevElem = project.elems.get(elem.id) - const changeParent = !!prevElem && prevElem.parentId != elem.parentId + const changeParent = !!prevElem && prevElem.parentId !== elem.parentId if (!changeParent) { @@ -181,25 +183,25 @@ export function upsertElement(project: ImmutableRoot, elem: Project.Element): Im } else if (elem.parentId < 0) { - let prevList = project.lists.get(prevElem!.parentId) ?? new ListOfRanges() - prevList = prevList.removeById(prevElem!.id) + let prevList = project.lists.get(prevElem.parentId) ?? new ListOfRanges() + prevList = prevList.removeById(prevElem.id) let elems = project.elems.delete(elem.id) - let lists = project.lists.set(prevElem!.parentId, prevList) + let lists = project.lists.set(prevElem.parentId, prevList) return { ...project, nextId, elems, lists } } else { - let prevList = project.lists.get(prevElem!.parentId) ?? new ListOfRanges() - prevList = prevList.removeById(prevElem!.id) + let prevList = project.lists.get(prevElem.parentId) ?? new ListOfRanges() + prevList = prevList.removeById(prevElem.id) let nextList = project.lists.get(elem.parentId) ?? new ListOfRanges() nextList = nextList.upsert(elem) let elems = project.elems.set(elem.id, elem) let lists = project.lists - .set(prevElem!.parentId, prevList) + .set(prevElem.parentId, prevList) .set(elem.parentId, nextList) return { ...project, nextId, elems, lists } @@ -207,22 +209,9 @@ export function upsertElement(project: ImmutableRoot, elem: Project.Element): Im } -export function keyChangeTrackId(project: ImmutableRoot): Project.ID -{ - return project.keyChangeTrackId -} - - -export function meterChangeTrackId(project: ImmutableRoot): Project.ID -{ - return project.meterChangeTrackId -} - - export function keyAt(project: ImmutableRoot, trackId: Project.ID, time: Rational): Theory.Key { - const keyChangeTrackId = Project.keyChangeTrackId(project) - const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId) + const keyChangeTrackTimedElems = project.lists.get(project.keyChangeTrackId) if (!keyChangeTrackTimedElems) return defaultKey() @@ -240,8 +229,7 @@ export function keyAt(project: ImmutableRoot, trackId: Project.ID, time: Rationa export function meterChangeAt(project: ImmutableRoot, trackId: Project.ID, time: Rational): Project.MeterChange | null { - const meterChangeTrackId = Project.meterChangeTrackId(project) - const meterChangeTrackTimedElems = project.lists.get(meterChangeTrackId) + const meterChangeTrackTimedElems = project.lists.get(project.meterChangeTrackId) if (!meterChangeTrackTimedElems) return null @@ -269,7 +257,7 @@ export function meterAt(project: ImmutableRoot, trackId: Project.ID, time: Ratio export function withRefreshedRange(project: ImmutableRoot): ImmutableRoot { - let range = new Range(new Rational(0), new Rational(4)); + let range = new Range(new Rational(0), new Rational(4)) for (const track of project.tracks) { @@ -322,7 +310,7 @@ export function getTrack( : Extract | null { const elem = project.elems.get(id) - if (!elem || elem.type != "track" || elem.trackType != trackType) + if (!elem || elem.type !== "track" || elem.trackType !== trackType) return null return elem as Extract @@ -444,7 +432,7 @@ export function parentTrackFor(project: ImmutableRoot, elemId: Project.ID): Proj if (!elem) return null! - if (elem.type == "track") + if (elem.type === "track") return elem elemId = elem.parentId @@ -460,7 +448,7 @@ export function getAbsoluteTime(project: ImmutableRoot, parentId: Project.ID, ti if (!elem) return time - if (elem.type == "track") + if (elem.type === "track") return time time = time.add(elem.range.start) @@ -477,7 +465,7 @@ export function getRelativeTime(project: ImmutableRoot, parentId: Project.ID, ti if (!elem) return time - if (elem.type == "track") + if (elem.type === "track") return time time = time.subtract(elem.range.start) @@ -494,7 +482,7 @@ export function getAbsoluteRange(project: ImmutableRoot, parentId: Project.ID, r if (!elem) return range - if (elem.type == "track") + if (elem.type === "track") return range range = range.displace(elem.range.start) @@ -511,7 +499,7 @@ export function getRelativeRange(project: ImmutableRoot, parentId: Project.ID, r if (!elem) return range - if (elem.type == "track") + if (elem.type === "track") return range range = range.subtract(elem.range.start) @@ -533,7 +521,7 @@ export function getRangeForElems( if (!elem) continue - if (elem.type == "track") + if (elem.type === "track") continue const absRange = Project.getAbsoluteRange(project, elem.parentId, elem.range) @@ -544,13 +532,6 @@ export function getRangeForElems( } -export function getMillisecondsAt(project: ImmutableRoot, time: Rational): number -{ - const measuresPerSecond = (project.baseBpm / 4 / 60) - return time.subtract(project.range.start).asFloat() / measuresPerSecond * 1000 -} - - export function defaultKey(): Theory.Key { return Theory.Key.parse("C Major") diff --git a/src/project/tempo.ts b/src/project/tempo.ts new file mode 100644 index 0000000..334cba8 --- /dev/null +++ b/src/project/tempo.ts @@ -0,0 +1,129 @@ +import Immutable from "immutable" +import * as Project from "./index.ts" +import * as Theory from "../theory" +import BinarySearch from "../utils/binarySearch.ts" +import Rational from "../utils/rational.ts" +import ListOfRanges from "../utils/listOfRanges.ts" +import Range from "../utils/range.ts" + + +export interface TempoCacheRegion +{ + time1: Rational + time2: Rational + bpm: number + startMs: number +} + + +let tempoCacheKey: ListOfRanges = null! +let tempoCache: TempoCacheRegion[] = [] +let firstTempoCh: Project.TempoChange | null = null +let lastTempoCh: Project.TempoChange | null = null + +const defaultTempoRegion: TempoCacheRegion = { + time1: new Rational(0), + time2: new Rational(0), + bpm: 120, + startMs: 0, +} + + +export function ensureTempoCacheRefreshed(project: Project.ImmutableRoot) +{ + const tempoChList = project.lists.get(project.tempoChangeTrackId) + if (!tempoChList) + return + + if (tempoChList === tempoCacheKey) + return + + tempoCacheKey = tempoChList + tempoCache = [] + + if (!tempoChList) + return + + let accumulatedMs = 0 + + for (const [elem1, elem2] of tempoChList.iterAllPairwise()) + { + if (!elem1) + firstTempoCh = elem2 as Project.TempoChange | null + + if (!elem2) + lastTempoCh = elem1 as Project.TempoChange | null + + if (!elem1) + continue + + const tempoCh1 = elem1 as Project.TempoChange + const tempoCh2 = elem2 as (Project.TempoChange | null) + + tempoCache.push({ + time1: elem1.range.start, + time2: tempoCh2 ? tempoCh2.range.start : project.range.end, + bpm: tempoCh1.bpm, + startMs: accumulatedMs, + }) + + if (tempoCh2) + { + const measuresPerSecond = (tempoCh1.bpm / 4 / 60) + const durationMs = + tempoCh2.range.start.subtract(tempoCh1.range.start).asFloat() / + measuresPerSecond * 1000 + + accumulatedMs += durationMs + } + } +} + + +export function getMillisecondsAt( + project: Project.ImmutableRoot, + time: Rational) + : number +{ + ensureTempoCacheRefreshed(project) + + const tempoCacheIndex = BinarySearch.findPreviousOrEqual( + tempoCache, + (m) => time.compare(m.time1)) + + const tempoRegion = + tempoCacheIndex !== null ? tempoCache[tempoCacheIndex] : + tempoCache.length > 0 ? tempoCache[0] : + defaultTempoRegion + + const measuresPerSecond = (tempoRegion.bpm / 4 / 60) + const localMs = + time.subtract(tempoRegion.time1).asFloat() / + measuresPerSecond * 1000 + + return tempoRegion.startMs + localMs +} + + +export function getTimeAtMilliseconds( + project: Project.ImmutableRoot, + timeMs: number) + : Rational +{ + ensureTempoCacheRefreshed(project) + + const tempoCacheIndex = BinarySearch.findPreviousOrEqual( + tempoCache, + (m) => timeMs - m.startMs) + + const tempoRegion = + tempoCacheIndex !== null ? tempoCache[tempoCacheIndex] : + tempoCache.length > 0 ? tempoCache[0] : + defaultTempoRegion + + const measuresPerSecond = (tempoRegion.bpm / 4 / 60) + const localBeats = + (timeMs - tempoRegion.startMs) / 1000 * measuresPerSecond + + return tempoRegion.time1.add(Rational.fromFloat(localBeats, Project.MAX_RATIONAL_DENOMINATOR)) +} \ No newline at end of file diff --git a/src/timeline/Element.tsx b/src/timeline/Element.tsx index 34cf981..29a9b5f 100644 --- a/src/timeline/Element.tsx +++ b/src/timeline/Element.tsx @@ -181,6 +181,10 @@ function registerHandlers( } const onKeyDown = (ev: KeyboardEvent) => { + if (document.activeElement && + document.activeElement.tagName === "INPUT") + return + const timeline = Global.get().timeline const project = Global.get().project const prefs = Global.get().prefs diff --git a/src/timeline/draw.ts b/src/timeline/draw.ts index 72bab34..bc224ec 100644 --- a/src/timeline/draw.ts +++ b/src/timeline/draw.ts @@ -155,60 +155,7 @@ function drawElements( for (const element of elements) { if (element.kind === "note") - { - ctx.save() - ctx.beginPath() - ctx.roundRect( - element.rect.x, - element.rect.y, - element.rect.w, - element.rect.h, - timeline.noteRowH / 4) - ctx.clip() - - const x1 = element.rect.x + (element.cutStart ? -16 : 0) - const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) - - const key = element.key - const mode = key.scale.metadata?.mode ?? 0 - const fillStyle = CanvasUtils.fillStyleForDegree( - ctx, - key.degreeForMidi(element.note.midiPitch) + mode, - false) - - ctx.fillStyle = fillStyle - ctx.beginPath() - ctx.roundRect( - x1, - element.rect.y, - x2 - x1, - element.rect.h, - timeline.noteRowH / 4) - ctx.fill() - - if (timeline.hover?.id === element.id) - { - ctx.fillStyle = "#fff8" - ctx.fill() - } - - if (playback.playing && - element.note.range.overlapsPoint(playback.playTime)) - { - ctx.fillStyle = "#fff8" - ctx.fill() - } - - if (element.id !== undefined && - timeline.selection.has(element.id)) - { - ctx.strokeStyle = "#fff8" - ctx.lineWidth = 6 - ctx.stroke() - } - - ctx.restore() - } + drawNote(timeline, playback, prefs, ctx, element) else if (element.kind === "chord") drawChord(timeline, playback, prefs, ctx, element) @@ -219,6 +166,68 @@ function drawElements( } +function drawNote( + timeline: Timeline.State, + playback: Playback.Manager, + prefs: Prefs.Prefs, + ctx: CanvasRenderingContext2D, + element: Timeline.LayoutElementNote) +{ + ctx.save() + ctx.beginPath() + ctx.roundRect( + element.rect.x, + element.rect.y, + element.rect.w, + element.rect.h, + timeline.noteRowH / 4) + ctx.clip() + + const x1 = element.rect.x + (element.cutStart ? -16 : 0) + const x2 = element.rect.x2 + (element.cutEnd ? 16 : 0) + + const key = element.key + const mode = key.scale.metadata?.mode ?? 0 + const fillStyle = CanvasUtils.fillStyleForDegree( + ctx, + key.degreeForMidi(element.note.midiPitch) + mode, + false) + + ctx.fillStyle = fillStyle + ctx.beginPath() + ctx.roundRect( + x1, + element.rect.y, + x2 - x1, + element.rect.h, + timeline.noteRowH / 4) + ctx.fill() + + if (timeline.hover?.id === element.id) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } + + if (playback.playing && + element.note.range.overlapsPoint(playback.playTime)) + { + ctx.fillStyle = "#fff8" + ctx.fill() + } + + if (element.id !== undefined && + timeline.selection.has(element.id)) + { + ctx.strokeStyle = "#fff8" + ctx.lineWidth = 6 + ctx.stroke() + } + + ctx.restore() +} + + function drawChord( timeline: Timeline.State, playback: Playback.Manager, @@ -288,9 +297,10 @@ function drawMarker( ctx.save() const color = + element.tempoCh ? prefs.timeline.tempoChangeColor : element.keyCh ? prefs.timeline.keyChangeColor : element.meterCh ? prefs.timeline.meterChangeColor : - "#000" + prefs.timeline.measureLabelColor const makeKeyChangeDifferenceText = (chromaPrev: number | undefined, chromaNext: number) => { if (chromaPrev === undefined) @@ -303,6 +313,8 @@ function drawMarker( } const text = + element.tempoCh ? + element.tempoCh.bpm.toString() + " bpm" : element.keyCh ? element.keyCh.key.toString() + makeKeyChangeDifferenceText( @@ -560,6 +572,7 @@ export function drawLaneBkgMeasures( const x = Math.floor(Timeline.xAtTime(timeline, marker.time)) const color = + marker.tempoCh ? prefs.timeline.tempoChangeColor : marker.keyCh ? prefs.timeline.keyChangeColor : marker.meterCh ? prefs.timeline.meterChangeColor : prefs.timeline.measureColor diff --git a/src/timeline/lane_notes.ts b/src/timeline/lane_notes.ts index 903d830..9aa2a0a 100644 --- a/src/timeline/lane_notes.ts +++ b/src/timeline/lane_notes.ts @@ -141,8 +141,7 @@ export class LaneNotes extends Timeline.Lane const rect = rectForMarker( timeline, this, - elem.type === "keyChange" ? 0 : - 1, + elem.type, elem.range.start) let keyCh: Project.KeyChange | undefined = undefined @@ -165,6 +164,7 @@ export class LaneNotes extends Timeline.Lane rect, priority: 1, zIndex: 1, + tempoCh: elem.type === "tempoChange" ? elem : undefined, keyCh, keyChPrev, meterCh: elem.type === "meterChange" ? elem : undefined, @@ -172,6 +172,7 @@ export class LaneNotes extends Timeline.Lane timeline.layout.markers.push({ time: elem.range.start, + tempoCh: elem.type === "tempoChange" ? elem : undefined, keyCh: elem.type === "keyChange" ? elem : undefined, meterCh: elem.type === "meterChange" ? elem : undefined, }) @@ -411,31 +412,37 @@ function *iterMarkersForLayout( timeline: Timeline.State, project: Project.ImmutableRoot, range: Range) - : Generator + : Generator { - const keyChTrackElems = project.lists.get(project.keyChangeTrackId) - if (!keyChTrackElems) - return + const tempoChTrackElems = project.lists.get(project.tempoChangeTrackId) + if (tempoChTrackElems) + for (const tempoCh of tempoChTrackElems.iterAtRange(range)) + yield tempoCh as Project.TempoChange - for (const keyCh of keyChTrackElems.iterAtRange(range)) - yield keyCh as Project.KeyChange + const keyChTrackElems = project.lists.get(project.keyChangeTrackId) + if (keyChTrackElems) + for (const keyCh of keyChTrackElems.iterAtRange(range)) + yield keyCh as Project.KeyChange const meterChTrackElems = project.lists.get(project.meterChangeTrackId) - if (!meterChTrackElems) - return - - for (const meterCh of meterChTrackElems.iterAtRange(range)) - yield meterCh as Project.MeterChange + if (meterChTrackElems) + for (const meterCh of meterChTrackElems.iterAtRange(range)) + yield meterCh as Project.MeterChange } function rectForMarker( timeline: Timeline.State, lane: Timeline.Lane, - row: number, + markerType: Project.Element["type"], time: Rational) : Rect { + const row = + markerType === "tempoChange" ? 0 : + markerType === "keyChange" ? 1 : + 2 + const x = Timeline.xAtTime(timeline, time) const w = 16 const h = 24 @@ -451,17 +458,18 @@ function *iterMarkersForSelection( range: Range) : Generator { - const keyChTrackElems = project.lists.get(project.keyChangeTrackId) - if (!keyChTrackElems) - return + const tempoChTrackElems = project.lists.get(project.tempoChangeTrackId) + if (tempoChTrackElems) + for (const tempoCh of tempoChTrackElems.iterAtRange(range)) + yield tempoCh.id - for (const keyCh of keyChTrackElems.iterAtRange(range)) - yield keyCh.id + const keyChTrackElems = project.lists.get(project.keyChangeTrackId) + if (keyChTrackElems) + for (const keyCh of keyChTrackElems.iterAtRange(range)) + yield keyCh.id const meterChTrackElems = project.lists.get(project.meterChangeTrackId) - if (!meterChTrackElems) - return - - for (const meterCh of meterChTrackElems.iterAtRange(range)) - yield meterCh.id + if (meterChTrackElems) + for (const meterCh of meterChTrackElems.iterAtRange(range)) + yield meterCh.id } \ No newline at end of file diff --git a/src/timeline/layout.ts b/src/timeline/layout.ts index 86d0847..27c5e6a 100644 --- a/src/timeline/layout.ts +++ b/src/timeline/layout.ts @@ -76,6 +76,7 @@ export interface LayoutElementChord extends LayoutElementCommon export interface LayoutElementMarker extends LayoutElementCommon { kind: "marker" + tempoCh?: Project.TempoChange keyCh?: Project.KeyChange keyChPrev?: Project.KeyChange meterCh?: Project.MeterChange @@ -128,6 +129,7 @@ export interface ChordRegion export interface Marker { time: Rational + tempoCh?: Project.TempoChange keyCh?: Project.KeyChange meterCh?: Project.MeterChange } @@ -218,8 +220,7 @@ function *iterKeyChangePairsAtRange( range: Range) : Generator { - const keyChangeTrackId = Project.keyChangeTrackId(project) - const keyChangeTrackTimedElems = project.lists.get(keyChangeTrackId) + const keyChangeTrackTimedElems = project.lists.get(project.keyChangeTrackId) if (!keyChangeTrackTimedElems) return From 260b05e79f8d1c24f6d1fdedf98d0fcb137bc284 Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Sat, 27 Dec 2025 16:36:35 -0300 Subject: [PATCH 15/20] add meter change inspector --- src/components/Button.tsx | 10 ++ src/components/Select.tsx | 20 ++- src/components/TextInput.tsx | 65 +++++++++ src/components/index.ts | 3 +- src/inspector/Inspector.tsx | 6 + src/inspector/InspectorMeterChange.tsx | 188 +++++++++++++++++++++++++ src/inspector/InspectorTempoChange.tsx | 10 +- src/inspector/index.ts | 1 + src/playback/eventStream.ts | 45 +++--- src/project/measures.ts | 29 +++- src/theory/index.ts | 3 +- src/theory/key.ts | 2 +- src/theory/meter.ts | 84 +++++++++-- src/theory/scale.ts | 2 +- src/timeline/draw.ts | 5 +- src/timeline/lane_notes.ts | 2 +- 16 files changed, 421 insertions(+), 54 deletions(-) create mode 100644 src/components/TextInput.tsx create mode 100644 src/inspector/InspectorMeterChange.tsx diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 5f2c859..b53f9ac 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -4,7 +4,9 @@ import { styled } from "solid-styled-components" export function Button(props: { children?: Solid.JSXElement, + style?: Solid.JSX.CSSProperties, label?: Solid.JSXElement, + disabled?: boolean checked?: boolean, onClick?: () => void, groupStart?: boolean, @@ -18,6 +20,8 @@ export function Button(props: { data-group-middle={ !!props.groupMiddle } data-group-end={ !!props.groupEnd } onClick={ props.onClick } + disabled={ !!props.disabled } + style={ props.style } > { props.label ?? props.children } @@ -53,6 +57,12 @@ const StyledButton = styled.button<{ background-color: var(--theme-buttonBkgPress); } + &:disabled { + background-color: var(--theme-buttonBkgPress); + opacity: 0.5; + cursor: inherit; + } + &[data-checked=true] { background-color: var(--theme-buttonBkgSelected); } diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 8eaeded..0fba68b 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -2,17 +2,32 @@ import * as Solid from "solid-js" import { styled } from "solid-styled-components" +declare module "solid-js" +{ + namespace JSX + { + interface IntrinsicElements + { + "selectedcontent": HTMLAttributes + } + } +} + + export function Select(props: { children?: Solid.JSXElement, label?: Solid.JSXElement, value?: string, onChange?: (newValue: string) => void, + width?: string, }) { return props.onChange?.(ev.target.value) } - > + style={{ + width: props.width, + }}> { props.children } @@ -55,5 +70,4 @@ const StyledSelect = styled.select<{ &:active { background-color: var(--theme-buttonBkgPress); } -` -//${ props => props.$checked ? "background-color: var(--theme-buttonBkgSelected);" : "" } \ No newline at end of file +` \ No newline at end of file diff --git a/src/components/TextInput.tsx b/src/components/TextInput.tsx new file mode 100644 index 0000000..fe498b2 --- /dev/null +++ b/src/components/TextInput.tsx @@ -0,0 +1,65 @@ +import * as Solid from "solid-js" +import { styled } from "solid-styled-components" + + +export function TextInput(props: { + children?: Solid.JSXElement, + labelBefore?: Solid.JSXElement, + labelAfter?: Solid.JSXElement, + value?: string, + onChange?: (newValue: string) => void, + width?: string, +}) +{ + return + { props.labelBefore } + props.onChange?.(ev.target.value) } + onBlur={ ev => props.onChange?.(ev.target.value) } + style={{ + width: props.width, + }}/> + { props.labelAfter } + +} + + +const Layout = styled.div<{ +}>` + display: inline-block; + justify-self: stretch; + align-self: center; + user-select: none; + + margin: 0.25em; + padding: 0.25em 0.5em; + border: 0; + border-radius: var(--theme-buttonBorderRadius); + background-color: var(--theme-buttonBkg); + color: inherit; + font-family: inherit; + font-size: inherit; + + &:hover { + background-color: var(--theme-buttonBkgHover); + } +` + + +const StyledInput = styled.input<{ +}>` + display: inline-block; + justify-self: stretch; + align-self: stretch; + + margin: 0 0.05em; + padding: 0.25em 0.5em; + border: 0; + border-radius: var(--theme-buttonBorderRadius); + background-color: var(--theme-buttonBkgPress); + color: inherit; + font-family: inherit; + font-size: inherit; + outline: 0; +` \ No newline at end of file diff --git a/src/components/index.ts b/src/components/index.ts index 9f677a0..f48a131 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,3 +1,4 @@ export * from "./Button.tsx" export * from "./Checkbox.tsx" -export * from "./Select.tsx" \ No newline at end of file +export * from "./Select.tsx" +export * from "./TextInput.tsx" \ No newline at end of file diff --git a/src/inspector/Inspector.tsx b/src/inspector/Inspector.tsx index 1832914..39efb54 100644 --- a/src/inspector/Inspector.tsx +++ b/src/inspector/Inspector.tsx @@ -63,6 +63,12 @@ export function InspectorRoot(props: {}) upsertElem={ upsertElem } /> + if (elem?.type === "meterChange") + return + if (elem?.type === "chord") return void, +}) +{ + const [currMeter, setCurrMeter] = Solid.createSignal(props.value.meter) + + + const applyMeter = (meter: Theory.Meter) => { + setCurrMeter(meter) + const project = Global.get().project + const tempoCh = Project.getTypedElem(project.root, props.value.id, "meterChange") + if (tempoCh) + props.upsertElem({...tempoCh, meter }) + } + + + const parseNumerator = (str: string, index: number) => { + let numerator = parseInt(str) + if (!isFinite(numerator)) + return + + numerator = Math.max(1, Math.min(64, numerator)) + applyMeter(currMeter().withNumerator(index, numerator)) + } + + + const parseDenominator = (str: string, index: number) => { + let denominator = parseInt(str) + if (!isFinite(denominator)) + return + + denominator = Math.max(1, Math.min(64, denominator)) + applyMeter(currMeter().withDenominator(index, denominator)) + } + + + const addAlternating = () => { + applyMeter(currMeter().withAddedRatio()) + } + + + const removeAlternating = (index: number) => { + applyMeter(currMeter().withRemovedRatio(index)) + } + + + return <> + +

Meter Change

+ + + { (ratio, index) => +
+ parseNumerator(str, index) } + width="4em" + /> + { " / " } + +
+ } +
+ +
- setChordOptions(opts => ({ ...opts, withSus2: ev })) } />
- setChordOptions(opts => ({ ...opts, withSus4: ev })) } />
- setChordOptions(opts => ({ ...opts, withAdd9: ev })) } />
- setChordOptions(opts => ({ ...opts, withAdd11: ev })) } />
- setChordOptions(opts => ({ ...opts, withAdd13: ev })) } />

- setChordOptions(opts => ({ ...opts, withNo3: ev })) } />
- setChordOptions(opts => ({ ...opts, withNo5: ev })) } />
- setChordOptions(opts => ({ ...opts, withFlat5: ev })) } />
- setChordOptions(opts => ({ ...opts, withSharp5: ev })) } />
- setChordOptions(opts => ({ ...opts, withFlat9: ev })) } />
- setChordOptions(opts => ({ ...opts, withSharp9: ev })) } />
- setChordOptions(opts => ({ ...opts, withSharp11: ev })) } />
- setChordOptions(opts => ({ ...opts, withFlat13: ev })) } @@ -276,14 +275,14 @@ export function InspectorChord(props: { "grid-column": "1 / -1", "justify-self": "center", }}> - +
diff --git a/src/inspector/InspectorInsert.tsx b/src/ui/InspectorInsert.tsx similarity index 92% rename from src/inspector/InspectorInsert.tsx rename to src/ui/InspectorInsert.tsx index 0feda73..12bc83e 100644 --- a/src/inspector/InspectorInsert.tsx +++ b/src/ui/InspectorInsert.tsx @@ -1,10 +1,9 @@ import * as Solid from "solid-js" import * as Global from "../state.ts" -import * as Inspector from "./index.ts" +import * as Ui from "./index.ts" import * as Project from "../project" import * as Timeline from "../timeline" import * as Theory from "../theory" -import { Button } from "../components" import Rect from "../utils/rect.ts" import { styled } from "solid-styled-components" @@ -103,19 +102,19 @@ export function InspectorInsert(props: { return
- - - +
- diff --git a/src/inspector/InspectorKeyChange.tsx b/src/ui/InspectorKeyChange.tsx similarity index 96% rename from src/inspector/InspectorKeyChange.tsx rename to src/ui/InspectorKeyChange.tsx index 5f51d5e..7b1a216 100644 --- a/src/inspector/InspectorKeyChange.tsx +++ b/src/ui/InspectorKeyChange.tsx @@ -1,6 +1,6 @@ import * as Solid from "solid-js" import * as Global from "../state.ts" -import * as Inspector from "./index.ts" +import * as Ui from "./index.ts" import * as Project from "../project" import * as Timeline from "../timeline" import * as Theory from "../theory" @@ -155,7 +155,7 @@ export function InspectorKeyChange(props: { return applyScale(scaleMeta.id) } > { scaleMeta.names[0] } @@ -261,7 +261,7 @@ const ScaleList = styled.div` const ScaleButton = styled.div<{ - $selected: boolean, + "data-selected": boolean, }>` display: grid; grid-template: auto auto / auto; @@ -283,17 +283,10 @@ const ScaleButton = styled.div<{ &:active { background-color: var(--theme-buttonBkgPress); } - - ${ props => props.$selected ? "background-color: var(--theme-buttonBkgSelected);" : "" } -` - -const StyledSelect = styled.select` - /*appearance: base-select; - - &::picker(select) { - appearance: base-select; - }*/ + &:[data-selected=true] { + background-color: var(--theme-buttonBkgSelected); + } ` diff --git a/src/inspector/InspectorMeterChange.tsx b/src/ui/InspectorMeterChange.tsx similarity index 95% rename from src/inspector/InspectorMeterChange.tsx rename to src/ui/InspectorMeterChange.tsx index 7320a7a..53ec1c8 100644 --- a/src/inspector/InspectorMeterChange.tsx +++ b/src/ui/InspectorMeterChange.tsx @@ -1,10 +1,9 @@ import * as Solid from "solid-js" import * as Global from "../state.ts" -import * as Inspector from "./index.ts" +import * as Ui from "./index.ts" import * as Project from "../project" import * as Timeline from "../timeline" import * as Theory from "../theory" -import { Button, Select, TextInput } from "../components" import Rect from "../utils/rect.ts" import { styled } from "solid-styled-components" @@ -63,13 +62,13 @@ export function InspectorMeterChange(props: { { (ratio, index) =>
- parseNumerator(str, index) } width="4em" /> { " / " } - -