danoniplus 51.2.2 → 51.3.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/10/07
7
+ * Revised : 2026/10/10
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 51.2.2`;
12
- const g_revisedDate = `2026/10/07`;
11
+ const g_version = `Ver 51.3.0`;
12
+ const g_revisedDate = `2026/10/10`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/10/03 (v51.2.0)
8
+ * Revised : 2026/10/10 (v51.3.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -2353,6 +2353,9 @@ const g_keycons = {
2353
2353
  cursorNum: 0,
2354
2354
  keySwitchNum: 0,
2355
2355
  colorCursorNum: 0,
2356
+
2357
+ shortcutTypes: [`Retry`, `TitleBack`, `Pause`],
2358
+ defaultShortCuts: { Retry: C_KEY_RETRY, TitleBack: C_KEY_TITLEBACK, Pause: C_KEY_PAUSE },
2356
2359
  };
2357
2360
 
2358
2361
  let g_displays = [`stepZone`, `judgment`, `lifeGauge`, `score`, `musicInfo`, `filterLine`,
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2026/09/13
8
- * Revised : 2026/10/07 (v51.2.2)
8
+ * Revised : 2026/10/10 (v51.3.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -2580,10 +2580,22 @@ const getArrowSettings = (_retryFlg = false) => {
2580
2580
  storageObj[`keyCtrl${addKey}`] = setKeyCtrl(g_localKeyStorage, keyNum, keyCtrlPtn);
2581
2581
  if (g_keyObj.currentPtn !== -1) {
2582
2582
  storageObj[`keyCtrlPtn${addKey}`] = g_keyObj.currentPtn;
2583
+ g_keyObj.storagePtn = g_keyObj.currentPtn;
2583
2584
  g_keyCtrlBackup[keyCtrlPtn] = structuredClone(g_keyObj[`keyCtrl${keyCtrlPtn}`]);
2584
2585
  g_keyObj[`keyCtrl${keyCtrlPtn}`] = structuredClone(g_keyObj[`keyCtrl${keyCtrlPtn}d`]);
2585
2586
  }
2586
2587
 
2588
+ // ショートカットキーの保存(基盤パターンのデフォルトと異なるものだけ)
2589
+ const savedShortcut = {};
2590
+ const isDefaultShortcut = _type => g_headerObj[`key${_type}`] === getDefaultShortcut(_type);
2591
+ g_keycons.shortcutTypes.filter(type => !isDefaultShortcut(type))
2592
+ .forEach(type => savedShortcut[type] = g_headerObj[`key${type}`]);
2593
+ if (Object.keys(savedShortcut).length > 0) {
2594
+ storageObj[`shortcut${addKey}`] = savedShortcut;
2595
+ } else {
2596
+ delete storageObj[`shortcut${addKey}`];
2597
+ }
2598
+
2587
2599
  // カラーセットの保存(キー別)
2588
2600
  if (!g_keycons.colorDefTypes.includes(g_colorType)) {
2589
2601
 
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2026/09/13
8
- * Revised : 2026/09/27 (v51.1.0)
8
+ * Revised : 2026/10/10 (v51.3.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -1182,13 +1182,10 @@ const headerConvert = _dosObj => {
1182
1182
 
1183
1183
  // プレイ中のショートカットキー
1184
1184
  obj.keyRetry = setIntVal(getKeyCtrlVal(_dosObj.keyRetry), C_KEY_RETRY);
1185
- obj.keyRetryDef = obj.keyRetry;
1186
1185
  obj.keyRetryDef2 = obj.keyRetry;
1187
1186
  obj.keyTitleBack = setIntVal(getKeyCtrlVal(_dosObj.keyTitleBack), C_KEY_TITLEBACK);
1188
- obj.keyTitleBackDef = obj.keyTitleBack;
1189
1187
  obj.keyTitleBackDef2 = obj.keyTitleBack;
1190
1188
  obj.keyPause = setIntVal(getKeyCtrlVal(_dosObj.keyPause), C_KEY_PAUSE);
1191
- obj.keyPauseDef = obj.keyPause;
1192
1189
  obj.keyPauseDef2 = obj.keyPause;
1193
1190
 
1194
1191
  // フリーズアローの許容フレーム数設定
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2026/09/13
8
- * Revised : 2026/09/23 (v51.0.0)
8
+ * Revised : 2026/10/10 (v51.3.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -480,6 +480,21 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
480
480
  viewGroup(_type);
481
481
  };
482
482
 
483
+ /**
484
+ * ショートカットキーボタンの表示更新
485
+ * @param {string} _type Retry / TitleBack / Pause
486
+ */
487
+ const updateScButton = _type => {
488
+ const siz = wUnit(getFontSize2(getScMsg[_type](), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
489
+ document.getElementById(`sc${_type}`).textContent = getScMsg[_type]();
490
+ document.getElementById(`sc${_type}`).style.fontSize = siz;
491
+ if (g_isMac) {
492
+ scTitleBack.textContent = getScMsg.TitleBack();
493
+ scTitleBack.style.fontSize = wUnit(getFontSize2(getScMsg.TitleBack(), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
494
+ }
495
+ changeConfigColor(document.getElementById(`sc${_type}`), getScButtonColor(_type));
496
+ };
497
+
483
498
  const kcSubX = parseFloat(keyconSprite.style.width) * ((1 - g_keyObj.scale) / 4);
484
499
  const kcSubY = parseFloat(keyconSprite.style.height) / ((1 + g_keyObj.scale) / 2) - parseFloat(keyconSprite.style.height);
485
500
  multiAppend(divRoot,
@@ -494,27 +509,21 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
494
509
  cursor.style.top = wUnit(g_sHeight - 160 + kcSubY);
495
510
  selectedKc = `TitleBack`;
496
511
  }
497
- }, g_lblPosObj.scTitleBack, g_cssObj.button_Default_NoColor,
498
- g_headerObj.keyTitleBack === g_headerObj.keyTitleBackDef2 ?
499
- g_cssObj.title_base : g_cssObj.keyconfig_Changekey),
512
+ }, g_lblPosObj.scTitleBack, g_cssObj.button_Default_NoColor, getScButtonColor(`TitleBack`)),
500
513
 
501
514
  // リトライのショートカットキー変更
502
515
  createCss2Button(`scRetry`, getScMsg.Retry(), () => {
503
516
  cursor.style.left = wUnit(g_btnX(1 / 2) + kcSubX);
504
517
  cursor.style.top = wUnit(g_sHeight - 160 + kcSubY);
505
518
  selectedKc = `Retry`;
506
- }, g_lblPosObj.scRetry, g_cssObj.button_Default_NoColor,
507
- g_headerObj.keyRetry === g_headerObj.keyRetryDef2 ?
508
- g_cssObj.title_base : g_cssObj.keyconfig_Changekey),
519
+ }, g_lblPosObj.scRetry, g_cssObj.button_Default_NoColor, getScButtonColor(`Retry`)),
509
520
 
510
521
  // ポーズのショートカットキー変更
511
522
  createCss2Button(`scPause`, getScMsg.Pause(), () => {
512
523
  cursor.style.left = wUnit(g_btnX(3 / 4) + kcSubX);
513
524
  cursor.style.top = wUnit(g_sHeight - 160 + kcSubY);
514
525
  selectedKc = `Pause`;
515
- }, g_lblPosObj.scPause, g_cssObj.button_Default_NoColor,
516
- g_headerObj.keyPause === g_headerObj.keyPauseDef2 ?
517
- g_cssObj.title_base : g_cssObj.keyconfig_Changekey),
526
+ }, g_lblPosObj.scPause, g_cssObj.button_Default_NoColor, getScButtonColor(`Pause`)),
518
527
 
519
528
  // 別キーモード警告メッセージ
520
529
  createDivCss2Label(
@@ -973,6 +982,10 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
973
982
  changeKeyConfigColor(j, k, g_keyObj.currentPtn === -1 ? g_cssObj.keyconfig_Defaultkey : g_cssObj.title_base);
974
983
  }
975
984
  }
985
+ g_keycons.shortcutTypes.forEach(type => {
986
+ g_headerObj[`key${type}`] = getDefaultShortcut(type);
987
+ updateScButton(type);
988
+ });
976
989
  changeConfigCursor(0);
977
990
  }
978
991
  }, g_lblPosObj.btnKcReset, g_cssObj.button_Reset),
@@ -1035,17 +1048,7 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
1035
1048
  }
1036
1049
  // プレイ中ショートカットキー変更
1037
1050
  g_headerObj[`key${selectedKc}`] = setKey;
1038
- g_headerObj[`key${selectedKc}Def`] = setKey;
1039
- document.getElementById(`sc${selectedKc}`).textContent = getScMsg[selectedKc]();
1040
- document.getElementById(`sc${selectedKc}`).style.fontSize =
1041
- wUnit(getFontSize2(getScMsg[selectedKc](), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
1042
- if (g_isMac) {
1043
- scTitleBack.textContent = getScMsg.TitleBack();
1044
- scTitleBack.style.fontSize = wUnit(getFontSize2(getScMsg.TitleBack(), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
1045
- }
1046
- changeConfigColor(document.getElementById(`sc${selectedKc}`),
1047
- g_headerObj[`key${selectedKc}`] === g_headerObj[`key${selectedKc}Def2`] ?
1048
- g_cssObj.title_base : g_cssObj.keyconfig_Changekey);
1051
+ updateScButton(selectedKc);
1049
1052
  return;
1050
1053
  }
1051
1054
 
@@ -1131,6 +1134,61 @@ const completeTransKeyPtn = (_keyList) => {
1131
1134
  });
1132
1135
  };
1133
1136
 
1137
+ /**
1138
+ * 別キーモード時、移行先キーが保持するSelf保存パターンの取得可否チェック
1139
+ * @param {string} _keyCtrlPtn 例: "7_2"
1140
+ * @returns {number[][]|undefined} 適用可能な場合はSelf保存済みkeyCtrl配列、不可ならundefined
1141
+ */
1142
+ const getTransKeySelfCtrl = (_keyCtrlPtn) => {
1143
+ const transKeyName = g_keyObj[`transKey${_keyCtrlPtn}`];
1144
+ const transKeyPtn = g_keyObj[`transKeyPtn${_keyCtrlPtn}`];
1145
+ if (!hasVal(transKeyName) || transKeyPtn === undefined) {
1146
+ return undefined;
1147
+ }
1148
+ const [storageObj, addKey] = getKeyStorageObjByName(transKeyName);
1149
+ const savedCtrl = storageObj[`keyCtrl${addKey}`];
1150
+ const savedPtn = storageObj[`keyCtrlPtn${addKey}`];
1151
+
1152
+ if (savedPtn !== transKeyPtn) {
1153
+ return undefined;
1154
+ }
1155
+
1156
+ // 現在のキー配置(基準形状)とレーン数・各レーン長が完全一致することを確認
1157
+ const baseCtrl = g_keyObj[`keyCtrl${_keyCtrlPtn}`];
1158
+ const isValidShape = hasArrayList(savedCtrl, baseCtrl.length) &&
1159
+ savedCtrl.length === baseCtrl.length &&
1160
+ baseCtrl.every((lane, j) => hasArrayList(savedCtrl[j], lane.length) && savedCtrl[j].length === lane.length);
1161
+
1162
+ return isValidShape ? savedCtrl : undefined;
1163
+ };
1164
+
1165
+ /**
1166
+ * 別キーモードの移行先Selfパターンを現在のキー配置へ反映(保存はしない)
1167
+ */
1168
+ const applyTransKeySelfPattern = () => {
1169
+ const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
1170
+ const savedCtrl = getTransKeySelfCtrl(keyCtrlPtn);
1171
+ if (savedCtrl === undefined) {
1172
+ return;
1173
+ }
1174
+ const baseKeyNum = g_keyObj[`${g_keyObj.defaultProp}${keyCtrlPtn}`].length;
1175
+ for (let j = 0; j < baseKeyNum; j++) {
1176
+ for (let k = 0; k < (savedCtrl[j]?.length ?? 0); k++) {
1177
+ g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(savedCtrl[j][k], 0);
1178
+ }
1179
+ }
1180
+ // ショートカットも取込元の保存内容で上書き(レーンキーと重複するものは無視)
1181
+ const [storageObj, addKey] = getKeyStorageObjByName(g_keyObj[`transKey${keyCtrlPtn}`]);
1182
+ const savedShortcut = storageObj[`shortcut${addKey}`] ?? {};
1183
+ const usedKeys = g_keyObj[`keyCtrl${keyCtrlPtn}`].flat();
1184
+ g_keycons.shortcutTypes.forEach(type => {
1185
+ const savedKey = savedShortcut[type];
1186
+ g_headerObj[`key${type}`] = (savedKey !== undefined && !usedKeys.includes(savedKey))
1187
+ ? savedKey : getDefaultShortcut(type);
1188
+ });
1189
+ keyConfigInit();
1190
+ };
1191
+
1134
1192
  // KeyLockボタンを押したときの表示切替
1135
1193
  const toggleKcDesc = () => {
1136
1194
  if (document.getElementById(`kcDesc`) !== null) {
@@ -1152,6 +1210,44 @@ const getKcDescMsg = () =>
1152
1210
  const getKeyLockName = () =>
1153
1211
  `${g_lblNameObj.b_keyLock}${g_stateObj.keyLockFlg ? g_emojiObj.locked : g_emojiObj.unlocked}`;
1154
1212
 
1213
+ /** 保存・Self時に基準とするキーパターン番号 */
1214
+ const getBasePtn = () => g_keyObj.currentPtn === -1 ? g_keyObj.storagePtn : g_keyObj.currentPtn;
1215
+
1216
+ /**
1217
+ * ショートカットキーのデフォルト値(基盤パターン基準)
1218
+ * 優先順: ヘッダー指定 > パターン別定義(keyRetryX_Y等) > 定数
1219
+ * @params {string} _type Retry / TitleBack / Pause
1220
+ * @returns {number}
1221
+ */
1222
+ const getDefaultShortcut = _type => {
1223
+ const baseVal = g_keycons.defaultShortCuts[_type];
1224
+ const headerVal = g_headerObj[`key${_type}Def2`];
1225
+ if (headerVal !== baseVal) {
1226
+ return headerVal;
1227
+ }
1228
+ return setIntVal(getKeyCtrlVal(g_keyObj[`key${_type}${g_keyObj.currentKey}_${getBasePtn()}`]), headerVal);
1229
+ };
1230
+
1231
+ /**
1232
+ * ショートカットキーボタンの色クラスを取得
1233
+ * - ロード済みの保存値(Self)と同じ: Defaultkey
1234
+ * - 基準値(保存値 or パターンのデフォルト)と違う: Changekey
1235
+ * - 通常パターンでデフォルトのまま: title_base
1236
+ * @param {string} _type Retry / TitleBack / Pause
1237
+ * @returns {string}
1238
+ */
1239
+ const getScButtonColor = _type => {
1240
+ const current = g_headerObj[`key${_type}`];
1241
+ const loaded = g_keyObj.currentPtn === -1
1242
+ ? g_keyObj[`shortcut${g_keyObj.currentKey}_-1`]?.[_type] : undefined;
1243
+
1244
+ // ロード済みの保存値のまま
1245
+ if (loaded !== undefined && current === loaded) {
1246
+ return g_cssObj.keyconfig_Defaultkey;
1247
+ }
1248
+ // 本当のデフォルト(BackSpace/Delete/Pause)と違う場合は、変更の経緯を問わずChangekey
1249
+ return current !== g_keycons.defaultShortCuts[_type] ? g_cssObj.keyconfig_Changekey : g_cssObj.title_base;
1250
+ };
1155
1251
  /**
1156
1252
  * キーボードレイアウトプレビュー(Canvas版)
1157
1253
  *
@@ -1826,19 +1922,18 @@ const getShadowColor = (_colorPos, _arrowColor) => g_headerObj.setShadowColor[_c
1826
1922
 
1827
1923
  /**
1828
1924
  * デフォルトの曲中ショートカットをキー数・キーパターンにより切り替え
1829
- * - キーコンフィグ画面で個別に変えていた場合は変更しない
1925
+ * - Self(-1)のときは保存済みの値を優先(レーンキーと重複する場合は無視)
1926
+ * - それ以外はパターンのデフォルトへ戻す
1830
1927
  */
1831
1928
  const setPlayingShortcut = () => {
1832
1929
  const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
1833
- if (g_headerObj.keyRetryDef === C_KEY_RETRY) {
1834
- g_headerObj.keyRetry = setIntVal(getKeyCtrlVal(g_keyObj[`keyRetry${keyCtrlPtn}`]), g_headerObj.keyRetryDef);
1835
- }
1836
- if (g_headerObj.keyTitleBackDef === C_KEY_TITLEBACK) {
1837
- g_headerObj.keyTitleBack = setIntVal(getKeyCtrlVal(g_keyObj[`keyTitleBack${keyCtrlPtn}`]), g_headerObj.keyTitleBackDef);
1838
- }
1839
- if (g_headerObj.keyPauseDef === C_KEY_PAUSE) {
1840
- g_headerObj.keyPause = setIntVal(getKeyCtrlVal(g_keyObj[`keyPause${keyCtrlPtn}`]), g_headerObj.keyPauseDef);
1841
- }
1930
+ const saved = g_keyObj.currentPtn === -1 ? g_keyObj[`shortcut${g_keyObj.currentKey}_-1`] : undefined;
1931
+ const usedKeys = (g_keyObj[`keyCtrl${keyCtrlPtn}`] ?? []).flat();
1932
+ g_keycons.shortcutTypes.forEach(type => {
1933
+ const savedKey = saved?.[type];
1934
+ g_headerObj[`key${type}`] = (savedKey !== undefined && !usedKeys.includes(savedKey))
1935
+ ? savedKey : getDefaultShortcut(type);
1936
+ });
1842
1937
  };
1843
1938
 
1844
1939
  /**
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2026/09/13
8
- * Revised : 2026/09/29 (v51.1.1)
8
+ * Revised : 2026/10/10 (v51.3.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -1274,52 +1274,6 @@ const getKeyStorageObjByName = (_keyName) => {
1274
1274
  }), ``];
1275
1275
  };
1276
1276
 
1277
- /**
1278
- * 別キーモード時、移行先キーが保持するSelf保存パターンの取得可否チェック
1279
- * @param {string} _keyCtrlPtn 例: "7_2"
1280
- * @returns {number[][]|undefined} 適用可能な場合はSelf保存済みkeyCtrl配列、不可ならundefined
1281
- */
1282
- const getTransKeySelfCtrl = (_keyCtrlPtn) => {
1283
- const transKeyName = g_keyObj[`transKey${_keyCtrlPtn}`];
1284
- const transKeyPtn = g_keyObj[`transKeyPtn${_keyCtrlPtn}`];
1285
- if (!hasVal(transKeyName) || transKeyPtn === undefined) {
1286
- return undefined;
1287
- }
1288
- const [storageObj, addKey] = getKeyStorageObjByName(transKeyName);
1289
- const savedCtrl = storageObj[`keyCtrl${addKey}`];
1290
- const savedPtn = storageObj[`keyCtrlPtn${addKey}`];
1291
-
1292
- if (savedPtn !== transKeyPtn) {
1293
- return undefined;
1294
- }
1295
-
1296
- // 現在のキー配置(基準形状)とレーン数・各レーン長が完全一致することを確認
1297
- const baseCtrl = g_keyObj[`keyCtrl${_keyCtrlPtn}`];
1298
- const isValidShape = hasArrayList(savedCtrl, baseCtrl.length) &&
1299
- savedCtrl.length === baseCtrl.length &&
1300
- baseCtrl.every((lane, j) => hasArrayList(savedCtrl[j], lane.length) && savedCtrl[j].length === lane.length);
1301
-
1302
- return isValidShape ? savedCtrl : undefined;
1303
- };
1304
-
1305
- /**
1306
- * 別キーモードの移行先Selfパターンを現在のキー配置へ反映(保存はしない)
1307
- */
1308
- const applyTransKeySelfPattern = () => {
1309
- const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
1310
- const savedCtrl = getTransKeySelfCtrl(keyCtrlPtn);
1311
- if (savedCtrl === undefined) {
1312
- return;
1313
- }
1314
- const baseKeyNum = g_keyObj[`${g_keyObj.defaultProp}${keyCtrlPtn}`].length;
1315
- for (let j = 0; j < baseKeyNum; j++) {
1316
- for (let k = 0; k < (savedCtrl[j]?.length ?? 0); k++) {
1317
- g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(savedCtrl[j][k], 0);
1318
- }
1319
- }
1320
- keyConfigInit();
1321
- };
1322
-
1323
1277
  /**
1324
1278
  * 譜面初期化処理
1325
1279
  * - 譜面の基本設定(キー数、初期速度、リバース、ゲージ設定)をここで行う
@@ -1371,6 +1325,7 @@ const setDifficulty = (_chartChangeFlg) => {
1371
1325
  storageObj[`keyCtrlPtn${addKey}`] = 0;
1372
1326
  }
1373
1327
  getKeyCtrl(storageObj, addKey);
1328
+ g_keyObj[`shortcut${g_keyObj.currentKey}_-1`] = structuredClone(storageObj[`shortcut${addKey}`] ?? {});
1374
1329
 
1375
1330
  // カラーセット初期値設定
1376
1331
  if (storageObj[`setColor${addKey}`] === undefined) {
@@ -1401,10 +1356,9 @@ const setDifficulty = (_chartChangeFlg) => {
1401
1356
  g_keyObj[`${type}${keyCtrlPtn}`] = structuredClone(g_keyObj[`${type}${keyCtrlPtn}_0`]);
1402
1357
  }
1403
1358
  });
1404
-
1359
+ // 曲中ショートカットキーの切り替え
1360
+ setPlayingShortcut();
1405
1361
  }
1406
- // 曲中ショートカットキーの切り替え
1407
- setPlayingShortcut();
1408
1362
  }
1409
1363
 
1410
1364
  // スクロール設定用の配列を入れ替え
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "51.2.2",
3
+ "version": "51.3.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",