danoniplus 47.4.0 → 47.5.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.
package/js/danoni_main.js CHANGED
@@ -4,12 +4,12 @@
4
4
  *
5
5
  * Source by tickle
6
6
  * Created : 2018/10/08
7
- * Revised : 2026/04/26
7
+ * Revised : 2026/05/02
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 47.4.0`;
12
- const g_revisedDate = `2026/04/26`;
11
+ const g_version = `Ver 47.5.0`;
12
+ const g_revisedDate = `2026/05/02`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -3385,17 +3385,15 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
3385
3385
  mmWidthBase: (g_sWidth - 500) / 2 + 290,
3386
3386
  mmMarginY: 2,
3387
3387
  get laneWidth() {
3388
- return Math.min(Math.floor((this.mmWidthBase - this.timeMargin) / keyNum), 40);
3388
+ return Math.min((this.mmWidthBase - this.timeMargin) / keyNum, 40);
3389
3389
  },
3390
3390
  get logicalWidth() {
3391
- return this.timeMargin + (this.laneWidth * keyNum);
3391
+ const logicalWidth = this.timeMargin + (this.laneWidth * keyNum);
3392
+ return Math.ceil(logicalWidth * this.dpr) / this.dpr;
3392
3393
  }
3393
3394
  },
3394
3395
  };
3395
3396
 
3396
- // ヘッダー生成
3397
- g_detailObj.scoreMinimapHeader[_scoreId] = createMinimapHeader(g_detailObj.miniMapParams[_scoreId].config, _keyCtrlPtn, keyNum);
3398
-
3399
3397
  // Canvas保存用配列を空で初期化
3400
3398
  g_detailObj.scoreMinimap[_scoreId] = null;
3401
3399
  g_detailObj.scoreMinimapReverse[_scoreId] = null;
@@ -3510,7 +3508,7 @@ const createMinimapHeader = (_config, _keyCtrlPtn, _keyNum) => {
3510
3508
  for (let j = 0; j < _keyNum; j++) {
3511
3509
  // config.laneWidth を使って中央座標を計算
3512
3510
  const x = timeMargin + j * laneWidth + laneWidth / 2;
3513
- const keyText = g_kCd[g_keyObj[`keyCtrl${_keyCtrlPtn}`][j][0]];
3511
+ const keyText = g_kCd[g_keyObj[`keyCtrl${_keyCtrlPtn}`][j][0]].split(` `).join(``);
3514
3512
 
3515
3513
  ctx.fillText(keyText, x, headerHeight / 2 + 2); // 視覚的な中央調整で +2px
3516
3514
  }
@@ -4612,8 +4610,11 @@ const headerConvert = _dosObj => {
4612
4610
 
4613
4611
  g_stateObj.scoreDetail = g_settings.scoreDetails[0] || ``;
4614
4612
  g_settings.scoreDetailCursors = g_settings.scoreDetails.map(val => `lnk${val}G`);
4613
+ g_settings.scoreDetailCursorsOrg = g_settings.scoreDetailCursors.concat();
4615
4614
  g_settings.scoreDetailCursors.push(`btnGraphB`);
4616
- [`option`, `difSelector`].forEach(page => g_shortcutObj[page].KeyQ.id = g_settings.scoreDetailCursors[0]);
4615
+ [`option`, `difSelector`, `scoreDetail`].forEach(page => g_shortcutObj[page].KeyQ.id = g_settings.scoreDetailCursors[0]);
4616
+ g_shortcutObj.scoreDetail.ArrowDown.id = g_settings.scoreDetailCursorsOrg[0];
4617
+ g_shortcutObj.scoreDetail.ArrowUp.id = g_settings.scoreDetailCursorsOrg[nextPos(0, -1, g_settings.scoreDetailCursorsOrg.length)];
4617
4618
 
4618
4619
  // 判定位置をBackgroundのON/OFFと連動してリセットする設定
4619
4620
  obj.jdgPosReset = setBoolVal(_dosObj.jdgPosReset, true);
@@ -7290,7 +7291,6 @@ const drawSpeedGraph = _scoreId => {
7290
7291
  speed: { frame: [0], speed: [1], cnt: 0, strokeColor: g_graphColorObj.speed },
7291
7292
  boost: { frame: [0], speed: [1], cnt: 0, strokeColor: g_graphColorObj.boost }
7292
7293
  };
7293
- const dpr = window.devicePixelRatio || 1;
7294
7294
 
7295
7295
  const tmpSpeedPoint = [0];
7296
7296
  Object.keys(speedObj).forEach(speedType => {
@@ -7509,7 +7509,7 @@ const updateScoreDetailLabel = (_name, _label, _value, _pos = 0, _labelname = _l
7509
7509
  const baseLabel = (_bLabel, _bLabelname, _bAlign) =>
7510
7510
  document.getElementById(`detail${_name}`).appendChild(
7511
7511
  createDivCss2Label(_bLabel, _bLabelname, {
7512
- x: 10, y: 110 + _pos * 20, w: 100, h: 20, siz: g_limitObj.difSelectorSiz, align: _bAlign,
7512
+ x: 10, y: 130 + _pos * 16, w: 100, h: 16, siz: g_limitObj.difSelectorSiz, align: _bAlign,
7513
7513
  })
7514
7514
  );
7515
7515
  if (document.getElementById(`data${_label}`) === null) {
@@ -7880,9 +7880,14 @@ const drawMinimap = (_scoreId, { _initFlg = false, _fadeinFlg = false } = {}) =>
7880
7880
  ? g_detailObj.scoreMinimapReverse[_scoreId]
7881
7881
  : g_detailObj.scoreMinimap[_scoreId];
7882
7882
 
7883
+ const params = g_detailObj.miniMapParams[_scoreId];
7884
+ const kPtn = params._keyCtrlPtn;
7885
+ if (!g_detailObj.scoreMinimapHeader[kPtn]) {
7886
+ // ヘッダーはキー種ごとに共通なので、未作成の場合のみ生成してキャッシュ
7887
+ g_detailObj.scoreMinimapHeader[kPtn] = createMinimapHeader(params.config, kPtn, params._keyNum);
7888
+ }
7883
7889
  if (!savedCanvases) {
7884
7890
  // 未作成の場合のみミニマップを生成(Lazy Generation)
7885
- const params = g_detailObj.miniMapParams[_scoreId];
7886
7891
  savedCanvases = generateMinimapData(params, isRev);
7887
7892
 
7888
7893
  // 生成したものをキャッシュに保存
@@ -7896,7 +7901,7 @@ const drawMinimap = (_scoreId, { _initFlg = false, _fadeinFlg = false } = {}) =>
7896
7901
  // --- ヘッダー部分 ---
7897
7902
  const detailMiniMapHeader = createEmptySprite(detailMiniMap, `detailMiniMapHeader`, g_windowObj.detailMiniMapHeader);
7898
7903
  $id(`detailMiniMapHeader`).top = (g_stateObj.miniMapRevFlg ? 230 + g_sHeight - 500 : 0) + `px`;
7899
- detailMiniMapHeader.appendChild(g_detailObj.scoreMinimapHeader[_scoreId]);
7904
+ detailMiniMapHeader.appendChild(g_detailObj.scoreMinimapHeader[kPtn]);
7900
7905
 
7901
7906
  // --- メイン(譜面)部分 ---
7902
7907
  const detailMiniMapSub = createEmptySprite(detailMiniMap, `detailMiniMapSub`, g_windowObj.detailMiniMapSub);
@@ -8243,7 +8248,6 @@ const createOptionWindow = _sprite => {
8243
8248
  graphObj.style.top = wUnit(0);
8244
8249
  graphObj.style.position = `absolute`;
8245
8250
  graphObj.style.background = j === 0 ? bkColor : `#ffffff00`;
