@onjmin/dtm 0.1.24 → 0.1.25

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.mjs CHANGED
@@ -1319,6 +1319,7 @@ var buildUI = (target, options) => {
1319
1319
  <div class="dtm-modal-body" data-dtm="modal-body"></div>
1320
1320
  </div>
1321
1321
  </div>
1322
+
1322
1323
  </div>`;
1323
1324
  const root = q(target, '[data-dtm="root"]');
1324
1325
  const sel = (name) => q(root, `[data-dtm="${name}"]`);
@@ -2502,7 +2503,20 @@ var createWorkerBackend = async (workerUrl, options) => {
2502
2503
  };
2503
2504
  };
2504
2505
  var createKoeVoice = async (ctx, destination, options) => {
2505
- const backend = options.voiceWorkerUrl ? await createWorkerBackend(options.voiceWorkerUrl, options) : await createLocalBackend(options);
2506
+ let backend;
2507
+ if (options.voiceWorkerUrl) {
2508
+ try {
2509
+ backend = await createWorkerBackend(options.voiceWorkerUrl, options);
2510
+ } catch (err2) {
2511
+ console.warn(
2512
+ "[dtm] Failed to spawn voice worker. Falling back to local backend.",
2513
+ err2
2514
+ );
2515
+ backend = await createLocalBackend(options);
2516
+ }
2517
+ } else {
2518
+ backend = await createLocalBackend(options);
2519
+ }
2506
2520
  const renderCache = /* @__PURE__ */ new Map();
2507
2521
  const inflight = /* @__PURE__ */ new Map();
2508
2522
  const active = /* @__PURE__ */ new Set();
@@ -4017,6 +4031,110 @@ var isChordHeavyTrack = (notes, threshold = 0.6) => {
4017
4031
  return chordNotes / notes.length >= threshold;
4018
4032
  };
4019
4033
 
4034
+ // src/mml-info.ts
4035
+ var MML_INFO_HTML = `
4036
+ <div class="dtm-modal-body-content">
4037
+ <h4>1. \u97F3\u7B26\u3068\u4F11\u7B26</h4>
4038
+ <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>
4039
+ <ul>
4040
+ <li>\u534A\u97F3\u4E0A\u3052\u308B: <code>c#</code> \u307E\u305F\u306F <code>c+</code></li>
4041
+ <li>\u534A\u97F3\u4E0B\u3052\u308B: <code>d-</code></li>
4042
+ <li>\u4F11\u7B26: <code>r</code></li>
4043
+ </ul>
4044
+
4045
+ <h4>2. \u97F3\u306E\u9577\u3055</h4>
4046
+ <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>
4047
+ <ul>
4048
+ <li><code>c4</code> : 4\u5206\u97F3\u7B26\u306E\u30C9</li>
4049
+ <li><code>r8</code> : 8\u5206\u4F11\u7B26</li>
4050
+ <li><code>c4.</code> : \u4ED8\u70B94\u5206\u97F3\u7B26\u306E\u30C9\uFF08\u9577\u3055\u30921.5\u500D\u306B\uFF09</li>
4051
+ <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>
4052
+ </ul>
4053
+
4054
+ <h4>3. \u30AA\u30AF\u30BF\u30FC\u30D6\uFF08\u97F3\u306E\u9AD8\u3055\uFF09</h4>
4055
+ <ul>
4056
+ <li><code>o4</code>, <code>o5</code> : \u9AD8\u3055\u3092\u76F4\u63A5\u6307\u5B9A\uFF08\u3075\u3064\u3046\u306F o4 \u304B o5\uFF09</li>
4057
+ <li><code>&gt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u308B</li>
4058
+ <li><code>&lt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0B\u3052\u308B</li>
4059
+ </ul>
4060
+
4061
+ <h4>4. \u30C6\u30F3\u30DD</h4>
4062
+ <ul>
4063
+ <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>
4064
+ </ul>
4065
+
4066
+ <h4>5. \u548C\u97F3</h4>
4067
+ <p>\u97F3\u7B26\u3092 <code>[</code> \u3068 <code>]</code> \u3067\u56F2\u3080\u3068\u540C\u6642\u306B\u767A\u97F3\u3057\u307E\u3059\u3002</p>
4068
+ <pre>\u4F8B: [ceg]4 \uFF08\u30C9\u30FB\u30DF\u30FB\u30BD\u30924\u5206\u97F3\u7B26\u3067\u540C\u6642\u306B\u767A\u97F3\uFF09</pre>
4069
+
4070
+ <h4>6. \u30C8\u30E9\u30C3\u30AF\u306E\u533A\u5207\u308A</h4>
4071
+ <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>
4072
+ <ul>
4073
+ <li><code>@0</code>: \u30E1\u30ED\u30C7\u30A3</li>
4074
+ <li><code>@1</code>: \u30B5\u30D6\u30E1\u30ED</li>
4075
+ <li><code>@2</code>: \u30D9\u30FC\u30B9</li>
4076
+ <li><code>@3</code>: \u4F34\u594F</li>
4077
+ </ul>
4078
+
4079
+ <h4>7. \u6B4C\u58F0\u30FB\u6B4C\u8A5E\u5165\u529B</h4>
4080
+ <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>
4081
+ <pre>\u4F8B: @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053</pre>
4082
+ <p style="margin-top:4px; margin-bottom:16px;"><small>\uFF08\u97F3\u6E90\u540D\u306F <code>tsukuyomi</code> \u3084 <code>klatt</code>, <code>roze</code> \u306A\u3069\u306E\u97F3\u58F0\u30E2\u30C7\u30EB\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\uFF09</small></p>
4083
+
4084
+ <h4 style="margin-top: 18px; border-top: 1px solid var(--dtm-border2); padding-top: 8px;">\u30B5\u30F3\u30D7\u30EB\u66F2\uFF08\u8A66\u8074\u30FB\u30B3\u30D4\u30FC\uFF09</h4>
4085
+
4086
+ <!-- \u30B5\u30F3\u30D7\u30EB1 -->
4087
+ <div class="dtm-modal-sample-box">
4088
+ <div class="dtm-modal-sample-header">
4089
+ <span class="dtm-modal-sample-tag">1. \u57FA\u672C\u306E\u30E1\u30ED\u30C7\u30A3</span>
4090
+ <button class="dtm-btn dtm-btn--ghost dtm-btn--xs dtm-modal-sample-copy-btn" data-mml="@0 t120 l8 o5 c d e f g a b > c">\u{1F4CB} \u30B3\u30D4\u30FC</button>
4091
+ </div>
4092
+ <pre style="margin: 0; padding: 6px;">@0 t120 l8 o5 c d e f g a b &gt; c</pre>
4093
+ <div class="dtm-modal-sample-desc">
4094
+ \u57FA\u672C\u7684\u306A\u30E1\u30ED\u30C7\u30A3\u306E\u66F8\u304D\u65B9\uFF08\u97F3\u540D\u30FB\u9577\u3055\u30FB\u30AA\u30AF\u30BF\u30FC\u30D6\u3068\u30C6\u30F3\u30DD\uFF09\u3002
4095
+ </div>
4096
+ <div style="margin-top: 8px;">
4097
+ <button class="dtm-btn dtm-btn--primary dtm-btn--xs dtm-modal-sample-play-btn" data-mml="@0 t120 l8 o5 c d e f g a b > c">\u25B6 \u8A66\u8074</button>
4098
+ </div>
4099
+ <div class="dtm-modal-sample-player-container"></div>
4100
+ </div>
4101
+
4102
+ <!-- \u30B5\u30F3\u30D7\u30EB2 -->
4103
+ <div class="dtm-modal-sample-box">
4104
+ <div class="dtm-modal-sample-header">
4105
+ <span class="dtm-modal-sample-tag">2. \u8907\u6570\u30C8\u30E9\u30C3\u30AF\u3068\u548C\u97F3</span>
4106
+ <button class="dtm-btn dtm-btn--ghost dtm-btn--xs dtm-modal-sample-copy-btn" data-mml="@0 t120 o5 c e g2 ; @3 o4 [ceg]2 [ceg]2">\u{1F4CB} \u30B3\u30D4\u30FC</button>
4107
+ </div>
4108
+ <pre style="margin: 0; padding: 6px;">@0 t120 o5 c e g2 ;
4109
+ @3 o4 [ceg]2 [ceg]2</pre>
4110
+ <div class="dtm-modal-sample-desc">
4111
+ ; \u3067\u30C8\u30E9\u30C3\u30AF\uFF08\u4E0A\uFF1D\u30E1\u30ED\u30C7\u30A3\uFF0F\u4E0B\uFF1D\u4F34\u594F\uFF09\u3092\u5206\u3051\u3001[ceg] \u3067\u548C\u97F3\u3092\u9CF4\u3089\u3057\u307E\u3059\u3002
4112
+ </div>
4113
+ <div style="margin-top: 8px;">
4114
+ <button class="dtm-btn dtm-btn--primary dtm-btn--xs dtm-modal-sample-play-btn" data-mml="@0 t120 o5 c e g2 ; @3 o4 [ceg]2 [ceg]2">\u25B6 \u8A66\u8074</button>
4115
+ </div>
4116
+ <div class="dtm-modal-sample-player-container"></div>
4117
+ </div>
4118
+
4119
+ <!-- \u30B5\u30F3\u30D7\u30EB3 -->
4120
+ <div class="dtm-modal-sample-box">
4121
+ <div class="dtm-modal-sample-header">
4122
+ <span class="dtm-modal-sample-tag">3. \u6B4C\u5531\u4ED8\u304D (\u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D)</span>
4123
+ <button class="dtm-btn dtm-btn--ghost dtm-btn--xs dtm-modal-sample-copy-btn" data-mml="@0 t120 v100 o4g8 g8 e8 e8 f8 e8 d8 c8 g8 g8 e8 e8 d4.; @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053;">\u{1F4CB} \u30B3\u30D4\u30FC</button>
4124
+ </div>
4125
+ <pre style="margin: 0; padding: 6px;">@0 t120 v100 o4g8 g8 e8 e8 f8 e8 d8 c8 g8 g8 e8 e8 d4.;
4126
+ @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053;</pre>
4127
+ <div class="dtm-modal-sample-desc">
4128
+ @@0 tsukuyomi \u6B4C\u8A5E... \u3067\u30E1\u30ED\u30C7\u30A3\u30C8\u30E9\u30C3\u30AF\u306B\u6B4C\u8A5E\u3092\u540C\u671F\u3055\u305B\u3066\u6B4C\u308F\u305B\u307E\u3059\u3002\u203B\u72EC\u81EA\u62E1\u5F35
4129
+ </div>
4130
+ <div style="margin-top: 8px;">
4131
+ <button class="dtm-btn dtm-btn--primary dtm-btn--xs dtm-modal-sample-play-btn" data-mml="@0 t120 v100 o4g8 g8 e8 e8 f8 e8 d8 c8 g8 g8 e8 e8 d4.; @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053;">\u25B6 \u8A66\u8074</button>
4132
+ </div>
4133
+ <div class="dtm-modal-sample-player-container"></div>
4134
+ </div>
4135
+ </div>
4136
+ `;
4137
+
4020
4138
  // src/mml-parser.ts
4021
4139
  var PITCH_MAP2 = {
4022
4140
  c: 0,
@@ -4639,9 +4757,13 @@ var DAW_CSS = `
4639
4757
  /* \u30C7\u30B6\u30A4\u30F3\u30C8\u30FC\u30AF\u30F3\u306F\u7DE8\u96C6UI\u672C\u4F53\uFF08.dtm-daw\uFF09\u306B\u52A0\u3048\u3001\u305D\u306E\u5916\u5074\u306B\u5DEE\u3057\u8FBC\u307E\u308C\u308B
4640
4758
  \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC\uFF08.dtm-controlbar\uFF09\u306B\u3082\u4F9B\u7D66\u3059\u308B\u3002mountPresetSelect /
4641
4759
  mountModeSwitch \u306EUI\u306F .dtm-daw \u306E\u5144\u5F1F\u3068\u3057\u3066\u7F6E\u304B\u308C\u308B\u305F\u3081\u3001\u3053\u3053\u3067\u914D\u3089\u306A\u3044\u3068
4642
- var(--dtm-*) \u304C\u89E3\u6C7A\u3067\u304D\u305A\u7121\u88C5\u98FE\uFF08\u767D\u5730\u30FB\u65E2\u5B9A\u30D5\u30A9\u30F3\u30C8\uFF09\u306B\u306A\u3063\u3066\u3057\u307E\u3046\u3002 */
4760
+ var(--dtm-*) \u304C\u89E3\u6C7A\u3067\u304D\u305A\u7121\u88C5\u98FE\uFF08\u767D\u5730\u30FB\u65E2\u5B9A\u30D5\u30A9\u30F3\u30C8\uFF09\u306B\u306A\u3063\u3066\u3057\u307E\u3046\u3002
4761
+ \u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\u306E\u30E2\u30FC\u30C0\u30EB\uFF0F\u5229\u7528\u898F\u7D04\u30AB\u30D0\u30FC\u306F document.body \u76F4\u4E0B\u3078\u91CD\u306D\u308B\u305F\u3081\u3001
4762
+ .dtm-daw \u306E\u5916\u306B\u51FA\u308B\u3002\u3053\u308C\u3089\u3082\u540C\u69D8\u306B\u30C8\u30FC\u30AF\u30F3\u3092\u4F9B\u7D66\u3057\u306A\u3044\u3068\u9ED2\u5730\u30FB\u767D\u6587\u5B57\u306B\u306A\u308B\u3002 */
4643
4763
  .dtm-daw,
4644
- .dtm-controlbar {
4764
+ .dtm-controlbar,
4765
+ .dtm-modal-overlay,
4766
+ .dtm-consent-overlay {
4645
4767
  /* PICO-8 16\u8272\u30D1\u30EC\u30C3\u30C8\u3088\u308A */
4646
4768
  --c-black: #000000;
4647
4769
  --c-navy: #1d2b53;
@@ -5239,10 +5361,76 @@ var DAW_CSS = `
5239
5361
  justify-content: center;
5240
5362
  padding: 16px;
5241
5363
  backdrop-filter: blur(2px);
5364
+ /* body\u76F4\u4E0B\u306B\u91CD\u306D\u305F\u5834\u5408\uFF08\u518D\u751F\u5C02\u7528\u30D3\u30E5\u30FC\uFF09\u3067\u3082\u6587\u5B57\u8272\u30FB\u30D5\u30A9\u30F3\u30C8\u304C
5365
+ .dtm-daw \u304B\u3089\u7D99\u627F\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u3053\u3053\u3067\u660E\u793A\u3059\u308B\u3002 */
5366
+ color: var(--dtm-text);
5367
+ font-family: var(--dtm-font);
5242
5368
  }
5243
5369
  .dtm-modal-overlay[hidden] {
5244
5370
  display: none !important;
5245
5371
  }
5372
+
5373
+ /* \u2500\u2500\u2500 \u5229\u7528\u898F\u7D04\u540C\u610F\u30AB\u30D0\u30FC \u2500\u2500\u2500 */
5374
+ .dtm-consent-overlay {
5375
+ position: fixed;
5376
+ inset: 0;
5377
+ z-index: 10100;
5378
+ background: rgba(0, 0, 0, 0.6);
5379
+ display: flex;
5380
+ align-items: center;
5381
+ justify-content: center;
5382
+ padding: 16px;
5383
+ backdrop-filter: blur(2px);
5384
+ /* body\u76F4\u4E0B\u306B\u91CD\u306D\u308B\u305F\u3081 .dtm-daw \u304B\u3089\u7D99\u627F\u3067\u304D\u306A\u3044\u6587\u5B57\u8272\u30FB\u30D5\u30A9\u30F3\u30C8\u3092\u660E\u793A\u3002 */
5385
+ color: var(--dtm-text);
5386
+ font-family: var(--dtm-font);
5387
+ }
5388
+ .dtm-consent-overlay[hidden] {
5389
+ display: none !important;
5390
+ }
5391
+ .dtm-consent-modal {
5392
+ max-width: 450px;
5393
+ width: 100%;
5394
+ max-height: 85vh;
5395
+ display: flex;
5396
+ flex-direction: column;
5397
+ background: var(--dtm-surface);
5398
+ border: 2px solid var(--c-black);
5399
+ box-shadow:
5400
+ inset 0 0 0 2px var(--c-black),
5401
+ 0 0 0 2px var(--dtm-primary),
5402
+ 4px 4px 0 var(--c-black);
5403
+ overflow-y: auto;
5404
+ }
5405
+ .dtm-consent-header {
5406
+ background: var(--dtm-deep);
5407
+ color: var(--dtm-text);
5408
+ padding: 8px 12px;
5409
+ border-bottom: 2px solid var(--c-black);
5410
+ font-weight: bold;
5411
+ text-align: center;
5412
+ font-size: 14px;
5413
+ }
5414
+ .dtm-consent-body {
5415
+ padding: 12px 16px;
5416
+ font-size: 13px;
5417
+ line-height: 1.6;
5418
+ }
5419
+ .dtm-consent-body a {
5420
+ color: var(--dtm-primary);
5421
+ text-decoration: underline;
5422
+ }
5423
+ .dtm-consent-body a:hover {
5424
+ color: var(--dtm-accent);
5425
+ }
5426
+ .dtm-consent-footer {
5427
+ padding: 8px;
5428
+ border-top: 2px solid var(--c-black);
5429
+ background: var(--dtm-deep);
5430
+ display: flex;
5431
+ justify-content: center;
5432
+ }
5433
+
5246
5434
  .dtm-modal {
5247
5435
  max-width: 500px;
5248
5436
  width: 100%;
@@ -5376,18 +5564,19 @@ var DAW_CSS = `
5376
5564
  }
5377
5565
 
5378
5566
  .dtm-hidden { display: none !important; }
5379
- /* \u8AAD\u8FBC\u6642\u306E\u63A7\u3048\u3081\u306A\u304A\u77E5\u3089\u305B\uFF08\u4F8B: \u30B7\u30F3\u30D7\u30EB\u30E2\u30FC\u30C9\u3067\u306E\u30C8\u30E9\u30C3\u30AF\u5408\u7B97\uFF09\u3002\u4E3B\u5F35\u3057\u3059\u304E\u306A\u3044 muted \u8868\u793A\u3002 */
5567
+ /* \u8AAD\u8FBC\u6642\u306E\u8B66\u544A\u304A\u77E5\u3089\u305B\uFF08\u4F8B: \u30B7\u30F3\u30D7\u30EB\u30E2\u30FC\u30C9\u3067\u306E\u30C8\u30E9\u30C3\u30AF\u5408\u7B97\uFF09\u3002 */
5380
5568
  .dtm-load-note {
5381
5569
  margin: 6px 0 0;
5382
5570
  padding: 0 2px;
5383
5571
  font-family: var(--dtm-font);
5384
- font-size: 10px;
5572
+ font-size: 11px;
5385
5573
  line-height: 1.5;
5386
5574
  letter-spacing: .04em;
5387
- color: var(--dtm-muted);
5388
- opacity: .85;
5575
+ color: var(--dtm-warn); /* \u8B66\u544A\u8272\uFF08\u30AA\u30EC\u30F3\u30B8\uFF09 */
5576
+ font-weight: bold;
5577
+ opacity: 1.0;
5389
5578
  }
5390
- .dtm-load-note::before { content: "\u24D8 "; }
5579
+ .dtm-load-note::before { content: "\u26A0 "; }
5391
5580
  .dtm-grow { flex: 1 1 auto; }
5392
5581
  .dtm-lyric-icon {
5393
5582
  flex: 0 0 auto;
@@ -5788,6 +5977,7 @@ var STEPS_PER_BEAT3 = 48;
5788
5977
  var STEPS_PER_BAR = 192;
5789
5978
  var DEFAULT_TRACK_COLORS = ["#00e436", "#29adff", "#ff77a8", "#ffec27"];
5790
5979
  var activePlayer = null;
5980
+ var agreedModelsInSession = /* @__PURE__ */ new Set();
5791
5981
  var LYRIC_MODEL_LABELS = {
5792
5982
  klatt: "\u8EFD\u91CF\u30ED\u30DC\u58F0",
5793
5983
  ...KOE_VOICEBANK_LABELS
@@ -6043,16 +6233,21 @@ var mountMmlPlayer = (target, mml, options = {}) => {
6043
6233
  const menuDropdown = doc.createElement("div");
6044
6234
  menuDropdown.className = "dtm-player-menu";
6045
6235
  menuDropdown.style.display = "none";
6046
- const copyMmlItem = doc.createElement("button");
6047
- copyMmlItem.type = "button";
6048
- copyMmlItem.className = "dtm-player-menu-item";
6049
- copyMmlItem.textContent = "MML\u30B3\u30D4\u30FC";
6050
- const embedItem = doc.createElement("button");
6051
- embedItem.type = "button";
6052
- embedItem.className = "dtm-player-menu-item";
6053
- embedItem.textContent = "\u57CB\u3081\u8FBC\u3080";
6054
- menuDropdown.appendChild(copyMmlItem);
6236
+ const makeMenuItem = (label) => {
6237
+ const item = doc.createElement("button");
6238
+ item.type = "button";
6239
+ item.className = "dtm-player-menu-item";
6240
+ item.textContent = label;
6241
+ return item;
6242
+ };
6243
+ const showMmlItem = makeMenuItem("MML\u3092\u8868\u793A");
6244
+ const mmlInfoItem = makeMenuItem("MML\u66F8\u5F0F\u3068\u306F");
6245
+ const embedItem = makeMenuItem("\u57CB\u3081\u8FBC\u3080");
6246
+ const copyMmlItem = makeMenuItem("MML\u30B3\u30D4\u30FC");
6247
+ menuDropdown.appendChild(showMmlItem);
6248
+ menuDropdown.appendChild(mmlInfoItem);
6055
6249
  menuDropdown.appendChild(embedItem);
6250
+ menuDropdown.appendChild(copyMmlItem);
6056
6251
  menuContainer.appendChild(menuDropdown);
6057
6252
  mmlHeader.appendChild(menuContainer);
6058
6253
  const toggleMenu = (show) => {
@@ -6075,38 +6270,200 @@ var mountMmlPlayer = (target, mml, options = {}) => {
6075
6270
  e.stopPropagation();
6076
6271
  toggleMenu();
6077
6272
  });
6078
- copyMmlItem.addEventListener("click", async (e) => {
6079
- e.stopPropagation();
6080
- const success = await copyToClipboard(doc, mml);
6081
- if (success) {
6082
- copyMmlItem.textContent = "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F\uFF01";
6083
- } else {
6084
- copyMmlItem.textContent = "\u30B3\u30D4\u30FC\u5931\u6557";
6273
+ let infoModalEl = null;
6274
+ let modalSamplePlayer = null;
6275
+ const closeInfoModal = () => {
6276
+ if (modalSamplePlayer) {
6277
+ modalSamplePlayer.stop();
6278
+ modalSamplePlayer.destroy();
6279
+ modalSamplePlayer = null;
6280
+ }
6281
+ infoModalEl?.remove();
6282
+ infoModalEl = null;
6283
+ };
6284
+ const openInfoModal = (title) => {
6285
+ closeInfoModal();
6286
+ const overlay = doc.createElement("div");
6287
+ overlay.className = "dtm-modal-overlay";
6288
+ const modal = doc.createElement("div");
6289
+ modal.className = "dtm-win dtm-modal";
6290
+ const header = doc.createElement("div");
6291
+ header.className = "dtm-modal-header";
6292
+ const titleEl = doc.createElement("span");
6293
+ titleEl.className = "dtm-modal-title";
6294
+ titleEl.textContent = title;
6295
+ const closeBtn = doc.createElement("button");
6296
+ closeBtn.type = "button";
6297
+ closeBtn.className = "dtm-modal-close";
6298
+ closeBtn.innerHTML = "&times;";
6299
+ closeBtn.title = "\u9589\u3058\u308B";
6300
+ header.append(titleEl, closeBtn);
6301
+ const modalBody = doc.createElement("div");
6302
+ modalBody.className = "dtm-modal-body";
6303
+ modal.append(header, modalBody);
6304
+ overlay.appendChild(modal);
6305
+ closeBtn.addEventListener("click", (e) => {
6306
+ e.stopPropagation();
6307
+ closeInfoModal();
6308
+ });
6309
+ overlay.addEventListener("click", (e) => {
6310
+ if (e.target === overlay) closeInfoModal();
6311
+ });
6312
+ doc.body.appendChild(overlay);
6313
+ infoModalEl = overlay;
6314
+ return modalBody;
6315
+ };
6316
+ const appendCopyButton = (parent, text) => {
6317
+ const actions = doc.createElement("div");
6318
+ actions.style.marginTop = "8px";
6319
+ const copyBtn = doc.createElement("button");
6320
+ copyBtn.type = "button";
6321
+ copyBtn.className = "dtm-btn dtm-btn--primary dtm-btn--xs";
6322
+ copyBtn.textContent = "\u{1F4CB} \u30B3\u30D4\u30FC";
6323
+ copyBtn.addEventListener("click", async (e) => {
6324
+ e.stopPropagation();
6325
+ const ok = await copyToClipboard(doc, text);
6326
+ copyBtn.textContent = ok ? "\u2713 \u30B3\u30D4\u30FC\u5B8C\u4E86" : "\u30B3\u30D4\u30FC\u5931\u6557";
6327
+ if (ok) copyBtn.classList.add("dtm-btn--success");
6328
+ setTimeout(() => {
6329
+ copyBtn.textContent = "\u{1F4CB} \u30B3\u30D4\u30FC";
6330
+ copyBtn.classList.remove("dtm-btn--success");
6331
+ }, 1200);
6332
+ });
6333
+ actions.appendChild(copyBtn);
6334
+ parent.appendChild(actions);
6335
+ };
6336
+ const wireSampleButtons = (modalBody) => {
6337
+ const copyBtns = modalBody.querySelectorAll(".dtm-modal-sample-copy-btn");
6338
+ for (const btn of copyBtns) {
6339
+ const el = btn;
6340
+ el.addEventListener("click", async (e) => {
6341
+ e.stopPropagation();
6342
+ const sampleMml = el.getAttribute("data-mml") ?? "";
6343
+ const original = el.textContent;
6344
+ const ok = await copyToClipboard(doc, sampleMml);
6345
+ el.textContent = ok ? "\u2713 \u30B3\u30D4\u30FC\u5B8C\u4E86" : "\u30B3\u30D4\u30FC\u5931\u6557";
6346
+ if (ok) el.classList.add("dtm-btn--success");
6347
+ setTimeout(() => {
6348
+ el.textContent = original;
6349
+ el.classList.remove("dtm-btn--success");
6350
+ }, 1200);
6351
+ });
6085
6352
  }
6086
- setTimeout(() => {
6087
- copyMmlItem.textContent = "MML\u30B3\u30D4\u30FC";
6088
- }, 2e3);
6353
+ let activeSampleBtn = null;
6354
+ const resetSampleBtn = (b) => {
6355
+ if (!b) return;
6356
+ b.textContent = "\u25B6 \u8A66\u8074";
6357
+ b.classList.remove("dtm-btn--danger");
6358
+ b.classList.add("dtm-btn--primary");
6359
+ };
6360
+ const markPlaying = (b) => {
6361
+ b.textContent = "\u25A0 \u505C\u6B62";
6362
+ b.classList.remove("dtm-btn--primary");
6363
+ b.classList.add("dtm-btn--danger");
6364
+ };
6365
+ const playBtns = modalBody.querySelectorAll(".dtm-modal-sample-play-btn");
6366
+ for (const btn of playBtns) {
6367
+ const el = btn;
6368
+ el.addEventListener("click", (e) => {
6369
+ e.stopPropagation();
6370
+ const sampleMml = el.getAttribute("data-mml") ?? "";
6371
+ if (activeSampleBtn === el && modalSamplePlayer) {
6372
+ if (modalSamplePlayer.isPlaying()) {
6373
+ modalSamplePlayer.stop();
6374
+ } else {
6375
+ modalSamplePlayer.play();
6376
+ markPlaying(el);
6377
+ }
6378
+ return;
6379
+ }
6380
+ if (modalSamplePlayer) {
6381
+ modalSamplePlayer.stop();
6382
+ modalSamplePlayer.destroy();
6383
+ modalSamplePlayer = null;
6384
+ }
6385
+ resetSampleBtn(activeSampleBtn);
6386
+ activeSampleBtn = el;
6387
+ const sampleBox = el.closest(".dtm-modal-sample-box");
6388
+ const container = sampleBox?.querySelector(
6389
+ ".dtm-modal-sample-player-container"
6390
+ );
6391
+ if (!container) return;
6392
+ container.innerHTML = "";
6393
+ modalSamplePlayer = mountMmlPlayer(container, sampleMml, {
6394
+ onPlayNote: options.onPlayNote,
6395
+ onPlayDrum: options.onPlayDrum,
6396
+ onResumeAudio: options.onResumeAudio,
6397
+ getAudioTime: options.getAudioTime,
6398
+ singingVoices: options.singingVoices,
6399
+ drumPatterns: options.drumPatterns,
6400
+ volume: trackVolume,
6401
+ // 解説モーダル内の試聴サンプルは規約同意を要求しない。
6402
+ skipConsent: true,
6403
+ onStop: () => {
6404
+ if (activeSampleBtn === el) resetSampleBtn(el);
6405
+ }
6406
+ });
6407
+ markPlaying(el);
6408
+ modalSamplePlayer.play();
6409
+ });
6410
+ }
6411
+ };
6412
+ showMmlItem.addEventListener("click", (e) => {
6413
+ e.stopPropagation();
6414
+ toggleMenu(false);
6415
+ const modalBody = openInfoModal("MML");
6416
+ const pre = doc.createElement("pre");
6417
+ pre.textContent = mml;
6418
+ pre.style.whiteSpace = "pre-wrap";
6419
+ pre.style.wordBreak = "break-all";
6420
+ modalBody.appendChild(pre);
6421
+ appendCopyButton(modalBody, mml);
6422
+ });
6423
+ mmlInfoItem.addEventListener("click", (e) => {
6424
+ e.stopPropagation();
6425
+ toggleMenu(false);
6426
+ const modalBody = openInfoModal("MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC");
6427
+ modalBody.innerHTML = MML_INFO_HTML;
6428
+ wireSampleButtons(modalBody);
6089
6429
  });
6090
6430
  embedItem.addEventListener("click", async (e) => {
6091
6431
  e.stopPropagation();
6092
- embedItem.textContent = "\u751F\u6210\u4E2D...";
6432
+ toggleMenu(false);
6433
+ const modalBody = openInfoModal("\u57CB\u3081\u8FBC\u307F");
6434
+ const loading = doc.createElement("p");
6435
+ loading.textContent = "\u751F\u6210\u4E2D...";
6436
+ modalBody.appendChild(loading);
6093
6437
  try {
6094
6438
  const embedBase = options.embedUrl ?? "https://onjmin.github.io/dtm/demo/embed.html";
6095
6439
  const payload = await encodeMml(mml);
6096
6440
  const url2 = `${embedBase}#${payload}`;
6097
6441
  const snippet = `<iframe src="${url2}" width="100%" height="260" frameborder="0" loading="lazy" title="@onjmin/dtm player"></iframe>`;
6098
- const success = await copyToClipboard(doc, snippet);
6099
- if (success) {
6100
- embedItem.textContent = "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F\uFF01";
6101
- } else {
6102
- embedItem.textContent = "\u30B3\u30D4\u30FC\u5931\u6557";
6103
- }
6442
+ if (!modalBody.isConnected) return;
6443
+ loading.remove();
6444
+ const desc = doc.createElement("p");
6445
+ desc.textContent = "\u3053\u306EHTML\u3092\u30D6\u30ED\u30B0\u3084\u30B5\u30A4\u30C8\u306B\u8CBC\u308A\u4ED8\u3051\u308B\u3068\u3001\u30D7\u30EC\u30A4\u30E4\u30FC\u3092\u305D\u306E\u307E\u307E\u57CB\u3081\u8FBC\u3081\u307E\u3059\u3002";
6446
+ const pre = doc.createElement("pre");
6447
+ pre.textContent = snippet;
6448
+ pre.style.whiteSpace = "pre-wrap";
6449
+ pre.style.wordBreak = "break-all";
6450
+ modalBody.append(desc, pre);
6451
+ appendCopyButton(modalBody, snippet);
6104
6452
  } catch (err2) {
6105
6453
  console.error("[dtm] failed to generate embed snippet", err2);
6106
- embedItem.textContent = "\u751F\u6210\u5931\u6557";
6454
+ if (modalBody.isConnected) loading.textContent = "\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F";
6455
+ }
6456
+ });
6457
+ copyMmlItem.addEventListener("click", async (e) => {
6458
+ e.stopPropagation();
6459
+ const success = await copyToClipboard(doc, mml);
6460
+ if (success) {
6461
+ copyMmlItem.textContent = "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F\uFF01";
6462
+ } else {
6463
+ copyMmlItem.textContent = "\u30B3\u30D4\u30FC\u5931\u6557";
6107
6464
  }
6108
6465
  setTimeout(() => {
6109
- embedItem.textContent = "\u57CB\u3081\u8FBC\u3080";
6466
+ copyMmlItem.textContent = "MML\u30B3\u30D4\u30FC";
6110
6467
  }, 2e3);
6111
6468
  });
6112
6469
  const promotedToImage = /* @__PURE__ */ new Set();
@@ -6352,6 +6709,77 @@ var mountMmlPlayer = (target, mml, options = {}) => {
6352
6709
  root.appendChild(termsDiv);
6353
6710
  }
6354
6711
  target.appendChild(root);
6712
+ let consentOverlayEl = null;
6713
+ const checkConsentAndShow = () => {
6714
+ try {
6715
+ if (options.skipConsent) return;
6716
+ const unagreed = termsModels.filter((model) => {
6717
+ if (agreedModelsInSession.has(model)) return false;
6718
+ try {
6719
+ if (typeof localStorage === "undefined" || !localStorage) return true;
6720
+ return localStorage.getItem(`dtm_agreed_terms_${model}`) !== "true";
6721
+ } catch (e) {
6722
+ console.warn(
6723
+ "[dtm-player] localStorage access denied in consent check",
6724
+ e
6725
+ );
6726
+ return true;
6727
+ }
6728
+ });
6729
+ if (unagreed.length === 0) return;
6730
+ const consentOverlay = doc.createElement("div");
6731
+ consentOverlay.className = "dtm-consent-overlay";
6732
+ const modal = doc.createElement("div");
6733
+ modal.className = "dtm-win dtm-consent-modal";
6734
+ const header = doc.createElement("div");
6735
+ header.className = "dtm-consent-header";
6736
+ header.textContent = "\u5229\u7528\u898F\u7D04\u306E\u78BA\u8A8D";
6737
+ const body2 = doc.createElement("div");
6738
+ body2.className = "dtm-consent-body";
6739
+ let contentHTML = `<p style="margin: 0 0 8px 0; line-height: 1.4; font-weight: bold; color: var(--dtm-danger);">\u672C\u30C7\u30FC\u30BF\u306B\u306F UTAU \u6B4C\u58F0\u97F3\u6E90\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002<br>\u3054\u5229\u7528\u306B\u3042\u305F\u3063\u3066\u306F\u3001\u4EE5\u4E0B\u306E\u97F3\u6E90\u5229\u7528\u898F\u7D04\u3078\u306E\u540C\u610F\u304C\u5FC5\u8981\u3067\u3059\u3002</p>`;
6740
+ for (const model of unagreed) {
6741
+ const label = KOE_VOICEBANK_LABELS[model] || model;
6742
+ const url2 = KOE_VOICEBANK_TERMS[model];
6743
+ contentHTML += `
6744
+ <div style="margin-bottom: 8px; padding: 6px 10px; background: var(--dtm-deep); border: 2px solid var(--c-black); box-shadow: 2px 2px 0 var(--c-black);">
6745
+ <div style="display: flex; align-items: center; gap: 4px; flex-wrap: wrap; font-size: 11px; font-weight: bold; color: var(--dtm-gold);">
6746
+ <span>\u4F7F\u7528\u6642\u306B\u306F</span>
6747
+ <a href="${url2}" target="_blank" rel="noopener noreferrer" style="color: var(--dtm-primary); text-decoration: underline;">${label}UTAU\u97F3\u6E90</a>
6748
+ <span>\u306E\u5229\u7528\u898F\u7D04\u306B\u5F93\u3063\u3066\u304F\u3060\u3055\u3044</span>
6749
+ </div>
6750
+ </div>
6751
+ `;
6752
+ }
6753
+ body2.innerHTML = contentHTML;
6754
+ const footer = doc.createElement("div");
6755
+ footer.className = "dtm-consent-footer";
6756
+ const btn = doc.createElement("button");
6757
+ btn.type = "button";
6758
+ btn.className = "dtm-btn dtm-btn--success";
6759
+ btn.textContent = "\u540C\u610F\u3057\u3066\u5229\u7528\u3059\u308B";
6760
+ btn.onclick = () => {
6761
+ for (const model of unagreed) {
6762
+ try {
6763
+ if (typeof localStorage !== "undefined" && localStorage) {
6764
+ localStorage.setItem(`dtm_agreed_terms_${model}`, "true");
6765
+ }
6766
+ } catch (e) {
6767
+ }
6768
+ agreedModelsInSession.add(model);
6769
+ }
6770
+ consentOverlay.remove();
6771
+ consentOverlayEl = null;
6772
+ };
6773
+ footer.appendChild(btn);
6774
+ modal.append(header, body2, footer);
6775
+ consentOverlay.appendChild(modal);
6776
+ doc.body.appendChild(consentOverlay);
6777
+ consentOverlayEl = consentOverlay;
6778
+ } catch (err2) {
6779
+ console.error("[dtm-player] Error in checkConsentAndShow:", err2);
6780
+ }
6781
+ };
6782
+ checkConsentAndShow();
6355
6783
  const autoScroll = (lane, el) => {
6356
6784
  if (el.offsetWidth === 0 || lane.clientWidth === 0) return;
6357
6785
  const elementCenter = el.offsetLeft + el.offsetWidth / 2;
@@ -6526,6 +6954,8 @@ var mountMmlPlayer = (target, mml, options = {}) => {
6526
6954
  hideActiveBalloon();
6527
6955
  }
6528
6956
  root.remove();
6957
+ consentOverlayEl?.remove();
6958
+ closeInfoModal();
6529
6959
  };
6530
6960
  const instance = {
6531
6961
  play,
@@ -6567,108 +6997,6 @@ var CHORD_INFO_HTML = `
6567
6997
  </ul>
6568
6998
  </div>
6569
6999
  `;
6570
- var MML_INFO_HTML = `
6571
- <div class="dtm-modal-body-content">
6572
- <h4>1. \u97F3\u7B26\u3068\u4F11\u7B26</h4>
6573
- <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>
6574
- <ul>
6575
- <li>\u534A\u97F3\u4E0A\u3052\u308B: <code>c#</code> \u307E\u305F\u306F <code>c+</code></li>
6576
- <li>\u534A\u97F3\u4E0B\u3052\u308B: <code>d-</code></li>
6577
- <li>\u4F11\u7B26: <code>r</code></li>
6578
- </ul>
6579
-
6580
- <h4>2. \u97F3\u306E\u9577\u3055</h4>
6581
- <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>
6582
- <ul>
6583
- <li><code>c4</code> : 4\u5206\u97F3\u7B26\u306E\u30C9</li>
6584
- <li><code>r8</code> : 8\u5206\u4F11\u7B26</li>
6585
- <li><code>c4.</code> : \u4ED8\u70B94\u5206\u97F3\u7B26\u306E\u30C9\uFF08\u9577\u3055\u30921.5\u500D\u306B\uFF09</li>
6586
- <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>
6587
- </ul>
6588
-
6589
- <h4>3. \u30AA\u30AF\u30BF\u30FC\u30D6\uFF08\u97F3\u306E\u9AD8\u3055\uFF09</h4>
6590
- <ul>
6591
- <li><code>o4</code>, <code>o5</code> : \u9AD8\u3055\u3092\u76F4\u63A5\u6307\u5B9A\uFF08\u3075\u3064\u3046\u306F o4 \u304B o5\uFF09</li>
6592
- <li><code>&gt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u308B</li>
6593
- <li><code>&lt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0B\u3052\u308B</li>
6594
- </ul>
6595
-
6596
- <h4>4. \u30C6\u30F3\u30DD</h4>
6597
- <ul>
6598
- <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>
6599
- </ul>
6600
-
6601
- <h4>5. \u548C\u97F3</h4>
6602
- <p>\u97F3\u7B26\u3092 <code>[</code> \u3068 <code>]</code> \u3067\u56F2\u3080\u3068\u540C\u6642\u306B\u767A\u97F3\u3057\u307E\u3059\u3002</p>
6603
- <pre>\u4F8B: [ceg]4 \uFF08\u30C9\u30FB\u30DF\u30FB\u30BD\u30924\u5206\u97F3\u7B26\u3067\u540C\u6642\u306B\u767A\u97F3\uFF09</pre>
6604
-
6605
- <h4>6. \u30C8\u30E9\u30C3\u30AF\u306E\u533A\u5207\u308A</h4>
6606
- <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>
6607
- <ul>
6608
- <li><code>@0</code>: \u30E1\u30ED\u30C7\u30A3</li>
6609
- <li><code>@1</code>: \u30B5\u30D6\u30E1\u30ED</li>
6610
- <li><code>@2</code>: \u30D9\u30FC\u30B9</li>
6611
- <li><code>@3</code>: \u4F34\u594F</li>
6612
- </ul>
6613
-
6614
- <h4>7. \u6B4C\u58F0\u30FB\u6B4C\u8A5E\u5165\u529B</h4>
6615
- <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>
6616
- <pre>\u4F8B: @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053</pre>
6617
- <p style="margin-top:4px; margin-bottom:16px;"><small>\uFF08\u97F3\u6E90\u540D\u306F <code>tsukuyomi</code> \u3084 <code>klatt</code>, <code>roze</code> \u306A\u3069\u306E\u97F3\u58F0\u30E2\u30C7\u30EB\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\uFF09</small></p>
6618
-
6619
- <h4 style="margin-top: 18px; border-top: 1px solid var(--dtm-border2); padding-top: 8px;">\u30B5\u30F3\u30D7\u30EB\u66F2\uFF08\u8A66\u8074\u30FB\u30B3\u30D4\u30FC\uFF09</h4>
6620
-
6621
- <!-- \u30B5\u30F3\u30D7\u30EB1 -->
6622
- <div class="dtm-modal-sample-box">
6623
- <div class="dtm-modal-sample-header">
6624
- <span class="dtm-modal-sample-tag">1. \u57FA\u672C\u306E\u30E1\u30ED\u30C7\u30A3</span>
6625
- <button class="dtm-btn dtm-btn--ghost dtm-btn--xs dtm-modal-sample-copy-btn" data-mml="@0 t120 l8 o5 c d e f g a b > c">\u{1F4CB} \u30B3\u30D4\u30FC</button>
6626
- </div>
6627
- <pre style="margin: 0; padding: 6px;">@0 t120 l8 o5 c d e f g a b &gt; c</pre>
6628
- <div class="dtm-modal-sample-desc">
6629
- \u57FA\u672C\u7684\u306A\u30E1\u30ED\u30C7\u30A3\u306E\u66F8\u304D\u65B9\uFF08\u97F3\u540D\u30FB\u9577\u3055\u30FB\u30AA\u30AF\u30BF\u30FC\u30D6\u3068\u30C6\u30F3\u30DD\uFF09\u3002
6630
- </div>
6631
- <div style="margin-top: 8px;">
6632
- <button class="dtm-btn dtm-btn--primary dtm-btn--xs dtm-modal-sample-play-btn" data-mml="@0 t120 l8 o5 c d e f g a b > c">\u25B6 \u8A66\u8074</button>
6633
- </div>
6634
- <div class="dtm-modal-sample-player-container"></div>
6635
- </div>
6636
-
6637
- <!-- \u30B5\u30F3\u30D7\u30EB2 -->
6638
- <div class="dtm-modal-sample-box">
6639
- <div class="dtm-modal-sample-header">
6640
- <span class="dtm-modal-sample-tag">2. \u8907\u6570\u30C8\u30E9\u30C3\u30AF\u3068\u548C\u97F3</span>
6641
- <button class="dtm-btn dtm-btn--ghost dtm-btn--xs dtm-modal-sample-copy-btn" data-mml="@0 t120 o5 c e g2 ; @3 o4 [ceg]2 [ceg]2">\u{1F4CB} \u30B3\u30D4\u30FC</button>
6642
- </div>
6643
- <pre style="margin: 0; padding: 6px;">@0 t120 o5 c e g2 ;
6644
- @3 o4 [ceg]2 [ceg]2</pre>
6645
- <div class="dtm-modal-sample-desc">
6646
- ; \u3067\u30C8\u30E9\u30C3\u30AF\uFF08\u4E0A\uFF1D\u30E1\u30ED\u30C7\u30A3\uFF0F\u4E0B\uFF1D\u4F34\u594F\uFF09\u3092\u5206\u3051\u3001[ceg] \u3067\u548C\u97F3\u3092\u9CF4\u3089\u3057\u307E\u3059\u3002
6647
- </div>
6648
- <div style="margin-top: 8px;">
6649
- <button class="dtm-btn dtm-btn--primary dtm-btn--xs dtm-modal-sample-play-btn" data-mml="@0 t120 o5 c e g2 ; @3 o4 [ceg]2 [ceg]2">\u25B6 \u8A66\u8074</button>
6650
- </div>
6651
- <div class="dtm-modal-sample-player-container"></div>
6652
- </div>
6653
-
6654
- <!-- \u30B5\u30F3\u30D7\u30EB3 -->
6655
- <div class="dtm-modal-sample-box">
6656
- <div class="dtm-modal-sample-header">
6657
- <span class="dtm-modal-sample-tag">3. \u6B4C\u5531\u4ED8\u304D (\u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D)</span>
6658
- <button class="dtm-btn dtm-btn--ghost dtm-btn--xs dtm-modal-sample-copy-btn" data-mml="@0 t120 v100 o4g8 g8 e8 e8 f8 e8 d8 c8 g8 g8 e8 e8 d4.; @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053;">\u{1F4CB} \u30B3\u30D4\u30FC</button>
6659
- </div>
6660
- <pre style="margin: 0; padding: 6px;">@0 t120 v100 o4g8 g8 e8 e8 f8 e8 d8 c8 g8 g8 e8 e8 d4.;
6661
- @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053;</pre>
6662
- <div class="dtm-modal-sample-desc">
6663
- @@0 tsukuyomi \u6B4C\u8A5E... \u3067\u30E1\u30ED\u30C7\u30A3\u30C8\u30E9\u30C3\u30AF\u306B\u6B4C\u8A5E\u3092\u540C\u671F\u3055\u305B\u3066\u6B4C\u308F\u305B\u307E\u3059\u3002\u203B\u72EC\u81EA\u62E1\u5F35
6664
- </div>
6665
- <div style="margin-top: 8px;">
6666
- <button class="dtm-btn dtm-btn--primary dtm-btn--xs dtm-modal-sample-play-btn" data-mml="@0 t120 v100 o4g8 g8 e8 e8 f8 e8 d8 c8 g8 g8 e8 e8 d4.; @@0 tsukuyomi \u3069\u3093\u3050\u308A\u3053\u308D\u3053\u308D\u3069\u3093\u3050\u308A\u3053;">\u25B6 \u8A66\u8074</button>
6667
- </div>
6668
- <div class="dtm-modal-sample-player-container"></div>
6669
- </div>
6670
- </div>
6671
- `;
6672
7000
  var MIDI_INFO_HTML = `
6673
7001
  <div class="dtm-modal-body-content">
6674
7002
  <h4>1. MIDI\u30D5\u30A1\u30A4\u30EB\u3068\u306F</h4>
@@ -8039,8 +8367,8 @@ var mountDAW = (target, options = {}) => {
8039
8367
  t.vocalPan = 64;
8040
8368
  t.vocalOctave = 0;
8041
8369
  }
8042
- lyrics?.forEach((lt, idx) => {
8043
- const t = trackStates[idx];
8370
+ lyrics?.forEach((lt) => {
8371
+ const t = trackStates[lt.trackId];
8044
8372
  if (!t) return;
8045
8373
  t.lyrics = lt.syllables.map((s) => s.kana).join("");
8046
8374
  t.lyricModel = lt.model;