vibe-editor 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/package.json +56 -0
  4. package/src/fonts/bravura/FONTLOG.txt +243 -0
  5. package/src/fonts/bravura/OFL-FAQ.txt +369 -0
  6. package/src/fonts/bravura/OFL.txt +94 -0
  7. package/src/fonts/bravura/bravura-text.md +153 -0
  8. package/src/fonts/bravura/bravura_metadata.json +34718 -0
  9. package/src/fonts/bravura/eot/Bravura.eot +0 -0
  10. package/src/fonts/bravura/eot/BravuraText.eot +0 -0
  11. package/src/fonts/bravura/otf/Bravura.otf +0 -0
  12. package/src/fonts/bravura/otf/BravuraText.otf +0 -0
  13. package/src/fonts/bravura/svg/Bravura.svg +3517 -0
  14. package/src/fonts/bravura/svg/BravuraText.svg +18879 -0
  15. package/src/fonts/bravura/woff/Bravura.woff +0 -0
  16. package/src/fonts/bravura/woff/BravuraText.woff +0 -0
  17. package/src/fonts/colaborate/ColabBol-webfont.eot +0 -0
  18. package/src/fonts/colaborate/ColabBol-webfont.svg +976 -0
  19. package/src/fonts/colaborate/ColabBol-webfont.ttf +0 -0
  20. package/src/fonts/colaborate/ColabBol-webfont.woff +0 -0
  21. package/src/fonts/colaborate/ColabLig-webfont.eot +0 -0
  22. package/src/fonts/colaborate/ColabLig-webfont.svg +976 -0
  23. package/src/fonts/colaborate/ColabLig-webfont.ttf +0 -0
  24. package/src/fonts/colaborate/ColabLig-webfont.woff +0 -0
  25. package/src/fonts/colaborate/ColabMed-webfont.eot +0 -0
  26. package/src/fonts/colaborate/ColabMed-webfont.svg +976 -0
  27. package/src/fonts/colaborate/ColabMed-webfont.ttf +0 -0
  28. package/src/fonts/colaborate/ColabMed-webfont.woff +0 -0
  29. package/src/fonts/colaborate/ColabReg-webfont.eot +0 -0
  30. package/src/fonts/colaborate/ColabReg-webfont.svg +976 -0
  31. package/src/fonts/colaborate/ColabReg-webfont.ttf +0 -0
  32. package/src/fonts/colaborate/ColabReg-webfont.woff +0 -0
  33. package/src/fonts/colaborate/ColabThi-webfont.eot +0 -0
  34. package/src/fonts/colaborate/ColabThi-webfont.svg +970 -0
  35. package/src/fonts/colaborate/ColabThi-webfont.ttf +0 -0
  36. package/src/fonts/colaborate/ColabThi-webfont.woff +0 -0
  37. package/src/images/GUI/.DS_Store +0 -0
  38. package/src/images/GUI/backward-fast-solid.svg +1 -0
  39. package/src/images/GUI/bars-solid.svg +1 -0
  40. package/src/images/GUI/caret-left-solid.svg +1 -0
  41. package/src/images/GUI/caret-right-solid.svg +1 -0
  42. package/src/images/GUI/edit-solid.svg +1 -0
  43. package/src/images/GUI/pause-solid.svg +1 -0
  44. package/src/images/GUI/play-solid.svg +1 -0
  45. package/src/images/GUI/triplet.svg +21 -0
  46. package/src/images/GUI/zoomin.svg +1 -0
  47. package/src/images/GUI/zoomout.svg +1 -0
  48. package/src/images/bravura_notes/.DS_Store +0 -0
  49. package/src/images/bravura_notes/16th.svg +1 -0
  50. package/src/images/bravura_notes/32th.svg +1 -0
  51. package/src/images/bravura_notes/alterDDown.svg +1 -0
  52. package/src/images/bravura_notes/alterDUp.svg +1 -0
  53. package/src/images/bravura_notes/alterDown.svg +1 -0
  54. package/src/images/bravura_notes/alterNeutral.svg +1 -0
  55. package/src/images/bravura_notes/alterUp.svg +1 -0
  56. package/src/images/bravura_notes/beams.svg +1 -0
  57. package/src/images/bravura_notes/eigth.svg +1 -0
  58. package/src/images/bravura_notes/full.svg +1 -0
  59. package/src/images/bravura_notes/half.svg +1 -0
  60. package/src/images/bravura_notes/oneDot.svg +1 -0
  61. package/src/images/bravura_notes/pauseNote.svg +1 -0
  62. package/src/images/bravura_notes/quarter.svg +1 -0
  63. package/src/images/bravura_notes/tie.svg +1 -0
  64. package/src/images/bravura_notes/twoDot.svg +1 -0
  65. package/src/scripts/js/.DS_Store +0 -0
  66. package/src/scripts/js/Core.js +887 -0
  67. package/src/scripts/js/MusicPlayer.js +572 -0
  68. package/src/scripts/js/MusicProcessor.js +652 -0
  69. package/src/scripts/js/VerovioScoreEditor.js +183 -0
  70. package/src/scripts/js/assets/mei_template.js +161 -0
  71. package/src/scripts/js/constants.js +20 -0
  72. package/src/scripts/js/datastructures/MeasureMatrix.js +235 -0
  73. package/src/scripts/js/datastructures/ScoreGraph.js +432 -0
  74. package/src/scripts/js/datastructures/ScoreNode.js +78 -0
  75. package/src/scripts/js/entry.js +4 -0
  76. package/src/scripts/js/gui/Annotations.js +456 -0
  77. package/src/scripts/js/gui/Cursor.js +203 -0
  78. package/src/scripts/js/gui/CustomAnnotationDrawer.js +114 -0
  79. package/src/scripts/js/gui/CustomAnnotationShapeDrawer.js +114 -0
  80. package/src/scripts/js/gui/HarmonyLabel.js +104 -0
  81. package/src/scripts/js/gui/Label.js +2 -0
  82. package/src/scripts/js/gui/PhantomElement.js +132 -0
  83. package/src/scripts/js/gui/ScoreManipulator.js +156 -0
  84. package/src/scripts/js/gui/Tabbar.js +675 -0
  85. package/src/scripts/js/gui/TempoLabel.js +60 -0
  86. package/src/scripts/js/gui/Toolbar copy.js +614 -0
  87. package/src/scripts/js/gui/Toolbar.js +618 -0
  88. package/src/scripts/js/handlers/AnnotationChangeHandler.js +567 -0
  89. package/src/scripts/js/handlers/AnnotationDragHandler.js +113 -0
  90. package/src/scripts/js/handlers/AnnotationLineHandler.js +113 -0
  91. package/src/scripts/js/handlers/ArticulationHandler.js +20 -0
  92. package/src/scripts/js/handlers/ClickModeHandler.js +265 -0
  93. package/src/scripts/js/handlers/CustomAnnotationShapeDrawer.js +131 -0
  94. package/src/scripts/js/handlers/CustomToolbarHandler.js +297 -0
  95. package/src/scripts/js/handlers/DeleteHandler.js +102 -0
  96. package/src/scripts/js/handlers/GlobalKeyboardHandler.js +367 -0
  97. package/src/scripts/js/handlers/Handler.js +2 -0
  98. package/src/scripts/js/handlers/HarmonyHandler.js +282 -0
  99. package/src/scripts/js/handlers/InsertModeHandler copy.js +423 -0
  100. package/src/scripts/js/handlers/InsertModeHandler.js +380 -0
  101. package/src/scripts/js/handlers/InsertModeHandler_deprecated.js +424 -0
  102. package/src/scripts/js/handlers/KeyModeHandler copy.js +407 -0
  103. package/src/scripts/js/handlers/KeyModeHandler.js +456 -0
  104. package/src/scripts/js/handlers/KeyModeHandler_deprecated.js +411 -0
  105. package/src/scripts/js/handlers/LabelHandler.js +461 -0
  106. package/src/scripts/js/handlers/ModHandler.js +311 -0
  107. package/src/scripts/js/handlers/NoteDragHandler copy.js +148 -0
  108. package/src/scripts/js/handlers/NoteDragHandler.js +97 -0
  109. package/src/scripts/js/handlers/NoteDragHandler_deprecated.js +150 -0
  110. package/src/scripts/js/handlers/PhantomElementHandler.js +168 -0
  111. package/src/scripts/js/handlers/ScoreManipulatorHandler.js +135 -0
  112. package/src/scripts/js/handlers/SelectionHandler.js +218 -0
  113. package/src/scripts/js/handlers/SideBarHandler.js +499 -0
  114. package/src/scripts/js/handlers/TooltipHandler.js +132 -0
  115. package/src/scripts/js/handlers/WindowHandler.js +257 -0
  116. package/src/scripts/js/utils/DOMCreator.js +174 -0
  117. package/src/scripts/js/utils/MEIConverter.js +64 -0
  118. package/src/scripts/js/utils/MEIOperations.js +2112 -0
  119. package/src/scripts/js/utils/Mouse2MEI.js +735 -0
  120. package/src/scripts/js/utils/Mouse2SVG.js +737 -0
  121. package/src/scripts/js/utils/SVGEditor.js +352 -0
  122. package/src/scripts/js/utils/SVGFiller.js +245 -0
  123. package/src/scripts/js/utils/Types.js +2 -0
  124. package/src/scripts/js/utils/VerovioWrapper copy.js +156 -0
  125. package/src/scripts/js/utils/VerovioWrapper.js +165 -0
  126. package/src/scripts/js/utils/VerovioWrapperLocal.js +156 -0
  127. package/src/scripts/js/utils/convenienceQueries.js +37 -0
  128. package/src/scripts/js/utils/coordinates.js +54 -0
  129. package/src/scripts/js/utils/firefoxBBoxes.js +143 -0
  130. package/src/scripts/js/utils/mappings.js +332 -0
  131. package/src/scripts/js/utils/random.js +45 -0
  132. package/src/styles/VerovioScoreEditor.css +694 -0