8246
- graphObj.style.border = `dotted ${wUnit(2)}`;
8247
8251
  const ctx = graphObj.getContext(`2d`);
8248
8252
  ctx.scale(dpr, dpr);
8249
8253
 
@@ -8275,6 +8279,8 @@ const createOptionWindow = _sprite => {
8275
8279
  if (g_currentPage === `difSelector`) {
8276
8280
  resetDifWindow();
8277
8281
  }
8282
+ g_currentPage = `scoreDetail`;
8283
+ setShortcutEvent(g_currentPage, () => true, { displayFlg: false });
8278
8284
  g_stateObj.scoreDetailViewFlg = true;
8279
8285
  scoreDetail.style.visibility = `visible`;
8280
8286
  visibleSettingSummary(false);
@@ -8286,7 +8292,9 @@ const createOptionWindow = _sprite => {
8286
8292
  // 選択先を表示、ボタン色を選択中に変更
8287
8293
  // Qキーを押したときのリンク先を次の明細へ変更
8288
8294
  g_stateObj.scoreDetail = g_settings.scoreDetails[_val];
8289
- [`option`, `difSelector`].forEach(page => g_shortcutObj[page].KeyQ.id = g_settings.scoreDetailCursors[(_val + 1) % g_settings.scoreDetailCursors.length]);
8295
+ [`option`, `difSelector`, `scoreDetail`].forEach(page => g_shortcutObj[page].KeyQ.id = g_settings.scoreDetailCursors[nextPos(_val, 1, g_settings.scoreDetailCursors.length)]);
8296
+ g_shortcutObj.scoreDetail.ArrowDown.id = g_settings.scoreDetailCursorsOrg[nextPos(_val, 1, g_settings.scoreDetailCursorsOrg.length)];
8297
+ g_shortcutObj.scoreDetail.ArrowUp.id = g_settings.scoreDetailCursorsOrg[nextPos(_val, -1, g_settings.scoreDetailCursorsOrg.length)];
8290
8298
 
8291
8299
  $id(`detail${g_stateObj.scoreDetail}`).visibility = `visible`;
8292
8300
  document.getElementById(`lnk${g_stateObj.scoreDetail}G`).classList.replace(g_cssObj.button_Default, g_cssObj.button_Setting);
@@ -8332,9 +8340,12 @@ const createOptionWindow = _sprite => {
8332
8340
  detailObj.style.visibility = visibles[Number(g_stateObj.scoreDetailViewFlg)];
8333
8341
  visibleSettingSummary(g_stateObj.scoreDetailViewFlg ? false : g_stateObj.settingSummaryVisible);
8334
8342
 
8335
- // Qキーを押したときのカーソル位置を先頭に初期化
8336
- if (_resetFlg) {
8337
- g_shortcutObj.option.KeyQ.id = g_settings.scoreDetailCursors[0];
8343
+ g_currentPage = g_stateObj.scoreDetailViewFlg ? `scoreDetail` : `option`;
8344
+ setShortcutEvent(g_currentPage, () => true, { displayFlg: false });
8345
+
8346
+ // Qキーのカーソル位置は、ハードリセットまたはスコア明細を閉じるときに先頭へ戻す
8347
+ if (_resetFlg || !g_stateObj.scoreDetailViewFlg) {
8348
+ [`option`, `difSelector`, `scoreDetail`].forEach(page => g_shortcutObj[page].KeyQ.id = g_settings.scoreDetailCursors[0]);
8338
8349
  }
8339
8350
  document.getElementById(`lnkMiniMapRev`).style.display =
8340
8351
  g_stateObj.scoreDetail === `MiniMap` && g_stateObj.scoreDetailViewFlg ? C_DIS_INHERIT : C_DIS_NONE;
@@ -12956,7 +12967,6 @@ const mainInit = () => {
12956
12967
  const dummyArrowCnts = fillArray(keyNum);
12957
12968
  const dummyFrzCnts = fillArray(keyNum);
12958
12969
  let speedCnts = 0;
12959
- let boostCnts = 0;
12960
12970
  let keychCnts = 0;
12961
12971
 
12962
12972
  g_workObj.flatMode = g_stateObj.d_stepzone === `FlatBar` ||
@@ -13123,7 +13133,8 @@ const mainInit = () => {
13123
13133
 
13124
13134
  const makerView = g_headerObj.makerView ? ` (${g_headerObj.creatorNames[g_stateObj.scoreId]})` : ``;
13125
13135
  const transKeyName = getTransKeyName();
13126
- let difName = `[${getKeyName(g_headerObj.keyLabels[g_stateObj.scoreId])}${transKeyName} / ${g_headerObj.difLabels[g_stateObj.scoreId]}${assistFlg}${shuffleName}${makerView}]`;
13136
+ const autoAll = g_stateObj.autoAll === C_FLG_ON ? ` &gt; AutoPlay` : ``;
13137
+ let difName = `[${getKeyName(g_headerObj.keyLabels[g_stateObj.scoreId])}${transKeyName} / ${g_headerObj.difLabels[g_stateObj.scoreId]}${assistFlg}${shuffleName}${makerView}${autoAll}]`;
13127
13138
  let creditName = `${musicTitle} / ${artistName}`;
13128
13139
  if (checkMusicSiz(creditName, g_limitObj.musicTitleSiz) < 12) {
13129
13140
  creditName = `${musicTitle}`;
@@ -13557,6 +13568,10 @@ const mainInit = () => {
13557
13568
  }
13558
13569
  },
13559
13570
 
13571
+ get dummyArrowON() {
13572
+ return this.dummyArrowOFF;
13573
+ },
13574
+
13560
13575
  // フリーズアロー(成功時)
13561
13576
  frzOK: (_j, _k, _frzName, _cnt) => {
13562
13577
  judgeKita(_cnt);
@@ -13600,10 +13615,11 @@ const mainInit = () => {
13600
13615
 
13601
13616
  // ダミーフリーズアロー(キーを離したときの処理)
13602
13617
  // ※処理上通ることはないが、統一のために定義
13603
- dummyFrzKeyUp: (_j, _k, _frzName, _cnt) => { },
13618
+ get dummyFrzKeyUp() {
13619
+ return this.dummyFrzNG;
13620
+ }
13604
13621
 
13605
13622
  };
13606
- judgeMotionFunc.dummyArrowON = (_j, _arrowName, _cnt) => judgeMotionFunc.dummyArrowOFF(_j, _arrowName, _cnt);
13607
13623
 
13608
13624
  /**
13609
13625
  * 次矢印・フリーズアローへ判定を移すかチェック
@@ -13641,8 +13657,12 @@ const mainInit = () => {
13641
13657
  },
13642
13658
 
13643
13659
  arrowON: (_j, _k, _cnt) => true,
13644
- dummyArrowOFF: (_j, _k, _cnt) => true,
13645
- dummyArrowON: (_j, _k, _cnt) => true,
13660
+ get dummyArrowOFF() {
13661
+ return this.arrowON;
13662
+ },
13663
+ get dummyArrowON() {
13664
+ return this.arrowON;
13665
+ },
13646
13666
 
13647
13667
  frzOFF: (_j, _k, _cnt) => {
13648
13668
 
@@ -13682,10 +13702,8 @@ const mainInit = () => {
13682
13702
  changeHitFrz(_j, _k, `dummyFrz`);
13683
13703
  }
13684
13704
  },
13685
- dummyFrzON: (_j, _k, _cnt) => {
13686
- if (_cnt === 0) {
13687
- changeHitFrz(_j, _k, `dummyFrz`);
13688
- }
13705
+ get dummyFrzON() {
13706
+ return this.dummyFrzOFF;
13689
13707
  },
13690
13708
  };
13691
13709
 
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/04/25 (v47.3.2)
8
+ * Revised : 2026/05/02 (v47.5.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -489,31 +489,31 @@ const updateWindowSiz = () => {
489
489
  x: 290, y: 145, w: 120, h: 20, siz: 50, align: C_ALIGN_CENTER,
490
490
  },
491
491
  lblSpdHeader: {
492
- x: 5, y: 180, w: 100, h: 20, siz: g_limitObj.difSelectorSiz, align: C_ALIGN_LEFT,
492
+ x: 5, y: 190, w: 100, h: 20, siz: g_limitObj.difSelectorSiz, align: C_ALIGN_LEFT,
493
493
  },
494
494
  lblSpdBase: {
495
- x: 0, y: 200, w: 40, h: 20, siz: 11.5, fontWeight: `bold`,
495
+ x: 0, y: 210, w: 40, h: 20, siz: 11.5, fontWeight: `bold`,
496
496
  },
497
497
  lblSpdOverall: {
498
- x: 40, y: 200, w: 40, h: 20, siz: 11.5,
498
+ x: 40, y: 210, w: 40, h: 20, siz: 11.5,
499
499
  color: g_graphColorObj.speedChara, fontWeight: `bold`,
500
500
  },
501
501
  lblSpdBoost: {
502
- x: 80, y: 200, w: 40, h: 20, siz: 11.5,
502
+ x: 80, y: 210, w: 40, h: 20, siz: 11.5,
503
503
  color: g_graphColorObj.boostChara, fontWeight: `bold`,
504
504
  },
505
505
  lblSpdTotal: {
506
- x: 5, y: 215, w: 100, h: 20, siz: g_limitObj.difSelectorSiz,
506
+ x: 5, y: 225, w: 100, h: 20, siz: g_limitObj.difSelectorSiz,
507
507
  align: C_ALIGN_LEFT, fontWeight: `bold`,
508
508
  },
509
509
  lblSpdFrame: {
510
- x: 70, y: 218, w: 50, h: 20, siz: 12, fontWeight: `bold`,
510
+ x: 70, y: 228, w: 50, h: 20, siz: 12, fontWeight: `bold`,
511
511
  },
512
512
  btnSpdCursorL: {
513
- x: 85, y: 180, w: 15, h: 20, siz: 12,
513
+ x: 85, y: 190, w: 15, h: 20, siz: 12,
514
514
  },
515
515
  btnSpdCursorR: {
516
- x: 100, y: 180, w: 15, h: 20, siz: 12,
516
+ x: 100, y: 190, w: 15, h: 20, siz: 12,
517
517
  },
518
518
  lnkMiniMapRev: {
519
519
  w: g_limitObj.difCoverWidth, h: 20, borderStyle: `solid`,
@@ -2762,7 +2762,6 @@ const g_shortcutObj = {
2762
2762
  Numpad5: { id: `lnkMiniMapG` },
2763
2763
  KeyQ: { id: `lnkDensityG` },
2764
2764
  KeyP: { id: `lnkDifInfo` },
2765
- KeyX: { id: `lnkMiniMapRev` },
2766
2765
  ControlLeft_KeyC: { id: `` },
2767
2766
  ControlRight_KeyC: { id: `` },
2768
2767
  KeyC: { id: `lnkHighScore`, reset: true },
@@ -2776,6 +2775,53 @@ const g_shortcutObj = {
2776
2775
  Tab: { id: `btnDisplay` },
2777
2776
  KeyU: { id: `btnSettingSummary` },
2778
2777
  },
2778
+ scoreDetail: {
2779
+ ShiftLeft_KeyD: { id: `lnkDifficultyL` },
2780
+ ShiftRight_KeyD: { id: `lnkDifficultyL` },
2781
+ KeyD: { id: `lnkDifficultyR` },
2782
+ KeyL: { id: `lnkDifficulty` },
2783
+
2784
+ ShiftLeft_ArrowRight: { id: `lnkSpeedR` },
2785
+ ShiftRight_ArrowRight: { id: `lnkSpeedR` },
2786
+ AltLeft_ArrowRight: { id: `lnkSpeedHR` },
2787
+ AltRight_ArrowRight: { id: `lnkSpeedHR` },
2788
+ ArrowRight: { id: `lnkSpeedRR` },
2789
+ ShiftLeft_ArrowLeft: { id: `lnkSpeedL` },
2790
+ ShiftRight_ArrowLeft: { id: `lnkSpeedL` },
2791
+ AltLeft_ArrowLeft: { id: `lnkSpeedHL` },
2792
+ AltRight_ArrowLeft: { id: `lnkSpeedHL` },
2793
+ ArrowLeft: { id: `lnkSpeedLL` },
2794
+
2795
+ ArrowDown: { id: `lnkDensityG` },
2796
+ ArrowUp: { id: `lnkDensityG` },
2797
+
2798
+ KeyI: { id: `btnGraph` },
2799
+ Digit1: { id: `lnkDensityG` },
2800
+ Digit2: { id: `lnkSpeedG` },
2801
+ Digit3: { id: `lnkToolDifG` },
2802
+ Digit4: { id: `lnkHighScoreG` },
2803
+ Digit5: { id: `lnkMiniMapG` },
2804
+ Numpad1: { id: `lnkDensityG` },
2805
+ Numpad2: { id: `lnkSpeedG` },
2806
+ Numpad3: { id: `lnkToolDifG` },
2807
+ Numpad4: { id: `lnkHighScoreG` },
2808
+ Numpad5: { id: `lnkMiniMapG` },
2809
+ KeyQ: { id: `lnkDensityG` },
2810
+ KeyP: { id: `lnkDifInfo` },
2811
+ KeyX: { id: `lnkMiniMapRev` },
2812
+ ControlLeft_KeyC: { id: `` },
2813
+ ControlRight_KeyC: { id: `` },
2814
+ KeyC: { id: `lnkHighScore`, reset: true },
2815
+
2816
+ Escape: { id: `btnBack` },
2817
+ Space: { id: `btnKeyConfig` },
2818
+ Enter: { id: `btnPlay` },
2819
+ NumpadEnter: { id: `btnPlay` },
2820
+ ShiftLeft_Tab: { id: `btnBack` },
2821
+ ShiftRight_Tab: { id: `btnBack` },
2822
+ Tab: { id: `btnDisplay` },
2823
+ KeyU: { id: `btnSettingSummary` },
2824
+ },
2779
2825
  settingsDisplay: {
2780
2826
  ShiftLeft_KeyA: { id: `lnkAppearanceL` },
2781
2827
  ShiftRight_KeyA: { id: `lnkAppearanceL` },
@@ -2987,7 +3033,8 @@ const g_btnPatterns = {
2987
3033
  dataMgt: { Back: 0, Environment: -35, Highscores: -35, CustomKey: -35, Others: -35 },
2988
3034
  precondition: { Back: 0 },
2989
3035
  option: { Back: 0, KeyConfig: 0, Play: 0, Display: -5, Save: -10, Graph: -25, SettingSummary: -10 },
2990
- difSelector: { SettingSummary: -10 },
3036
+ difSelector: {},
3037
+ scoreDetail: {},
2991
3038
  settingsDisplay: { Back: 0, KeyConfig: 0, Play: 0, Save: -10, Settings: -5, SettingSummary: -10 },
2992
3039
  exSetting: { Back: 0, KeyConfig: 0, Play: 0, exSetting: -5, Save: -10, SettingSummary: -10 },
2993
3040
  loadingIos: { Play: 0 },
@@ -4844,6 +4891,7 @@ const g_lang_msgObj = {
4844
4891
  lnkDensityG: `譜面の密度状況を表示`,
4845
4892
  lnkToolDifG: `譜面の難易度、矢印・フリーズアローの分布状況を表示`,
4846
4893
  lnkHighScoreG: `譜面のハイスコアを表示`,
4894
+ lnkMiniMapG: `譜面内容をミニマップで表示`,
4847
4895
  lnkDifInfo: `譜面の難易度、矢印・フリーズアローの分布状況をクリップボードへコピー`,
4848
4896
  lnkResetHighScore: `譜面のハイスコア情報を消去`,
4849
4897
  lnkHighScore: `譜面のハイスコアをクリップボードへコピー`,
@@ -4944,6 +4992,7 @@ const g_lang_msgObj = {
4944
4992
  lnkDensityG: `Displays the density status of the chart.`,
4945
4993
  lnkToolDifG: `Displays the difficulty level of the chart and the distribution of arrows and freeze arrows.`,
4946
4994
  lnkHighScoreG: `Displays the high score of the chart.`,
4995
+ lnkMiniMapG: `Display chart on the minimap.`,
4947
4996
  lnkDifInfo: `Copy the difficulty of the chart and the distribution of arrows and freeze arrows to the clipboard.`,
4948
4997
  lnkResetHighScore: `Erase the high score information in the chart.`,
4949
4998
  lnkHighScore: `Copies the high score of the chart to the clipboard.`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "47.4.0",
3
+ "version": "47.5.0",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "./js/danoni_main.js",
6
6
  "jsdelivr": "./js/danoni_main.js",