@onjmin/dtm 0.1.11 → 0.1.13

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.
package/dist/index.js CHANGED
@@ -1209,6 +1209,9 @@ var ICONS = {
1209
1209
  settings: {
1210
1210
  d: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065zM15 12a3 3 0 11-6 0 3 3 0 016 0z",
1211
1211
  stroke: true
1212
+ },
1213
+ info: {
1214
+ d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"
1212
1215
  }
1213
1216
  };
1214
1217
  var icon = (name, size = 20) => {
@@ -1319,19 +1322,32 @@ var buildUI = (target, options) => {
1319
1322
  <summary>MIDI / MML \u5165\u529B</summary>
1320
1323
  <div class="dtm-panel-body">
1321
1324
  <div class="dtm-row">
1322
- <span class="dtm-label">MIDI</span>
1325
+ <div style="display: inline-flex; flex-direction: column; align-items: center; gap: 4px; justify-content: center; min-width: 48px;">
1326
+ <span class="dtm-label" style="line-height: 1;">MIDI</span>
1327
+ <button class="dtm-infobtn" data-dtm="midi-info" title="MIDI\u306E\u8AAD\u307F\u8FBC\u307F\u89E3\u8AAC">${icon("info", 12)}</button>
1328
+ </div>
1323
1329
  <input type="file" class="dtm-input dtm-grow" accept=".mid,.midi" data-dtm="midi-input">
1324
1330
  <button class="dtm-btn dtm-btn--success" data-dtm="midi-load">\u8AAD\u8FBC</button>
1325
1331
  </div>
1326
1332
  <div class="dtm-row dtm-hidden" data-dtm="midi-track-selection"></div>
1327
1333
  <div class="dtm-row">
1328
- <span class="dtm-label">MML</span>
1334
+ <div style="display: inline-flex; flex-direction: column; align-items: center; gap: 4px; justify-content: center; min-width: 48px;">
1335
+ <span class="dtm-label" style="line-height: 1;">MML</span>
1336
+ <button class="dtm-infobtn" data-dtm="mml-info" title="MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC">${icon("info", 12)}</button>
1337
+ </div>
1329
1338
  <textarea class="dtm-textarea dtm-grow" data-dtm="mml-input" placeholder="MML\u3092\u5165\u529B"></textarea>
1330
1339
  <button class="dtm-btn dtm-btn--primary" data-dtm="mml-load">\u8AAD\u8FBC</button>
1331
1340
  </div>
1341
+ </div>
1342
+ </details>
1343
+
1344
+ <details class="dtm-panel">
1345
+ <summary>\u30DE\u30AF\u30ED</summary>
1346
+ <div class="dtm-panel-body">
1332
1347
  <div class="dtm-row">
1333
1348
  <span class="dtm-label">\u5168\u4F53\u30B7\u30D5\u30C8</span>
1334
1349
  <select class="dtm-select" data-dtm="shift-select">
1350
+ <option value="-192">-1\u5C0F\u7BC0</option>
1335
1351
  <option value="-96">-2\u5206</option>
1336
1352
  <option value="-48">-4\u5206</option>
1337
1353
  <option value="-24">-8\u5206</option>
@@ -1340,15 +1356,10 @@ var buildUI = (target, options) => {
1340
1356
  <option value="24">+8\u5206</option>
1341
1357
  <option value="48">+4\u5206</option>
1342
1358
  <option value="96">+2\u5206</option>
1359
+ <option value="192">+1\u5C0F\u7BC0</option>
1343
1360
  </select>
1344
1361
  <button class="dtm-btn dtm-btn--primary" data-dtm="shift-apply">\u9069\u7528</button>
1345
1362
  </div>
1346
- </div>
1347
- </details>
1348
-
1349
- <details class="dtm-panel">
1350
- <summary>\u30DE\u30AF\u30ED</summary>
1351
- <div class="dtm-panel-body">
1352
1363
  <div class="dtm-row">
1353
1364
  <button class="dtm-btn dtm-btn--danger" data-dtm="macro-clear">\u5168\u6D88\u53BB</button>
1354
1365
  <button class="dtm-btn dtm-btn--accent" data-dtm="macro-random">\u30E9\u30F3\u30C0\u30E0\u914D\u7F6E</button>
@@ -1398,6 +1409,17 @@ var buildUI = (target, options) => {
1398
1409
  </div>
1399
1410
  </div>
1400
1411
  </details>
1412
+
1413
+ <!-- \u2550\u2550\u2550\u2550 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2550\u2550\u2550\u2550 -->
1414
+ <div class="dtm-modal-overlay" data-dtm="modal-overlay" hidden>
1415
+ <div class="dtm-win dtm-modal">
1416
+ <div class="dtm-modal-header">
1417
+ <span class="dtm-modal-title" data-dtm="modal-title"></span>
1418
+ <button class="dtm-modal-close" data-dtm="modal-close">&times;</button>
1419
+ </div>
1420
+ <div class="dtm-modal-body" data-dtm="modal-body"></div>
1421
+ </div>
1422
+ </div>
1401
1423
  </div>`;
1402
1424
  const root = q(target, '[data-dtm="root"]');
1403
1425
  const sel = (name) => q(root, `[data-dtm="${name}"]`);
@@ -1436,6 +1458,7 @@ var buildUI = (target, options) => {
1436
1458
  drumVolumeLabel: sel("drum-volume-label"),
1437
1459
  midiInput: sel("midi-input"),
1438
1460
  midiLoadBtn: sel("midi-load"),
1461
+ midiInfoBtn: sel("midi-info"),
1439
1462
  midiTrackSelection: sel("midi-track-selection"),
1440
1463
  midiPanel: sel("midi-panel"),
1441
1464
  mmlInput: sel("mml-input"),
@@ -1457,7 +1480,12 @@ var buildUI = (target, options) => {
1457
1480
  outputMini: sel("output-mini"),
1458
1481
  copyFullBtn: sel("copy-full"),
1459
1482
  copyMiniBtn: sel("copy-mini"),
1460
- overlay: sel("overlay")
1483
+ overlay: sel("overlay"),
1484
+ mmlInfoBtn: sel("mml-info"),
1485
+ modalOverlay: sel("modal-overlay"),
1486
+ modalTitle: sel("modal-title"),
1487
+ modalBody: sel("modal-body"),
1488
+ modalClose: sel("modal-close")
1461
1489
  };
1462
1490
  };
1463
1491
 
@@ -2864,7 +2892,7 @@ var analyzeMidiTracks = (midi) => {
2864
2892
  currentTime += event.deltaTime;
2865
2893
  const data = event.data;
2866
2894
  if (event.type === 9 && data && data[1]) {
2867
- notes.push({ pitch: data[0] });
2895
+ notes.push({ pitch: data[0], channel: event.channel ?? 0 });
2868
2896
  } else if (event.type === 8) {
2869
2897
  for (let k = notes.length - 1; k >= 0; k--) {
2870
2898
  if (notes[k].pitch === data[0] && notes[k].end === void 0) {
@@ -2875,11 +2903,13 @@ var analyzeMidiTracks = (midi) => {
2875
2903
  }
2876
2904
  }
2877
2905
  const validNotes = notes.filter((n) => n.end !== void 0);
2906
+ const editableNotes = validNotes.filter((n) => n.channel !== 9);
2907
+ if (validNotes.length > 0 && editableNotes.length === 0) continue;
2878
2908
  result.push({
2879
2909
  index: i,
2880
- name: `Ch${i}`,
2881
- noteCount: validNotes.length,
2882
- selected: validNotes.length > 0
2910
+ name: `Ch${i + 1}`,
2911
+ noteCount: editableNotes.length,
2912
+ selected: editableNotes.length > 0
2883
2913
  });
2884
2914
  }
2885
2915
  return result;
@@ -4860,6 +4890,128 @@ var DAW_CSS = `
4860
4890
  @keyframes dtm-blink { 0%,100%{opacity:1} 50%{opacity:0} }
4861
4891
  .dtm-blink { animation: dtm-blink 1s steps(1) infinite; }
4862
4892
 
4893
+ /* \u2500\u2500\u2500 \u30A4\u30F3\u30D5\u30A9\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */
4894
+ .dtm-infobtn {
4895
+ display: inline-flex;
4896
+ align-items: center;
4897
+ justify-content: center;
4898
+ width: 20px;
4899
+ height: 20px;
4900
+ flex: 0 0 auto;
4901
+ border: 2px solid var(--dtm-border2);
4902
+ background: var(--dtm-surface);
4903
+ color: var(--dtm-muted);
4904
+ cursor: pointer;
4905
+ box-shadow: 1px 1px 0 var(--c-black);
4906
+ padding: 0;
4907
+ margin: 0;
4908
+ }
4909
+ .dtm-infobtn:hover {
4910
+ color: var(--dtm-primary);
4911
+ border-color: var(--dtm-primary);
4912
+ }
4913
+ .dtm-infobtn:active {
4914
+ transform: translate(1px, 1px);
4915
+ box-shadow: none;
4916
+ }
4917
+
4918
+ /* \u2500\u2500\u2500 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2500\u2500\u2500 */
4919
+ .dtm-modal-overlay {
4920
+ position: fixed;
4921
+ inset: 0;
4922
+ z-index: 10000;
4923
+ background: rgba(0, 0, 0, 0.7);
4924
+ display: flex;
4925
+ align-items: center;
4926
+ justify-content: center;
4927
+ padding: 16px;
4928
+ backdrop-filter: blur(2px);
4929
+ }
4930
+ .dtm-modal-overlay[hidden] {
4931
+ display: none !important;
4932
+ }
4933
+ .dtm-modal {
4934
+ max-width: 500px;
4935
+ width: 100%;
4936
+ max-height: 80vh;
4937
+ display: flex;
4938
+ flex-direction: column;
4939
+ background: var(--dtm-surface);
4940
+ border: 2px solid var(--c-black);
4941
+ box-shadow:
4942
+ inset 0 0 0 2px var(--c-black),
4943
+ 0 0 0 2px var(--dtm-primary),
4944
+ 4px 4px 0 var(--c-black);
4945
+ overflow: hidden;
4946
+ }
4947
+ .dtm-modal-header {
4948
+ display: flex;
4949
+ align-items: center;
4950
+ justify-content: space-between;
4951
+ background: var(--dtm-deep);
4952
+ padding: 8px 12px;
4953
+ border-bottom: 2px solid var(--c-black);
4954
+ }
4955
+ .dtm-modal-title {
4956
+ font-family: var(--dtm-font);
4957
+ font-size: 14px;
4958
+ color: var(--dtm-gold);
4959
+ font-weight: bold;
4960
+ }
4961
+ .dtm-modal-close {
4962
+ background: transparent;
4963
+ border: none;
4964
+ color: var(--dtm-text);
4965
+ font-size: 20px;
4966
+ cursor: pointer;
4967
+ padding: 0;
4968
+ line-height: 1;
4969
+ }
4970
+ .dtm-modal-close:hover {
4971
+ color: var(--dtm-danger);
4972
+ }
4973
+ .dtm-modal-body {
4974
+ padding: 12px;
4975
+ overflow-y: auto;
4976
+ font-size: 13px;
4977
+ line-height: 1.6;
4978
+ }
4979
+ .dtm-modal-body h4 {
4980
+ margin: 12px 0 6px 0;
4981
+ color: var(--dtm-primary);
4982
+ font-size: 13px;
4983
+ }
4984
+ .dtm-modal-body h4:first-child {
4985
+ margin-top: 0;
4986
+ }
4987
+ .dtm-modal-body p {
4988
+ margin: 0 0 8px 0;
4989
+ }
4990
+ .dtm-modal-body ul {
4991
+ margin: 0 0 8px 0;
4992
+ padding-left: 16px;
4993
+ }
4994
+ .dtm-modal-body li {
4995
+ margin-bottom: 4px;
4996
+ }
4997
+ .dtm-modal-body code {
4998
+ background: var(--dtm-deep);
4999
+ color: var(--dtm-accent);
5000
+ padding: 1px 4px;
5001
+ font-family: var(--dtm-font);
5002
+ font-size: 12px;
5003
+ }
5004
+ .dtm-modal-body pre {
5005
+ background: var(--dtm-deep);
5006
+ color: var(--dtm-success);
5007
+ padding: 8px;
5008
+ border: 1px solid var(--dtm-border2);
5009
+ margin: 6px 0;
5010
+ overflow-x: auto;
5011
+ font-family: var(--dtm-font);
5012
+ font-size: 12px;
5013
+ }
5014
+
4863
5015
  .dtm-hidden { display: none !important; }
4864
5016
  .dtm-grow { flex: 1 1 auto; }
4865
5017
  .dtm-lyric-icon {
@@ -5129,6 +5281,118 @@ var VOICE_IMAGES = {
5129
5281
  };
5130
5282
 
5131
5283
  // src/daw.ts
5284
+ var CHORD_INFO_HTML = `
5285
+ <div class="dtm-modal-body-content">
5286
+ <h4>1. \u57FA\u672C\u306E\u66F8\u304D\u65B9</h4>
5287
+ <p>\u30B3\u30FC\u30C9\u540D\uFF08\u548C\u97F3\u8A18\u53F7\uFF09\u3092\u7E26\u7DDA <code>|</code>\u3001\u30B9\u30DA\u30FC\u30B9\u3001\u307E\u305F\u306F\u30AB\u30F3\u30DE\u3067\u533A\u5207\u3063\u3066\u5165\u529B\u3057\u307E\u3059\u3002\u7E26\u7DDA\u3067\u533A\u5207\u308B\u30681\u5C0F\u7BC0\u3054\u3068\u306E\u914D\u7F6E\u306B\u306A\u308A\u307E\u3059\u3002</p>
5288
+ <pre>\u4F8B: C | G | Am | F</pre>
5289
+ <p style="margin-top:4px;"><small>\u30B3\u30FC\u30C9\u9032\u884C\u3092\u81EA\u5206\u3067\u8003\u3048\u308B\u306E\u304C\u96E3\u3057\u3044\u3068\u304D\u306F\u3001\u30B3\u30FC\u30C9\u9032\u884C\u306E\u5171\u6709\u30B5\u30A4\u30C8\uFF08\u4F8B: <a href="https://rechord.cc/scores" target="_blank" rel="noopener">rechord.cc</a>\uFF09\u304B\u3089\u597D\u304D\u306A\u9032\u884C\u3092\u63A2\u3057\u3066\u30B3\u30D4\u30DA\u3059\u308B\u306E\u3082\u624B\u3067\u3059\u3002\u533A\u5207\u308A\u6587\u5B57\uFF08<code>|</code> / \u30B9\u30DA\u30FC\u30B9 / \u30AB\u30F3\u30DE\uFF09\u3060\u3051\u4E0A\u306E\u5F62\u5F0F\u306B\u5408\u308F\u305B\u308C\u3070\u3001\u305D\u306E\u307E\u307E\u4F7F\u3048\u307E\u3059\u3002</small></p>
5290
+
5291
+ <h4>2. 1\u5C0F\u7BC0\u306B\u8907\u6570\u30B3\u30FC\u30C9\u3092\u5165\u308C\u308B</h4>
5292
+ <p>\u5C0F\u7BC0\u306E\u533A\u5207\u308A\uFF08\u7E26\u7DDA <code>|</code>\uFF09\u306E\u4E2D\u306B\u3001\u30B9\u30DA\u30FC\u30B9\u533A\u5207\u308A\u3067\u30B3\u30FC\u30C9\u3092\u4E26\u3079\u307E\u3059\u3002\u7B49\u9593\u9694\u306B\u914D\u7F6E\u3055\u308C\u307E\u3059\u3002</p>
5293
+ <pre>\u4F8B: C G | Am F</pre>
5294
+ <p style="margin-top:4px;"><small>\uFF081\u5C0F\u7BC0\u76EE\uFF1A\u524D\u534AC\u30FB\u5F8C\u534AG\u30012\u5C0F\u7BC0\u76EE\uFF1A\u524D\u534AAm\u30FB\u5F8C\u534AF\uFF09</small></p>
5295
+
5296
+ <h4>3. \u5BFE\u5FDC\u30B3\u30FC\u30C9\u540D</h4>
5297
+ <ul>
5298
+ <li>\u30E1\u30B8\u30E3\u30FC / \u30DE\u30A4\u30CA\u30FC: <code>C</code>, <code>Dm</code>, <code>Am</code> \u306A\u3069</li>
5299
+ <li>\u30BB\u30D6\u30F3\u30B9: <code>C7</code>, <code>Am7</code>, <code>FM7</code> \u306A\u3069</li>
5300
+ <li>\u305D\u306E\u4ED6: <code>Csus4</code>, <code>Cdim</code>, <code>Caug</code>, <code>Cadd9</code> \u306A\u3069</li>
5301
+ </ul>
5302
+
5303
+ <h4>4. \u6F14\u594F\u30D1\u30BF\u30FC\u30F3</h4>
5304
+ <ul>
5305
+ <li><strong>\u30D6\u30ED\u30C3\u30AF</strong>: \u548C\u97F3\u306E\u69CB\u6210\u97F3\u3092\u3059\u3079\u3066\u540C\u6642\u306B\u4F38\u3070\u3057\u3066\u6F14\u594F\u3057\u307E\u3059\u3002</li>
5306
+ <li><strong>\u30A2\u30EB\u30DA\u30B8\u30AA</strong>: \u548C\u97F3\u306E\u69CB\u6210\u97F3\u3092\u4F4E\u3044\u9806\u306B\u5206\u6563\u3057\u3066\u6F14\u594F\u3057\u307E\u3059\u3002</li>
5307
+ <li><strong>\u30A2\u30EB\u30DA\u30B8\u30AA\uFF08\u30B8\u30E3\u30E9\u30FC\u30F3\uFF09</strong>: \u7D20\u65E9\u304F\u30A2\u30EB\u30DA\u30B8\u30AA\u3092\u9CF4\u3089\u3057\u307E\u3059\u3002</li>
5308
+ <li><strong>\u88CF\u6253\u3061</strong>: \u5404\u62CD\u306E\u88CF\uFF088\u5206\u88CF\uFF09\u306E\u30BF\u30A4\u30DF\u30F3\u30B0\u3067\u30B3\u30FC\u30C9\u3092\u523B\u307F\u307E\u3059\u3002</li>
5309
+ <li><strong>\u30E4\u30C4\u30E1\u7A74</strong>: \u30EA\u30BA\u30DF\u30AB\u30EB\u306A\u30D4\u30B3\u30D4\u30B3\u30B2\u30FC\u30E0\u98A8\u306E\u4F34\u594F\u30D1\u30BF\u30FC\u30F3\u3067\u3059\u3002</li>
5310
+ <li><strong>\u4EA4\u4E92\u594F</strong>: \u30EB\u30FC\u30C8\u97F3\uFF08\u4F4E\u97F3\uFF09\u3068\u30B3\u30FC\u30C9\u69CB\u6210\u97F3\uFF08\u9AD8\u97F3\uFF09\u3092\u4EA4\u4E92\u306B\u523B\u307F\u307E\u3059\u3002</li>
5311
+ </ul>
5312
+ </div>
5313
+ `;
5314
+ var MML_INFO_HTML = `
5315
+ <div class="dtm-modal-body-content">
5316
+ <h4>1. \u97F3\u7B26\u3068\u4F11\u7B26</h4>
5317
+ <p><code>c</code>(\u30C9) <code>d</code>(\u30EC) <code>e</code>(\u30DF) <code>f</code>(\u30D5\u30A1) <code>g</code>(\u30BD) <code>a</code>(\u30E9) <code>b</code>(\u30B7) \u306E\u30A2\u30EB\u30D5\u30A1\u30D9\u30C3\u30C8\u3067\u8868\u3057\u307E\u3059\u3002</p>
5318
+ <ul>
5319
+ <li>\u534A\u97F3\u4E0A\u3052\u308B: <code>c#</code> \u307E\u305F\u306F <code>c+</code></li>
5320
+ <li>\u534A\u97F3\u4E0B\u3052\u308B: <code>d-</code></li>
5321
+ <li>\u4F11\u7B26: <code>r</code></li>
5322
+ </ul>
5323
+
5324
+ <h4>2. \u97F3\u306E\u9577\u3055</h4>
5325
+ <p>\u97F3\u540D\u3084\u4F11\u7B26\u306E\u5F8C\u306B\u6570\u5024\u3067\u6307\u5B9A\u3057\u307E\u3059\uFF08\u4F8B: <code>4</code> = 4\u5206\u97F3\u7B26, <code>8</code> = 8\u5206\u97F3\u7B26, <code>16</code> = 16\u5206\u97F3\u7B26\uFF09\u3002</p>
5326
+ <ul>
5327
+ <li><code>c4</code> : 4\u5206\u97F3\u7B26\u306E\u30C9</li>
5328
+ <li><code>r8</code> : 8\u5206\u4F11\u7B26</li>
5329
+ <li><code>c4.</code> : \u4ED8\u70B94\u5206\u97F3\u7B26\u306E\u30C9\uFF08\u9577\u3055\u30921.5\u500D\u306B\uFF09</li>
5330
+ <li>\u6570\u5024\u3092\u7701\u7565\u3059\u308B\u3068\u3001<code>l</code> \u30B3\u30DE\u30F3\u30C9\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u30C7\u30D5\u30A9\u30EB\u30C8\u9577\uFF08\u901A\u5E3816\u5206\uFF09\u306B\u306A\u308A\u307E\u3059\u3002</li>
5331
+ </ul>
5332
+
5333
+ <h4>3. \u30AA\u30AF\u30BF\u30FC\u30D6\uFF08\u97F3\u306E\u9AD8\u3055\uFF09</h4>
5334
+ <ul>
5335
+ <li><code>o4</code>, <code>o5</code> : \u9AD8\u3055\u3092\u76F4\u63A5\u6307\u5B9A\uFF08\u3075\u3064\u3046\u306F o4 \u304B o5\uFF09</li>
5336
+ <li><code>&gt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u308B</li>
5337
+ <li><code>&lt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0B\u3052\u308B</li>
5338
+ </ul>
5339
+
5340
+ <h4>4. \u30C6\u30F3\u30DD</h4>
5341
+ <ul>
5342
+ <li><code>t120</code> : \u66F2\u306E\u901F\u3055\u3092BPM120\u306B\u6307\u5B9A\u3002\u203B\u30E1\u30ED\u30C7\u30A3\uFF08@0\uFF09\u306E\u30C6\u30F3\u30DD\u6307\u5B9A\u304C\u66F2\u5168\u4F53\u306B\u53CD\u6620\u3055\u308C\u307E\u3059\u3002</li>
5343
+ </ul>
5344
+
5345
+ <h4>5. \u548C\u97F3</h4>
5346
+ <p>\u97F3\u7B26\u3092 <code>[</code> \u3068 <code>]</code> \u3067\u56F2\u3080\u3068\u540C\u6642\u306B\u767A\u97F3\u3057\u307E\u3059\u3002</p>
5347
+ <pre>\u4F8B: [ceg]4 \uFF08\u30C9\u30FB\u30DF\u30FB\u30BD\u30924\u5206\u97F3\u7B26\u3067\u540C\u6642\u306B\u767A\u97F3\uFF09</pre>
5348
+
5349
+ <h4>6. \u30C8\u30E9\u30C3\u30AF\u306E\u533A\u5207\u308A</h4>
5350
+ <p><code>;</code> \u307E\u305F\u306F <code>@0</code>\u301C<code>@3</code> \u3067\u30C8\u30E9\u30C3\u30AF\u3092\u5207\u308A\u66FF\u3048\u307E\u3059\u3002</p>
5351
+ <ul>
5352
+ <li><code>@0</code>: \u30E1\u30ED\u30C7\u30A3</li>
5353
+ <li><code>@1</code>: \u30B5\u30D6\u30E1\u30ED</li>
5354
+ <li><code>@2</code>: \u30D9\u30FC\u30B9</li>
5355
+ <li><code>@3</code>: \u4F34\u594F</li>
5356
+ </ul>
5357
+
5358
+ <h4>7. \u6B4C\u58F0\u30FB\u6B4C\u8A5E\u5165\u529B</h4>
5359
+ <p><code>@@&lt;\u30C8\u30E9\u30C3\u30AF\u756A\u53F7&gt; &lt;\u97F3\u6E90\u540D&gt; &lt;\u6B4C\u8A5E&gt;</code> \u306E\u5F62\u5F0F\u3067\u3001\u97F3\u7B26\u3068\u540C\u671F\u3059\u308B\u6B4C\u8A5E\u3092\u5165\u529B\u3067\u304D\u307E\u3059\u3002</p>
5360
+ <pre>\u4F8B: @@0 klatt \u3061\u3087\u3046\u3061\u3087\u3046\u306A\u306E\u306F\u306B\u3068\u307E\u308C</pre>
5361
+ <p style="margin-top:4px;"><small>\uFF08\u97F3\u6E90\u540D\u306F <code>klatt</code> \u3084 <code>roze</code>, <code>teto</code> \u306A\u3069\u306E\u97F3\u58F0\u30E2\u30C7\u30EB\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\uFF09</small></p>
5362
+ </div>
5363
+ `;
5364
+ var MIDI_INFO_HTML = `
5365
+ <div class="dtm-modal-body-content">
5366
+ <h4>1. MIDI\u30D5\u30A1\u30A4\u30EB\u3068\u306F</h4>
5367
+ <p>\u300C\u3069\u306E\u97F3\u3092\u30FB\u3044\u3064\u30FB\u3069\u306E\u304F\u3089\u3044\u306E\u9577\u3055\u3067\u9CF4\u3089\u3059\u304B\u300D\u3092\u8A18\u9332\u3057\u305F\u3001\u6F14\u594F\u30C7\u30FC\u30BF\u306E\u30D5\u30A1\u30A4\u30EB\uFF08\u62E1\u5F35\u5B50 <code>.mid</code> / <code>.midi</code>\uFF09\u3067\u3059\u3002\u97F3\u305D\u306E\u3082\u306E\u3067\u306F\u306A\u304F\u697D\u8B5C\u306B\u8FD1\u3044\u30C7\u30FC\u30BF\u306A\u306E\u3067\u3001\u8AAD\u307F\u8FBC\u3093\u3067\u305D\u306E\u307E\u307E\u7DE8\u96C6\u3067\u304D\u307E\u3059\u3002</p>
5368
+
5369
+ <h4>2. \u8AAD\u307F\u8FBC\u307F\u306E\u3057\u304B\u305F</h4>
5370
+ <ul>
5371
+ <li>\u300C\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E\u300D\u304B\u3089 <code>.mid</code> \u30D5\u30A1\u30A4\u30EB\u3092\u9078\u3073\u307E\u3059\u3002</li>
5372
+ <li>\u30D5\u30A1\u30A4\u30EB\u5185\u306E\u30C8\u30E9\u30C3\u30AF\u4E00\u89A7\u304C\u51FA\u308B\u306E\u3067\u3001\u53D6\u308A\u8FBC\u307F\u305F\u3044\u30C8\u30E9\u30C3\u30AF\u3092\u9078\u3073\u307E\u3059\u3002</li>
5373
+ <li>\u300C\u8AAD\u8FBC\u300D\u3092\u62BC\u3059\u3068\u53CD\u6620\u3055\u308C\u307E\u3059\u3002</li>
5374
+ </ul>
5375
+
5376
+ <h4>3. \u30E2\u30FC\u30C9\u306B\u3088\u308B\u53D6\u308A\u8FBC\u307F\u65B9\u306E\u9055\u3044</h4>
5377
+ <ul>
5378
+ <li><strong>SIMPLE</strong>: \u5404\u30C8\u30E9\u30C3\u30AF\u306E\u7279\u5FB4\u304B\u3089\u3001\u30E1\u30ED\u30C7\u30A3\u30FC\u30FB\u30B5\u30D6\u30E1\u30ED\u30FB\u30D9\u30FC\u30B9\u30FB\u4F34\u594F\u306E4\u3064\u306E\u5F79\u5272\u306B\u81EA\u52D5\u3067\u632F\u308A\u5206\u3051\u3089\u308C\u307E\u3059\u3002</li>
5379
+ <li><strong>ADVANCED</strong>: MIDI\u306E\u30C8\u30E9\u30C3\u30AF\u69CB\u6210\u304C\u305D\u306E\u307E\u307E\u53CD\u6620\u3055\u308C\u307E\u3059\uFF081\u5BFE1\uFF09\u3002</li>
5380
+ </ul>
5381
+
5382
+ <h4>4. MIDI\u30D5\u30A1\u30A4\u30EB\u3092\u624B\u306B\u5165\u308C\u308B</h4>
5383
+ <p>\u624B\u5143\u306BMIDI\u304C\u7121\u3044\u3068\u304D\u306F\u3001\u300C<code>\u66F2\u540D midi</code>\u300D\u306A\u3069\u3067\u691C\u7D22\u3059\u308C\u3070\u3001\u7121\u6599\u3067\u914D\u5E03\u3057\u3066\u3044\u308B\u30B5\u30A4\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u3059\u3002</p>
5384
+ <p style="margin-top:4px;"><small>\u307F\u3093\u306A\u304CMIDI\u3092\u6295\u7A3F\u3067\u304D\u308B\u6295\u7A3F\u578B\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0: <a href="http://picotune.me/" target="_blank" rel="noopener">picotune.me</a>\uFF08\u3044\u308D\u3093\u306A\u30B8\u30E3\u30F3\u30EB\u306EMIDI\u3092\u7121\u6599\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3067\u304D\u307E\u3059\u3002\u30B5\u30A4\u30C8\u4E0A\u3067\u306F\u30C1\u30C3\u30D7\u30C1\u30E5\u30FC\u30F3\u98A8\u306B\u518D\u751F\u3055\u308C\u307E\u3059\uFF09</small></p>
5385
+ <p style="margin-top:4px;"><small>\u203B\u691C\u7D22\u3067\u898B\u3064\u304B\u308B\u914D\u5E03\u30B5\u30A4\u30C8\u306F\u3001\u500B\u4EBA\u904B\u55B6\u306E\u3082\u306E\u304B\u3089\u6A29\u5229\u7684\u306B\u30B0\u30EC\u30FC\u306A\u3082\u306E\u307E\u3067\u69D8\u3005\u3067\u3059\u3002\u305D\u306E\u305F\u3081\u3001\u305D\u308C\u3089\u3078\u306E\u76F4\u63A5\u30EA\u30F3\u30AF\u306F\u8F09\u305B\u3066\u3044\u307E\u305B\u3093\u3002\u5229\u7528\u306E\u969B\u306F\u914D\u5E03\u5143\u3084\u6A29\u5229\u95A2\u4FC2\u3092\u3054\u81EA\u8EAB\u3067\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044\u3002</small></p>
5386
+
5387
+ <h4>5. UST\uFF08UTAU\uFF09\u306E\u6B4C\u8A5E\u3092\u4F7F\u3046</h4>
5388
+ <p>UTAU\u306EUST\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6B4C\u8A5E\u3060\u3051\u3092\u53D6\u308A\u51FA\u3057\u3066\u3001\u6B4C\u308F\u305B\u308B\u3053\u3068\u3082\u3067\u304D\u307E\u3059\u3002</p>
5389
+ <ul>
5390
+ <li>\u97F3\u7B26: UTAU\u306A\u3069\u3067UST\u3092MIDI\u306B\u66F8\u304D\u51FA\u3057\u3001\u4E0A\u306E\u624B\u9806\u3067\u8AAD\u307F\u8FBC\u307F\u307E\u3059\u3002</li>
5391
+ <li>\u6B4C\u8A5E: \u4E0B\u8A18\u30B5\u30A4\u30C8\u3067UST\u304B\u3089\u6B4C\u8A5E\u30C6\u30AD\u30B9\u30C8\u3092\u629C\u304D\u51FA\u3057\u3001MML/\u6B4C\u8A5E\u5165\u529B\u6B04\u306E <code>@@</code> \u69CB\u6587\u306B\u8CBC\u308A\u4ED8\u3051\u307E\u3059\u3002</li>
5392
+ </ul>
5393
+ <p style="margin-top:4px;"><small>\u6B4C\u8A5E\u306E\u62BD\u51FA: <a href="https://rpgen3.github.io/ust2txt/" target="_blank" rel="noopener">ust2txt</a></small></p>
5394
+ </div>
5395
+ `;
5132
5396
  var BASE_STEP_WIDTH = 0.5;
5133
5397
  var BASE_KEY_HEIGHT = 15;
5134
5398
  var TRACKS_SIMPLE = [
@@ -5287,9 +5551,11 @@ var mountDAW = (target, options = {}) => {
5287
5551
  injectStyles();
5288
5552
  const getAudioTime = options.getAudioTime ?? (() => performance.now() / 1e3);
5289
5553
  const trackConfigs = options.tracks ?? DEFAULT_TRACKS;
5554
+ const mode = options.mode ?? (trackConfigs.length > TRACKS_SIMPLE.length ? "advanced" : "simple");
5555
+ const isAdvanced = mode === "advanced";
5290
5556
  const drumPatterns = options.drumPatterns ?? DRUM_PATTERNS;
5291
5557
  const showMidi = !!options.parseMidi;
5292
- const showChord = true;
5558
+ const showChord = !isAdvanced;
5293
5559
  const refs = buildUI(target, {
5294
5560
  tracks: trackConfigs,
5295
5561
  drumPatternNames: Object.keys(drumPatterns),
@@ -5381,6 +5647,7 @@ var mountDAW = (target, options = {}) => {
5381
5647
  return map;
5382
5648
  };
5383
5649
  const getActive = () => trackStates.find((t) => t.config.id === activeTrackId) ?? trackStates[0];
5650
+ let showModal;
5384
5651
  const getMaxNoteStep = () => {
5385
5652
  let maxStep = renderConfig.stepsPerBar * 4;
5386
5653
  for (const t of trackStates) {
@@ -6073,11 +6340,12 @@ var mountDAW = (target, options = {}) => {
6073
6340
  active.core.setVolume(active.volume);
6074
6341
  volLabel.textContent = String(active.volume);
6075
6342
  });
6076
- const lyricDiv = document.createElement("div");
6077
- lyricDiv.className = "dtm-row";
6078
- lyricDiv.style.flexDirection = "column";
6079
- lyricDiv.style.alignItems = "stretch";
6080
- lyricDiv.innerHTML = `
6343
+ if (isAdvanced || active.config.id !== "chord") {
6344
+ const lyricDiv = document.createElement("div");
6345
+ lyricDiv.className = "dtm-row";
6346
+ lyricDiv.style.flexDirection = "column";
6347
+ lyricDiv.style.alignItems = "stretch";
6348
+ lyricDiv.innerHTML = `
6081
6349
  <div class="dtm-row">
6082
6350
  <span class="dtm-label">\u266A \u6B4C\u8A5E</span>
6083
6351
  <select class="dtm-select" data-dtm="lyric-model" aria-label="\u6B4C\u5531\u30E2\u30C7\u30EB"></select>
@@ -6109,144 +6377,134 @@ var mountDAW = (target, options = {}) => {
6109
6377
  </div>
6110
6378
  <textarea class="dtm-textarea" data-dtm="lyric-input" rows="2" placeholder="\u3072\u3089\u304C\u306A\u30FB\u30AB\u30BF\u30AB\u30CA\u3067\u6B4C\u8A5E\uFF08\u4F8B: \u3069\u308C\u307F\u3075\u3041\u305D\u3089\u3057\u3069\uFF09"></textarea>
6111
6379
  </div>`;
6112
- refs.trackBody.appendChild(lyricDiv);
6113
- const lyricModelSel = lyricDiv.querySelector(
6114
- '[data-dtm="lyric-model"]'
6115
- );
6116
- const lyricOctaveSel = lyricDiv.querySelector(
6117
- '[data-dtm="lyric-octave"]'
6118
- );
6119
- const lyricIcon = lyricDiv.querySelector(
6120
- '[data-dtm="lyric-icon"]'
6121
- );
6122
- const lyricBody = lyricDiv.querySelector(
6123
- '[data-dtm="lyric-body"]'
6124
- );
6125
- const lyricInput = lyricDiv.querySelector(
6126
- '[data-dtm="lyric-input"]'
6127
- );
6128
- const lyricCount = lyricDiv.querySelector(
6129
- '[data-dtm="lyric-count"]'
6130
- );
6131
- const lyricVol = lyricDiv.querySelector(
6132
- '[data-dtm="lyric-vol"]'
6133
- );
6134
- const lyricVolLabel = lyricDiv.querySelector(
6135
- '[data-dtm="lyric-vol-label"]'
6136
- );
6137
- const lyricPan = lyricDiv.querySelector(
6138
- '[data-dtm="lyric-pan"]'
6139
- );
6140
- const lyricPanLabel = lyricDiv.querySelector(
6141
- '[data-dtm="lyric-pan-label"]'
6142
- );
6143
- const lyricTerms = lyricDiv.querySelector(
6144
- '[data-dtm="lyric-terms"]'
6145
- );
6146
- const lyricTermsLink = lyricDiv.querySelector(
6147
- '[data-dtm="lyric-terms-link"]'
6148
- );
6149
- const fmtPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
6150
- const addOpt = (value, label) => {
6151
- const o = document.createElement("option");
6152
- o.value = value;
6153
- o.textContent = label;
6154
- lyricModelSel.appendChild(o);
6155
- };
6156
- addOpt("", "\u306A\u3057");
6157
- for (const m of LYRIC_MODELS) addOpt(m, lyricModelLabel(m));
6158
- if (active.lyricModel && !LYRIC_MODELS.includes(active.lyricModel)) {
6159
- addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
6160
- }
6161
- lyricModelSel.value = active.lyricModel;
6162
- lyricOctaveSel.value = String(active.vocalOctave);
6163
- lyricInput.value = active.lyrics;
6164
- lyricVol.value = String(active.vocalVolume);
6165
- lyricVolLabel.textContent = String(active.vocalVolume);
6166
- lyricPan.value = String(active.vocalPan);
6167
- lyricPanLabel.textContent = fmtPan(active.vocalPan);
6168
- const updateLyricCount = () => {
6169
- const n = normalizeLyrics(lyricInput.value).length;
6170
- lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
6171
- };
6172
- const syncLyricTerms = () => {
6173
- const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6174
- if (url) {
6175
- const label = lyricModelLabel(active.lyricModel);
6176
- lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
6177
- lyricTermsLink.href = url;
6178
- lyricTerms.classList.remove("dtm-hidden");
6179
- } else {
6180
- lyricTerms.classList.add("dtm-hidden");
6181
- }
6182
- };
6183
- const syncLyricIcon = () => {
6184
- const imgKey = active.lyricModel ? VOICE_IMAGE_KEY[active.lyricModel.toLowerCase()] : void 0;
6185
- const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
6186
- if (src) {
6187
- lyricIcon.src = src;
6188
- lyricIcon.classList.remove("dtm-hidden");
6189
- } else {
6190
- lyricIcon.removeAttribute("src");
6191
- lyricIcon.classList.add("dtm-hidden");
6380
+ refs.trackBody.appendChild(lyricDiv);
6381
+ const lyricModelSel = lyricDiv.querySelector(
6382
+ '[data-dtm="lyric-model"]'
6383
+ );
6384
+ const lyricOctaveSel = lyricDiv.querySelector(
6385
+ '[data-dtm="lyric-octave"]'
6386
+ );
6387
+ const lyricIcon = lyricDiv.querySelector(
6388
+ '[data-dtm="lyric-icon"]'
6389
+ );
6390
+ const lyricBody = lyricDiv.querySelector(
6391
+ '[data-dtm="lyric-body"]'
6392
+ );
6393
+ const lyricInput = lyricDiv.querySelector(
6394
+ '[data-dtm="lyric-input"]'
6395
+ );
6396
+ const lyricCount = lyricDiv.querySelector(
6397
+ '[data-dtm="lyric-count"]'
6398
+ );
6399
+ const lyricVol = lyricDiv.querySelector(
6400
+ '[data-dtm="lyric-vol"]'
6401
+ );
6402
+ const lyricVolLabel = lyricDiv.querySelector(
6403
+ '[data-dtm="lyric-vol-label"]'
6404
+ );
6405
+ const lyricPan = lyricDiv.querySelector(
6406
+ '[data-dtm="lyric-pan"]'
6407
+ );
6408
+ const lyricPanLabel = lyricDiv.querySelector(
6409
+ '[data-dtm="lyric-pan-label"]'
6410
+ );
6411
+ const lyricTerms = lyricDiv.querySelector(
6412
+ '[data-dtm="lyric-terms"]'
6413
+ );
6414
+ const lyricTermsLink = lyricDiv.querySelector(
6415
+ '[data-dtm="lyric-terms-link"]'
6416
+ );
6417
+ const fmtPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
6418
+ const addOpt = (value, label) => {
6419
+ const o = document.createElement("option");
6420
+ o.value = value;
6421
+ o.textContent = label;
6422
+ lyricModelSel.appendChild(o);
6423
+ };
6424
+ addOpt("", "\u306A\u3057");
6425
+ for (const m of LYRIC_MODELS) addOpt(m, lyricModelLabel(m));
6426
+ if (active.lyricModel && !LYRIC_MODELS.includes(active.lyricModel)) {
6427
+ addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
6192
6428
  }
6193
- };
6194
- const syncLyricVisibility = () => {
6195
- lyricBody.style.display = active.lyricModel ? "" : "none";
6196
- lyricOctaveSel.style.display = active.lyricModel ? "" : "none";
6197
- updateLyricCount();
6198
- syncLyricTerms();
6199
- syncLyricIcon();
6200
- };
6201
- syncLyricVisibility();
6202
- lyricModelSel.addEventListener("change", () => {
6203
- active.lyricModel = lyricModelSel.value;
6204
- syncLyricVisibility();
6205
- });
6206
- lyricOctaveSel.addEventListener("change", () => {
6207
- active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
6208
- });
6209
- lyricInput.addEventListener("input", () => {
6210
- active.lyrics = lyricInput.value;
6211
- updateLyricCount();
6212
- });
6213
- lyricVol.addEventListener("input", () => {
6214
- active.vocalVolume = Number.parseInt(lyricVol.value, 10);
6215
- lyricVolLabel.textContent = lyricVol.value;
6216
- });
6217
- lyricPan.addEventListener("input", () => {
6218
- active.vocalPan = Number.parseInt(lyricPan.value, 10);
6429
+ lyricModelSel.value = active.lyricModel;
6430
+ lyricOctaveSel.value = String(active.vocalOctave);
6431
+ lyricInput.value = active.lyrics;
6432
+ lyricVol.value = String(active.vocalVolume);
6433
+ lyricVolLabel.textContent = String(active.vocalVolume);
6434
+ lyricPan.value = String(active.vocalPan);
6219
6435
  lyricPanLabel.textContent = fmtPan(active.vocalPan);
6220
- });
6221
- lyricPanLabel.style.cursor = "pointer";
6222
- lyricPanLabel.title = "\u30BF\u30C3\u30D7\u3067\u4E2D\u592E(C)\u3078";
6223
- lyricPanLabel.addEventListener("click", () => {
6224
- active.vocalPan = 64;
6225
- lyricPan.value = "64";
6226
- lyricPanLabel.textContent = fmtPan(64);
6227
- });
6436
+ const updateLyricCount = () => {
6437
+ const n = normalizeLyrics(lyricInput.value).length;
6438
+ lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
6439
+ };
6440
+ const syncLyricTerms = () => {
6441
+ const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6442
+ if (url) {
6443
+ const label = lyricModelLabel(active.lyricModel);
6444
+ lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
6445
+ lyricTermsLink.href = url;
6446
+ lyricTerms.classList.remove("dtm-hidden");
6447
+ } else {
6448
+ lyricTerms.classList.add("dtm-hidden");
6449
+ }
6450
+ };
6451
+ const syncLyricIcon = () => {
6452
+ const imgKey = active.lyricModel ? VOICE_IMAGE_KEY[active.lyricModel.toLowerCase()] : void 0;
6453
+ const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
6454
+ if (src) {
6455
+ lyricIcon.src = src;
6456
+ lyricIcon.classList.remove("dtm-hidden");
6457
+ } else {
6458
+ lyricIcon.removeAttribute("src");
6459
+ lyricIcon.classList.add("dtm-hidden");
6460
+ }
6461
+ };
6462
+ const syncLyricVisibility = () => {
6463
+ lyricBody.style.display = active.lyricModel ? "" : "none";
6464
+ lyricOctaveSel.style.display = active.lyricModel ? "" : "none";
6465
+ updateLyricCount();
6466
+ syncLyricTerms();
6467
+ syncLyricIcon();
6468
+ };
6469
+ syncLyricVisibility();
6470
+ lyricModelSel.addEventListener("change", () => {
6471
+ active.lyricModel = lyricModelSel.value;
6472
+ syncLyricVisibility();
6473
+ });
6474
+ lyricOctaveSel.addEventListener("change", () => {
6475
+ active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
6476
+ });
6477
+ lyricInput.addEventListener("input", () => {
6478
+ active.lyrics = lyricInput.value;
6479
+ updateLyricCount();
6480
+ });
6481
+ lyricVol.addEventListener("input", () => {
6482
+ active.vocalVolume = Number.parseInt(lyricVol.value, 10);
6483
+ lyricVolLabel.textContent = lyricVol.value;
6484
+ });
6485
+ lyricPan.addEventListener("input", () => {
6486
+ active.vocalPan = Number.parseInt(lyricPan.value, 10);
6487
+ lyricPanLabel.textContent = fmtPan(active.vocalPan);
6488
+ });
6489
+ lyricPanLabel.style.cursor = "pointer";
6490
+ lyricPanLabel.title = "\u30BF\u30C3\u30D7\u3067\u4E2D\u592E(C)\u3078";
6491
+ lyricPanLabel.addEventListener("click", () => {
6492
+ active.vocalPan = 64;
6493
+ lyricPan.value = "64";
6494
+ lyricPanLabel.textContent = fmtPan(64);
6495
+ });
6496
+ }
6228
6497
  if (active.config.id === "chord" && showChord) {
6229
6498
  const div = document.createElement("div");
6230
6499
  div.className = "dtm-row";
6231
6500
  div.style.flexDirection = "column";
6232
6501
  div.style.alignItems = "stretch";
6233
- const roots = [
6234
- "C",
6235
- "C#",
6236
- "D",
6237
- "D#",
6238
- "E",
6239
- "F",
6240
- "F#",
6241
- "G",
6242
- "G#",
6243
- "A",
6244
- "A#",
6245
- "B"
6246
- ];
6247
6502
  div.innerHTML = `
6248
- <div class="dtm-row">
6249
- <span class="dtm-label">\u548C\u97F3</span>
6503
+ <div class="dtm-row" style="justify-content: space-between; align-items: center;">
6504
+ <div style="display: inline-flex; align-items: center; gap: 6px;">
6505
+ <span class="dtm-label">\u548C\u97F3</span>
6506
+ <button class="dtm-infobtn" data-dtm="chord-info" title="\u30B3\u30FC\u30C9\u9032\u884C\u306E\u66F8\u304D\u65B9\u89E3\u8AAC">${icon("info", 12)}</button>
6507
+ </div>
6250
6508
  <select class="dtm-select" data-dtm="chord-pattern">
6251
6509
  <option value="block">\u30D6\u30ED\u30C3\u30AF</option>
6252
6510
  <option value="arpeggio">\u30A2\u30EB\u30DA\u30B8\u30AA</option>
@@ -6255,32 +6513,28 @@ var mountDAW = (target, options = {}) => {
6255
6513
  <option value="yatsume">\u30E4\u30C4\u30E1\u7A74</option>
6256
6514
  <option value="alternating">\u4EA4\u4E92\u594F</option>
6257
6515
  </select>
6258
- <select class="dtm-select" data-dtm="chord-root">
6259
- ${roots.map((r, i) => `<option value="${i}">${r}</option>`).join("")}
6260
- </select>
6261
- <button class="dtm-btn dtm-btn--primary" data-dtm="chord-apply">\u9069\u7528</button>
6262
6516
  </div>
6263
- <textarea class="dtm-textarea" data-dtm="chord-input" placeholder="\u4F8B: C|G|Am|Em|F|C|F|G">${active.savedChordInput}</textarea>`;
6517
+ <div class="dtm-row">
6518
+ <textarea class="dtm-textarea dtm-grow" data-dtm="chord-input" placeholder="\u4F8B: C|G|Am|Em|F|C|F|G">${active.savedChordInput}</textarea>
6519
+ <button class="dtm-btn dtm-btn--primary" data-dtm="chord-apply">\u9069\u7528</button>
6520
+ </div>`;
6264
6521
  refs.trackBody.appendChild(div);
6265
6522
  const patternSel = div.querySelector(
6266
6523
  '[data-dtm="chord-pattern"]'
6267
6524
  );
6268
- const rootSel = div.querySelector(
6269
- '[data-dtm="chord-root"]'
6270
- );
6271
6525
  const input = div.querySelector(
6272
6526
  '[data-dtm="chord-input"]'
6273
6527
  );
6274
6528
  patternSel.value = active.savedChordPattern;
6275
- rootSel.value = String(active.savedChordRoot);
6276
6529
  const save = () => {
6277
6530
  active.savedChordInput = input.value;
6278
6531
  active.savedChordPattern = patternSel.value;
6279
- active.savedChordRoot = Number.parseInt(rootSel.value, 10);
6280
6532
  };
6281
6533
  patternSel.addEventListener("change", save);
6282
- rootSel.addEventListener("change", save);
6283
6534
  input.addEventListener("input", save);
6535
+ div.querySelector('[data-dtm="chord-info"]').addEventListener("click", () => {
6536
+ showModal("\u30B3\u30FC\u30C9\u9032\u884C\u306E\u81EA\u52D5\u5165\u529B\u89E3\u8AAC", CHORD_INFO_HTML);
6537
+ });
6284
6538
  div.querySelector('[data-dtm="chord-apply"]').addEventListener("click", () => {
6285
6539
  save();
6286
6540
  applyChord();
@@ -6293,16 +6547,16 @@ var mountDAW = (target, options = {}) => {
6293
6547
  updateUndoRedo();
6294
6548
  redrawAll();
6295
6549
  };
6296
- const setToolMode = (mode) => {
6297
- activeToolMode = mode;
6550
+ const setToolMode = (mode2) => {
6551
+ activeToolMode = mode2;
6298
6552
  for (const [btn, m] of [
6299
6553
  [refs.toolPen, "pen"],
6300
6554
  [refs.toolSelect, "select"],
6301
6555
  [refs.toolEraser, "eraser"]
6302
6556
  ]) {
6303
- btn.classList.toggle("dtm-segbtn--active", m === mode);
6557
+ btn.classList.toggle("dtm-segbtn--active", m === mode2);
6304
6558
  }
6305
- if (mode !== "select") {
6559
+ if (mode2 !== "select") {
6306
6560
  selectionRect = null;
6307
6561
  selectedNotes = [];
6308
6562
  }
@@ -6536,7 +6790,6 @@ var mountDAW = (target, options = {}) => {
6536
6790
  const applyMidiSelection = (midi, selectedIndices) => {
6537
6791
  clearAll();
6538
6792
  for (const t of trackStates) t.core.setLoadMode(true);
6539
- const isAdvanced = trackStates.length > TRACKS_SIMPLE.length;
6540
6793
  const { placements, bpm: parsedBpm } = isAdvanced ? extractMidiPlacementsByTrack(
6541
6794
  midi,
6542
6795
  selectedIndices,
@@ -6718,6 +6971,25 @@ var mountDAW = (target, options = {}) => {
6718
6971
  "click",
6719
6972
  () => overlayDuring(() => loadMML(refs.mmlInput.value))
6720
6973
  );
6974
+ showModal = (title, bodyHTML) => {
6975
+ refs.modalTitle.textContent = title;
6976
+ refs.modalBody.innerHTML = bodyHTML;
6977
+ refs.modalOverlay.removeAttribute("hidden");
6978
+ };
6979
+ refs.modalClose.addEventListener("click", () => {
6980
+ refs.modalOverlay.setAttribute("hidden", "");
6981
+ });
6982
+ refs.modalOverlay.addEventListener("click", (e) => {
6983
+ if (e.target === refs.modalOverlay) {
6984
+ refs.modalOverlay.setAttribute("hidden", "");
6985
+ }
6986
+ });
6987
+ refs.mmlInfoBtn.addEventListener("click", () => {
6988
+ showModal("MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC", MML_INFO_HTML);
6989
+ });
6990
+ refs.midiInfoBtn.addEventListener("click", () => {
6991
+ showModal("MIDI\u306E\u8AAD\u307F\u8FBC\u307F\u89E3\u8AAC", MIDI_INFO_HTML);
6992
+ });
6721
6993
  refs.shiftApplyBtn.addEventListener(
6722
6994
  "click",
6723
6995
  () => overlayDuring(() => {