@@ -0,0 +1,737 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Mouse2SVG = void 0;
4
+ const random_1 = require("./random");
5
+ const mappings_1 = require("./mappings");
6
+ const MeasureMatrix_1 = require("../datastructures/MeasureMatrix");
7
+ const meiOperation = require("./MEIOperations");
8
+ const coordinates = require("./coordinates");
9
+ const cq = require("./convenienceQueries");
10
+ class Mouse2SVG {
11
+ constructor() {
12
+ this.lastSystemMouseEnter = null;
13
+ this.lastStaffMouseEnter = null;
14
+ this.lastMeasureMouseEnter = null;
15
+ this.lastLayerMouseEnter = null;
16
+ this.noteNewDur = "4";
17
+ this.noteBBoxes = new Array();
18
+ this.staffLineBBoxes = new Array();
19
+ this.measureMatrix = new MeasureMatrix_1.default();
20
+ //this.setMouseEnterElementListeners();
21
+ //this.findBBoxes();
22
+ }
23
+ /**
24
+ * Set Flags for current focused measure, staff, system and layer when mouse moves.
25
+ * @returns
26
+ */
27
+ setMouseEnterElementListeners() {
28
+ var that = this;
29
+ var mouseEventName = "mouseover";
30
+ var enteredFlag = "lastEntered";
31
+ var activeContainerFlag = "activeContainer";
32
+ this.container.addEventListener("mouseenter", function (e) {
33
+ Array.from(document.getElementsByClassName("vse-container")).forEach(ac => {
34
+ if (ac === that.container) {
35
+ if (!that.container.classList.contains(activeContainerFlag)) {
36
+ that.container.classList.add(activeContainerFlag);
37
+ }
38
+ }
39
+ else {
40
+ ac.classList.remove(activeContainerFlag);
41
+ }
42
+ });
43
+ });
44
+ this.container.addEventListener("mouseleave", function (e) {
45
+ Array.from(document.getElementsByClassName("vse-container")).forEach(ac => {
46
+ if (ac === that.container) {
47
+ ac.classList.remove(activeContainerFlag);
48
+ }
49
+ });
50
+ });
51
+ this.interactionOverlay.querySelectorAll(".system").forEach(sy => {
52
+ sy.addEventListener(mouseEventName, function (e) {
53
+ e.preventDefault();
54
+ var target = e.target;
55
+ that.lastSystemMouseEnter = target.closest(".system");
56
+ if (!that.lastSystemMouseEnter.classList.contains(enteredFlag)) {
57
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".system").forEach(s => {
58
+ s.classList.remove(enteredFlag);
59
+ });
60
+ that.lastSystemMouseEnter.classList.add(enteredFlag);
61
+ }
62
+ });
63
+ });
64
+ this.interactionOverlay.querySelectorAll(".staff").forEach(staff => {
65
+ staff.addEventListener(mouseEventName, function (e) {
66
+ var _a;
67
+ e.preventDefault();
68
+ var target = e.target;
69
+ that.lastStaffMouseEnter = target.closest(".staff");
70
+ (_a = that.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new Event("currStaffChanged"));
71
+ if (!that.lastStaffMouseEnter.classList.contains(enteredFlag)) {
72
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".staff").forEach(s => {
73
+ s.classList.remove(enteredFlag);
74
+ that.getElementinVrvSVG(s.getAttribute("refId")).classList.remove(enteredFlag);
75
+ });
76
+ that.container.querySelectorAll(".onChord").forEach(oc => oc.classList.remove("onChord")); // reset onChord, so that only chords in the same staff are set
77
+ that.lastStaffMouseEnter.classList.add(enteredFlag);
78
+ that.getElementinVrvSVG(that.lastStaffMouseEnter.getAttribute("refId")).classList.add(enteredFlag);
79
+ }
80
+ });
81
+ });
82
+ this.interactionOverlay.querySelectorAll(".measure").forEach(measure => {
83
+ measure.addEventListener(mouseEventName, function (e) {
84
+ e.preventDefault();
85
+ var target = e.target;
86
+ that.lastMeasureMouseEnter = target.closest(".measure");
87
+ if (!that.lastMeasureMouseEnter.classList.contains(enteredFlag)) {
88
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".measure").forEach(m => {
89
+ m.classList.remove(enteredFlag);
90
+ });
91
+ that.lastMeasureMouseEnter.classList.add(enteredFlag);
92
+ //that.vrvSVG.querySelector("#"+that.lastMeasureMouseEnter.id).classList.add(enteredFlag)
93
+ }
94
+ });
95
+ });
96
+ this.interactionOverlay.querySelectorAll(".layer").forEach(layer => {
97
+ layer.addEventListener(mouseEventName, function (e) {
98
+ e.preventDefault();
99
+ var target = e.target;
100
+ that.lastLayerMouseEnter = target.closest(".layer");
101
+ if (!that.lastLayerMouseEnter.classList.contains(enteredFlag)) {
102
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".layer").forEach(l => {
103
+ l.classList.remove(enteredFlag);
104
+ });
105
+ that.lastLayerMouseEnter.classList.add(enteredFlag);
106
+ }
107
+ });
108
+ });
109
+ return this;
110
+ }
111
+ setMouseEnterElements(refElement) {
112
+ var _a, _b, _c, _d, _e, _f, _g;
113
+ this.lastSystemMouseEnter = this.getElementInInteractOverlay((_a = refElement.closest(".system")) === null || _a === void 0 ? void 0 : _a.id);
114
+ this.lastMeasureMouseEnter = this.getElementInInteractOverlay((_b = refElement.closest(".measure")) === null || _b === void 0 ? void 0 : _b.id) || this.getElementInInteractOverlay((_c = refElement.querySelector(".measure")) === null || _c === void 0 ? void 0 : _c.id);
115
+ this.lastStaffMouseEnter = this.getElementInInteractOverlay((_d = refElement.closest(".staff")) === null || _d === void 0 ? void 0 : _d.id) || this.getElementInInteractOverlay((_e = refElement.querySelector(".staff")) === null || _e === void 0 ? void 0 : _e.id);
116
+ this.lastLayerMouseEnter = this.getElementInInteractOverlay((_f = refElement.closest(".layer")) === null || _f === void 0 ? void 0 : _f.id) || this.getElementInInteractOverlay((_g = refElement.querySelector(".layer")) === null || _g === void 0 ? void 0 : _g.id);
117
+ //this.update()
118
+ }
119
+ getMouseEnterElementByName(name) {
120
+ let e;
121
+ switch (name) {
122
+ case "system":
123
+ e = this.lastSystemMouseEnter;
124
+ break;
125
+ case "staff":
126
+ e = this.lastStaffMouseEnter;
127
+ break;
128
+ case "measure":
129
+ e = this.lastMeasureMouseEnter;
130
+ break;
131
+ case "layer":
132
+ e = this.lastLayerMouseEnter;
133
+ break;
134
+ default:
135
+ e = null;
136
+ }
137
+ return e;
138
+ }
139
+ findBBoxes() {
140
+ var notes = this.vrvSVG.querySelectorAll(".note, .rest, .mRest, .notehead");
141
+ var root = this.vrvSVG;
142
+ Array.from(notes).forEach(element => {
143
+ var interactionElement = this.interactionOverlay.querySelector("[refId=" + element.id + "]");
144
+ if (interactionElement === null)
145
+ return;
146
+ var relpt = coordinates.getDOMMatrixCoordinates(interactionElement, this.interactionOverlay);
147
+ let bb = {
148
+ id: element.id,
149
+ parentStaff: element.closest(".staff"),
150
+ parentLayer: element.closest(".layer"),
151
+ parentMeasure: element.closest(".measure"),
152
+ x: relpt.right,
153
+ y: relpt.y
154
+ };
155
+ this.noteBBoxes.push(bb);
156
+ });
157
+ this.measureMatrix.populateFromMEI(this.currentMEI);
158
+ var staves = this.currentMEI.querySelectorAll("staff"); //cq.getVrvSVG(this.containerId).querySelectorAll(".staff")
159
+ Array.from(staves).forEach(element => {
160
+ let g = cq.getVrvSVG(this.containerId).querySelectorAll("#" + element.id + " > path");
161
+ let staff = element;
162
+ let idxStaff = parseInt(element.getAttribute("n")) - 1;
163
+ let closestMeasure = element.closest("measure");
164
+ let idxParentMeasure = parseInt(closestMeasure.getAttribute("n")) - 1;
165
+ let clefShape = this.measureMatrix.get(idxParentMeasure, idxStaff).clef;
166
+ Array.from(g).forEach((staffLine, idx) => {
167
+ if (staffLine.id === "") {
168
+ staffLine.id = random_1.uuidv4();
169
+ }
170
+ staffLine.classList.add("staffLine");
171
+ staffLine.classList.add("Clef" + clefShape);
172
+ var map = null;
173
+ switch (clefShape) {
174
+ case "G":
175
+ map = mappings_1.idxNoteMapGClef;
176
+ break;
177
+ case "F":
178
+ map = mappings_1.idxNoteMapFClef;
179
+ break;
180
+ case "C":
181
+ map = mappings_1.idxNoteMapCClef;
182
+ break;
183
+ default:
184
+ console.error("No Clef found");
185
+ break;
186
+ }
187
+ staffLine.classList.add(map.get(idx * 2));
188
+ staffLine.classList.add("Clef" + clefShape);
189
+ var relpt = coordinates.getDOMMatrixCoordinates(staffLine, cq.getInteractOverlay(this.containerId)); //this.vrvSVG)
190
+ let bb = {
191
+ id: staffLine.parentElement.id,
192
+ y: relpt.y,
193
+ staffIdx: idx * 2,
194
+ classList: staffLine.classList
195
+ };
196
+ this.staffLineBBoxes.push(bb);
197
+ });
198
+ });
199
+ }
200
+ /**
201
+ * Create Phantom Lines to detect clicks above and under the system
202
+ */
203
+ createPhantomLines(upperStaffBound, lowerStaffBound) {
204
+ this.phantomStaffLinesAbove = new Array();
205
+ this.phantomStaffLinesBelow = new Array();
206
+ var diffY = Math.abs(this.staffLineBBoxes[0].y - this.staffLineBBoxes[1].y);
207
+ //Above System
208
+ for (var i = 0; i < 9; i++) {
209
+ if (i === 0) {
210
+ this.phantomStaffLinesAbove.push({ y: this.staffLineBBoxes[upperStaffBound].y - diffY });
211
+ }
212
+ else {
213
+ this.phantomStaffLinesAbove.push({ y: this.phantomStaffLinesAbove[i - 1].y - diffY });
214
+ }
215
+ }
216
+ //Below System
217
+ for (var i = 0; i < 12; i++) {
218
+ if (i === 0) {
219
+ this.phantomStaffLinesBelow.push({ y: this.staffLineBBoxes[lowerStaffBound].y + diffY });
220
+ }
221
+ else {
222
+ this.phantomStaffLinesBelow.push({ y: this.phantomStaffLinesBelow[i - 1].y + diffY });
223
+ }
224
+ }
225
+ }
226
+ /**
227
+ * Define New Note at coordinates
228
+ * 1. Check if left of Note
229
+ * 2. Check position between staves
230
+ * 3. update
231
+ *
232
+ * @param x client Coordinate
233
+ * @param y client Coordinate
234
+ */
235
+ defineNote(x, y, options) {
236
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
237
+ let staffIsEmpty = true;
238
+ let isLeftOfNote;
239
+ //let isRightOfNote: Boolean
240
+ let currentNearestNote = null;
241
+ let diffNote = null;
242
+ let leftRightPos;
243
+ let allIDs = Array.from(this.vrvSVG.querySelectorAll(".staff")).map(s => s.getAttribute("id"));
244
+ if (this.lastStaffMouseEnter === null) {
245
+ return;
246
+ }
247
+ let staffIdx = allIDs.indexOf((_a = this.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.getAttribute("refId"));
248
+ let upperStaffBound = staffIdx * 5 + 0;
249
+ let lowerStaffBound = staffIdx * 5 + 4;
250
+ let aboveSystem = (y < ((_b = this.staffLineBBoxes[upperStaffBound]) === null || _b === void 0 ? void 0 : _b.y)) ? true : false;
251
+ let belowSystem = (y > ((_c = this.staffLineBBoxes[lowerStaffBound]) === null || _c === void 0 ? void 0 : _c.y)) ? true : false;
252
+ let isInSystem = !aboveSystem && !belowSystem;
253
+ //this will cause that the duration of the chord will not be applied on inserted note
254
+ let isRestChord = false;
255
+ if (options.targetChord != undefined) {
256
+ isRestChord = options.targetChord.classList.contains("rest");
257
+ }
258
+ options.targetChord = isRestChord ? undefined : options.targetChord;
259
+ (_e = this.getElementinVrvSVG((_d = this.lastStaffMouseEnter) === null || _d === void 0 ? void 0 : _d.getAttribute("refId"))) === null || _e === void 0 ? void 0 : _e.querySelectorAll(".layer").forEach(l => {
260
+ if (l.hasChildNodes()) {
261
+ staffIsEmpty = false;
262
+ }
263
+ });
264
+ var currentStaffClef;
265
+ var entries = (_j = (_h = (_g = this.getElementinVrvSVG((_f = this.lastStaffMouseEnter) === null || _f === void 0 ? void 0 : _f.getAttribute("refId"))) === null || _g === void 0 ? void 0 : _g.querySelector(".staffLine")) === null || _h === void 0 ? void 0 : _h.classList) === null || _j === void 0 ? void 0 : _j.entries();
266
+ if ([null, undefined].some(n => entries == n))
267
+ return;
268
+ for (const [key, value] of entries) {
269
+ if (value.indexOf("Clef") !== -1) {
270
+ currentStaffClef = value;
271
+ break;
272
+ }
273
+ }
274
+ // Define relative position for click insert
275
+ // position should also consider right border of bounding box. Position should be
276
+ if (!staffIsEmpty) {
277
+ let nbb = [];
278
+ this.noteBBoxes.forEach(bb => {
279
+ var _a;
280
+ if (bb.parentStaff.id === ((_a = this.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.getAttribute("refId"))) {
281
+ nbb.push(bb);
282
+ }
283
+ });
284
+ nbb.forEach(bb => {
285
+ let zerocrossing = x - bb.x;
286
+ let tempDiff = Math.sqrt(Math.abs(x - bb.x) ** 2 + Math.abs(y - bb.y) ** 2);
287
+ if ((diffNote === null || Math.abs(tempDiff) < Math.abs(diffNote))) {
288
+ diffNote = tempDiff;
289
+ currentNearestNote = bb;
290
+ isLeftOfNote = zerocrossing <= 0 ? true : false;
291
+ }
292
+ });
293
+ leftRightPos = isLeftOfNote ? "left" : "right";
294
+ }
295
+ if (isRestChord) {
296
+ leftRightPos = "left";
297
+ }
298
+ let currentNearestStaffLine = null;
299
+ let currentNearestLineIdx = null;
300
+ let isOverStaff;
301
+ //let isUnderStaff: Boolean;
302
+ let diffStaff = null;
303
+ let pname;
304
+ let oct;
305
+ let noteDefinition = new Array();
306
+ let nextPitchIdx;
307
+ if (!isInSystem) { //Phantom Line Stuff
308
+ this.phantomLines = new Array();
309
+ let currentNearestY;
310
+ this.createPhantomLines(upperStaffBound, lowerStaffBound);
311
+ let lineArr = aboveSystem ? this.phantomStaffLinesAbove : this.phantomStaffLinesBelow;
312
+ let aboveMap;
313
+ let belowMap;
314
+ switch (currentStaffClef) {
315
+ case "ClefG":
316
+ aboveMap = mappings_1.idxNotePhantomMapAboveG;
317
+ belowMap = mappings_1.idxNotePhantomMapBelowG;
318
+ break;
319
+ case "ClefF":
320
+ aboveMap = mappings_1.idxNotePhantomMapAboveF;
321
+ belowMap = mappings_1.idxNotePhantomMapBelowF;
322
+ break;
323
+ case "ClefC":
324
+ aboveMap = mappings_1.idxNotePhantomMapAboveC;
325
+ belowMap = mappings_1.idxNotePhantomMapBelowC;
326
+ break;
327
+ default:
328
+ console.log("NO CLEF FOUND");
329
+ }
330
+ let map = aboveSystem ? aboveMap : belowMap;
331
+ let mappingidx = 0;
332
+ lineArr.forEach((line, idx) => {
333
+ let tempDiff = y - line.y;
334
+ mappingidx++;
335
+ if (diffStaff === null || Math.abs(tempDiff) < Math.abs(diffStaff)) {
336
+ this.phantomLines.push(line.y);
337
+ //if(idx%2 !== 0){return} // take only Elements which are actually lines! (every second one)
338
+ currentNearestY = line.y;
339
+ diffStaff = tempDiff;
340
+ currentNearestLineIdx = idx + mappingidx;
341
+ isOverStaff = tempDiff <= 0 ? true : false;
342
+ }
343
+ });
344
+ // prepare center coordinate (Y) for snapping
345
+ let lineDist = Math.abs(lineArr[0].y - lineArr[1].y);
346
+ this.lineDist = lineDist / 2;
347
+ lineDist = isOverStaff ? -lineDist : lineDist;
348
+ if (Math.abs(currentNearestY - y) < Math.abs(lineDist / 2 + currentNearestY - y)) { // line pos < middleline pos
349
+ this.newNoteY = currentNearestY;
350
+ nextPitchIdx = currentNearestLineIdx;
351
+ }
352
+ else {
353
+ if (aboveSystem) {
354
+ nextPitchIdx = isOverStaff ? currentNearestLineIdx + 1 : currentNearestLineIdx - 1;
355
+ }
356
+ else {
357
+ nextPitchIdx = isOverStaff ? currentNearestLineIdx - 1 : currentNearestLineIdx + 1;
358
+ }
359
+ this.newNoteY = currentNearestY + lineDist / 2;
360
+ }
361
+ if (map.get(nextPitchIdx) == undefined) {
362
+ return;
363
+ } // cursor is outside of score
364
+ pname = map.get(nextPitchIdx).charAt(0);
365
+ oct = map.get(nextPitchIdx).charAt(1);
366
+ }
367
+ else {
368
+ // Decide if Staffline is given or not
369
+ this.phantomLines = undefined;
370
+ if (options.staffLineId == undefined) {
371
+ let sbb = [];
372
+ this.staffLineBBoxes.forEach(bb => { var _a; if (bb.id === ((_a = this.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.getAttribute("refId")))
373
+ sbb.push(bb); });
374
+ sbb.forEach(bb => {
375
+ let tempDiff = y - bb.y;
376
+ if (diffStaff === null || Math.abs(tempDiff) < Math.abs(diffStaff)) {
377
+ diffStaff = tempDiff;
378
+ currentNearestStaffLine = bb;
379
+ isOverStaff = tempDiff <= 0 ? true : false;
380
+ //isUnderStaff = tempDiff > 0 ? true : false;
381
+ }
382
+ });
383
+ // prepare center coordinate (Y) for snapping
384
+ if (sbb[0] == undefined || sbb[1] == undefined) {
385
+ return;
386
+ }
387
+ let lineDist = Math.abs(sbb[0].y - sbb[1].y);
388
+ this.lineDist = lineDist / 2;
389
+ lineDist = isOverStaff ? -lineDist : lineDist;
390
+ if (Math.abs(currentNearestStaffLine.y - y) < Math.abs(lineDist / 2 + currentNearestStaffLine.y - y)) { // line pos < middleline pos
391
+ this.newNoteY = currentNearestStaffLine.y; // on line
392
+ nextPitchIdx = currentNearestStaffLine.staffIdx;
393
+ }
394
+ else {
395
+ this.newNoteY = currentNearestStaffLine.y + lineDist / 2; // between lines
396
+ nextPitchIdx = isOverStaff ? currentNearestStaffLine.staffIdx - 1 : currentNearestStaffLine.staffIdx + 1;
397
+ }
398
+ let map = null;
399
+ if (currentNearestStaffLine.classList.contains("ClefG")) {
400
+ map = mappings_1.idxNoteMapGClef;
401
+ }
402
+ else if (currentNearestStaffLine.classList.contains("ClefF")) {
403
+ map = mappings_1.idxNoteMapFClef;
404
+ }
405
+ else if (currentNearestStaffLine.classList.contains("ClefC")) {
406
+ map = mappings_1.idxNoteMapCClef;
407
+ }
408
+ else {
409
+ throw new Error("No Note to Clef Mapping found");
410
+ }
411
+ if (map.get(nextPitchIdx) == undefined) {
412
+ return;
413
+ }
414
+ pname = map.get(nextPitchIdx).charAt(0);
415
+ oct = map.get(nextPitchIdx).charAt(1);
416
+ }
417
+ else {
418
+ let pitch;
419
+ try {
420
+ pitch = cq.getInteractOverlay(this.containerId).querySelector("#" + options.staffLineId).getAttribute("class").split(" ");
421
+ }
422
+ catch (_o) {
423
+ return;
424
+ }
425
+ let p = pitch.filter(function (obj) {
426
+ let isPname = obj.charAt(0) === obj.charAt(0).toLowerCase(); // noch regexe?
427
+ let isOct = !isNaN(parseInt(obj.charAt(1)));
428
+ let length = obj.length === 2;
429
+ return isPname && isOct && length;
430
+ });
431
+ pname = p[0].charAt(0);
432
+ oct = p[0].charAt(1);
433
+ this.newNoteY = this.staffLineBBoxes.filter(function (bb) {
434
+ return bb.classList === cq.getInteractOverlay(this.containerId).querySelector("#" + options.staffLineId).classList;
435
+ })[0].y; // assert that length is 1 (all classlists are unique for )
436
+ }
437
+ }
438
+ //get relevant staffinfo
439
+ //var closestStaff = this.currentMEI.getElementById(currentNearestNote.id).closest("staff")
440
+ var closestStaff = this.currentMEI.getElementById((_k = this.lastStaffMouseEnter) === null || _k === void 0 ? void 0 : _k.getAttribute("refId"));
441
+ var closestMeasure = closestStaff.closest("measure");
442
+ var closestStaffIdx = parseInt(closestStaff.getAttribute("n")) - 1;
443
+ var closestMeasureIdx = parseInt(closestMeasure.getAttribute("n")) - 1;
444
+ var nearestNoteId = (currentNearestNote !== null) ? currentNearestNote.id : null;
445
+ if (nearestNoteId !== null) { // ensure note id to be in new note
446
+ nearestNoteId = this.vrvSVG.querySelector("#" + nearestNoteId).classList.contains("notehead") ? this.vrvSVG.querySelector("#" + nearestNoteId).closest(".note").id : nearestNoteId;
447
+ }
448
+ var keysig = this.measureMatrix.get(closestMeasureIdx, closestStaffIdx).keysig;
449
+ var accid;
450
+ if (this.container.querySelector(".alterBtn.selected") !== null) {
451
+ accid = mappings_1.modButtonToAttr.get(this.container.querySelector(".alterBtn.selected").id);
452
+ }
453
+ else if (keysig != undefined) {
454
+ accid = mappings_1.keysigToNotes.get(keysig);
455
+ accid = accid.filter((s) => { return s === pname; });
456
+ if (accid.length === 1) {
457
+ accid = keysig.charAt(1);
458
+ }
459
+ }
460
+ var newNote = {
461
+ id: random_1.uuidv4(),
462
+ pname: pname,
463
+ dur: this.getDurationNewNote(),
464
+ dots: this.getDotsNewNote(),
465
+ oct: oct,
466
+ keysig: keysig,
467
+ accid: accid,
468
+ nearestNoteId: nearestNoteId,
469
+ relPosX: leftRightPos,
470
+ staffId: (_l = this.lastStaffMouseEnter) === null || _l === void 0 ? void 0 : _l.getAttribute("refId"),
471
+ chordElement: options.targetChord,
472
+ rest: (_m = this.container.querySelector("#pauseNote")) === null || _m === void 0 ? void 0 : _m.classList.contains("selected")
473
+ };
474
+ this.newNote = newNote;
475
+ }
476
+ /**
477
+ * Find Score Element nearest to given Position (e.g. Mouse)
478
+ * @param posX should be already transformed DOMPoint
479
+ * @param posY should be already transformed DOMPoint
480
+ * @param checkStaff check if vertical distance in the staff should be considered
481
+ * (for example: should be false, when check position for Annotations, should be true when placing notes in different staves)
482
+ * @param orientation only consider elements which are left or right of given coordinates
483
+ * @returns
484
+ */
485
+ findScoreTarget(posX, posY, checkStaff = true, orientation = { left: true, right: true }) {
486
+ var notes = this.getNoteBBoxes();
487
+ var nextNote;
488
+ var tempDist = Math.pow(10, 10);
489
+ var i = 0;
490
+ notes.forEach(n => {
491
+ var _a, _b, _c, _d;
492
+ var x;
493
+ var y;
494
+ if (((_a = this.getElementinVrvSVG(n.id)) === null || _a === void 0 ? void 0 : _a.closest(".chord")) && navigator.userAgent.toLowerCase().indexOf("firefox") > -1) { // special rule for firefox browsers
495
+ x = (_b = this.getElementinVrvSVG(n.id)) === null || _b === void 0 ? void 0 : _b.closest(".chord").getBoundingClientRect().x;
496
+ y = (_c = this.getElementinVrvSVG(n.id)) === null || _c === void 0 ? void 0 : _c.closest(".chord").getBoundingClientRect().y;
497
+ }
498
+ else {
499
+ x = n.x;
500
+ y = n.y;
501
+ }
502
+ //filter for left and right elements
503
+ if (this.vrvSVG.querySelector("#" + n.id) === null)
504
+ return;
505
+ if (!this.vrvSVG.querySelector("#" + n.id).classList.contains("mRest")) { //mRest are excluded from this rule
506
+ if (orientation.left === false) {
507
+ if (x < posX)
508
+ return; //exclude left elements
509
+ }
510
+ else if (orientation.right === false) {
511
+ if (x > posX)
512
+ return; // exclude right elements
513
+ }
514
+ }
515
+ var dist = Math.abs(x - posX);
516
+ var staffCondition = n.parentStaff === this.getElementinVrvSVG((_d = this.lastStaffMouseEnter) === null || _d === void 0 ? void 0 : _d.getAttribute("refId"));
517
+ if (checkStaff === false) {
518
+ staffCondition = true;
519
+ dist = Math.sqrt(Math.abs(x - posX) ** 2 + Math.abs(y - posY) ** 2);
520
+ }
521
+ if (dist < tempDist && staffCondition) { // define next note in staff bounds
522
+ tempDist = dist;
523
+ nextNote = n;
524
+ }
525
+ // var l = {x: x, posX: posX, dist: dist, tempDist: tempDist, nextNote: nextNote.id}
526
+ // console.log(i, l)
527
+ // i++
528
+ });
529
+ return nextNote;
530
+ }
531
+ ///// GETTER/ SETTER ///////
532
+ getLastMouseEnter() {
533
+ return { layer: this.lastLayerMouseEnter, staff: this.lastStaffMouseEnter, measure: this.lastMeasureMouseEnter, system: this.lastSystemMouseEnter };
534
+ }
535
+ getNewNote() {
536
+ return this.newNote;
537
+ }
538
+ getNewNoteY() {
539
+ return this.newNoteY;
540
+ }
541
+ getPhantomLines() {
542
+ return this.phantomLines;
543
+ }
544
+ getNoteBBoxes() {
545
+ return this.noteBBoxes;
546
+ }
547
+ getStaffLineBBoxes() {
548
+ return this.staffLineBBoxes;
549
+ }
550
+ setPnameNewNote(name) {
551
+ this.notePname = name;
552
+ }
553
+ setDurationNewNote(dur) {
554
+ this.noteNewDur = dur.toString();
555
+ }
556
+ /**
557
+ * Change note, chord or rest to given duration
558
+ * @param dur
559
+ * @returns
560
+ */
561
+ setMarkedNoteDurations(dur) {
562
+ var retVal = false;
563
+ var markedElements = this.vrvSVG.querySelectorAll(".note.marked, .rest.marked");
564
+ markedElements.forEach(m => {
565
+ var currMeiClone = this.currentMEI.cloneNode(true);
566
+ var meiElement = this.currentMEI.getElementById(m.id);
567
+ var oldMeiElement = meiElement.cloneNode(true);
568
+ var newMeiElement;
569
+ if (meiElement.closest("chord") !== null) {
570
+ oldMeiElement = meiElement.closest("chord").cloneNode(true);
571
+ meiElement.closest("chord").setAttribute("dur", dur.toString());
572
+ newMeiElement = meiElement.closest("chord");
573
+ }
574
+ else {
575
+ oldMeiElement = meiElement.cloneNode(true);
576
+ meiElement.setAttribute("dur", dur.toString());
577
+ newMeiElement = meiElement;
578
+ }
579
+ oldMeiElement.replaceWith(newMeiElement);
580
+ this.currentMEI = meiOperation.fillWithRests(newMeiElement, oldMeiElement, this.currentMEI);
581
+ //if(this.currentMEI.querySelectorAll(".changed").length === 0){
582
+ var additionalElements = Array.from(newMeiElement.closest("layer").querySelectorAll("*[dur]"));
583
+ additionalElements = additionalElements.filter((v, i) => i > additionalElements.indexOf(newMeiElement));
584
+ //this.currentMEI = meiOperation.changeDuration(this.currentMEI, "reduce", additionalElements)
585
+ //additionalElements.unshift(oldMeiElement) // we need this information to determine the new duration of an element that has to be shortened
586
+ this.currentMEI = meiOperation.changeDurationsInLayer(this.currentMEI, additionalElements, newMeiElement); //this.currentMEI = meiOperation.changeDuration(this.currentMEI, additionalElements)
587
+ //}
588
+ this.currentMEI.querySelectorAll(".changed").forEach(c => c.classList.remove("changed"));
589
+ //check if following events (notes, chords, rests) should be replaced
590
+ if (meiOperation.elementIsOverfilling(meiElement, currMeiClone)) {
591
+ this.currentMEI = currMeiClone;
592
+ }
593
+ else {
594
+ retVal = true;
595
+ }
596
+ });
597
+ return retVal;
598
+ }
599
+ /**
600
+ * Change number of dots for note, chord or rest
601
+ * @param dots
602
+ * @returns
603
+ */
604
+ setMarkedNoteDots(dots) {
605
+ var retVal = false;
606
+ var markedElements = this.vrvSVG.querySelectorAll(".note.marked, .rest.marked");
607
+ markedElements.forEach(m => {
608
+ var currMeiClone = this.currentMEI.cloneNode(true);
609
+ var meiElement = this.currentMEI.getElementById(m.id);
610
+ var oldMeiElement = meiElement.cloneNode(true);
611
+ var newMeiElement;
612
+ if (meiElement.closest("chord") !== null) {
613
+ oldMeiElement = meiElement.closest("chord").cloneNode(true);
614
+ meiElement.closest("chord").setAttribute("dots", dots.toString());
615
+ newMeiElement = meiElement.closest("chord");
616
+ }
617
+ else {
618
+ oldMeiElement = meiElement.cloneNode(true);
619
+ meiElement.setAttribute("dots", dots.toString());
620
+ newMeiElement = meiElement;
621
+ }
622
+ oldMeiElement.replaceWith(newMeiElement);
623
+ this.currentMEI = meiOperation.fillWithRests(newMeiElement, oldMeiElement, this.currentMEI);
624
+ //if(this.currentMEI.querySelectorAll(".changed").length === 0){
625
+ var additionalElements = Array.from(newMeiElement.closest("layer").querySelectorAll("*[dur]"));
626
+ additionalElements = additionalElements.filter((v, i) => i > additionalElements.indexOf(newMeiElement));
627
+ //this.currentMEI = meiOperation.changeDuration(this.currentMEI, "reduce", additionalElements)
628
+ //additionalElements.unshift(oldMeiElement) // we need this information to determine the new duration of an element that has to be shortened
629
+ this.currentMEI = meiOperation.changeDurationsInLayer(this.currentMEI, additionalElements, newMeiElement, meiOperation.getAbsoluteRatio(newMeiElement) - meiOperation.getAbsoluteRatio(oldMeiElement)); //this.currentMEI = meiOperation.changeDuration(this.currentMEI, additionalElements)
630
+ //}
631
+ this.currentMEI.querySelectorAll(".changed").forEach(c => c.classList.remove("changed"));
632
+ if (meiOperation.elementIsOverfilling(meiElement, currMeiClone)) {
633
+ this.currentMEI = currMeiClone;
634
+ }
635
+ else {
636
+ retVal = true;
637
+ }
638
+ });
639
+ return retVal;
640
+ }
641
+ getElementinVrvSVG(id) {
642
+ if (id !== "" && id !== null) {
643
+ return this.vrvSVG.querySelector("#" + id);
644
+ }
645
+ return;
646
+ }
647
+ getElementInInteractOverlay(id) {
648
+ if (id !== "" && id !== null) {
649
+ return this.interactionOverlay.querySelector("#" + id);
650
+ }
651
+ return;
652
+ }
653
+ setDotsNewNote(dots) {
654
+ this.noteNewDots = dots.toString();
655
+ }
656
+ setCurrentMEI(xmlDoc) {
657
+ var _a;
658
+ this.currentMEI = xmlDoc;
659
+ if (((_a = this.noteBBoxes) === null || _a === void 0 ? void 0 : _a.length) === 0) {
660
+ this.findBBoxes();
661
+ }
662
+ return this;
663
+ }
664
+ setContainerId(id) {
665
+ this.containerId = id;
666
+ this.interactionOverlay = cq.getInteractOverlay(id);
667
+ this.vrvSVG = cq.getVrvSVG(id);
668
+ this.container = document.getElementById(id);
669
+ return this;
670
+ }
671
+ getCurrentMei() {
672
+ return this.currentMEI;
673
+ }
674
+ getMeasureMatrix() {
675
+ return this.measureMatrix;
676
+ }
677
+ getDurationNewNote() {
678
+ var dur;
679
+ var selEl = this.container.querySelector("#noteGroup .selected");
680
+ if (selEl === null) {
681
+ return "4";
682
+ }
683
+ switch (selEl.id) {
684
+ case "fullNote":
685
+ dur = 1;
686
+ break;
687
+ case "halfNote":
688
+ dur = 2;
689
+ break;
690
+ case "quarterNote":
691
+ dur = 4;
692
+ break;
693
+ case "eigthNote":
694
+ dur = 8;
695
+ break;
696
+ case "sixteenthNote":
697
+ dur = 16;
698
+ break;
699
+ case "thirtysecondNote":
700
+ dur = 32;
701
+ break;
702
+ }
703
+ return dur.toString(); //this.noteNewDur
704
+ }
705
+ getDotsNewNote() {
706
+ var dots;
707
+ var selEl = this.container.querySelector("#dotGroup .selected");
708
+ if (selEl === null) {
709
+ return "0";
710
+ }
711
+ switch (selEl.id) {
712
+ case "oneDot":
713
+ dots = "1";
714
+ break;
715
+ case "twoDot":
716
+ dots = "2";
717
+ break;
718
+ }
719
+ return dots;
720
+ }
721
+ getLineDist() {
722
+ return this.lineDist;
723
+ }
724
+ update() {
725
+ this.noteBBoxes.length = 0;
726
+ this.staffLineBBoxes.length = 0;
727
+ //this.updateOverlayCallback()
728
+ this.findBBoxes();
729
+ this.setMouseEnterElementListeners();
730
+ return this;
731
+ }
732
+ setUpdateOverlayCallback(updateOverlayCallback) {
733
+ this.updateOverlayCallback = updateOverlayCallback;
734
+ return this;
735
+ }
736
+ }
737
+ exports.Mouse2SVG = Mouse2SVG;