poi-plugin-koushu-rate 2.0.12 → 2.0.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.
Files changed (2) hide show
  1. package/index.js +670 -48
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -17,8 +17,8 @@ const LEVEL_TWO_ROWS = [
17
17
  { range: "★6→7", label: "90%", p: 0.90, source: "phase1" },
18
18
  { range: "★7→8", label: "82%", p: 0.82, source: "phase1" },
19
19
  { range: "★8→9", label: "77%", p: 0.77, source: "phase1" },
20
- { range: "★9→MAX", label: "67%", p: 0.67, source: "phase1" },
21
- { range: "MAX→进化", label: "62%", p: 0.62, source: "upgrade" },
20
+ { range: "★9→max", label: "67%", p: 0.67, source: "phase1" },
21
+ { range: "max→进化", label: "62%", p: 0.62, source: "upgrade" },
22
22
  ];
23
23
 
24
24
  const PLAN_LEVELS_6 = [
@@ -160,10 +160,10 @@ const CSS = `
160
160
  }
161
161
  .kr2-title-row {
162
162
  display: flex;
163
- align-items: center;
164
- justify-content: space-between;
163
+ flex-direction: column;
164
+ align-items: stretch;
165
+ justify-content: flex-start;
165
166
  gap: 12px;
166
- flex-wrap: wrap;
167
167
  }
168
168
  .kr2-title {
169
169
  font-size: 18px;
@@ -202,7 +202,7 @@ const CSS = `
202
202
  display: flex;
203
203
  gap: 6px;
204
204
  flex-wrap: wrap;
205
- margin-top: 0;
205
+ margin-top: 12px;
206
206
  }
207
207
  .kr2-day {
208
208
  padding: 5px 12px;
@@ -224,10 +224,10 @@ const CSS = `
224
224
  .kr2-nav {
225
225
  display: flex;
226
226
  gap: 6px;
227
- margin-top: 12px;
228
- margin-bottom: 20px;
227
+ margin: 0;
229
228
  }
230
229
  .kr2-nav-btn {
230
+ min-width: 110px;
231
231
  padding: 7px 18px;
232
232
  border: 1px solid #5f6b7c;
233
233
  border-radius: 6px;
@@ -235,6 +235,7 @@ const CSS = `
235
235
  color: #f6f7f9;
236
236
  cursor: pointer;
237
237
  font-size: 13px;
238
+ text-align: center;
238
239
  }
239
240
  .kr2-nav-btn:hover {
240
241
  background: #383e47;
@@ -333,6 +334,40 @@ const CSS = `
333
334
  .kr2-plan-table tbody tr:last-child td {
334
335
  border-bottom: 0;
335
336
  }
337
+ .kr2-plan-main-table {
338
+ table-layout: fixed;
339
+ width: 100%;
340
+ }
341
+ .kr2-plan-main-table th,
342
+ .kr2-plan-main-table td {
343
+ vertical-align: middle;
344
+ }
345
+ .kr2-plan-main-table th:nth-child(1),
346
+ .kr2-plan-main-table td:nth-child(1) { width: 40px; }
347
+ .kr2-plan-main-table th:nth-child(2),
348
+ .kr2-plan-main-table td:nth-child(2) { width: 170px; }
349
+ .kr2-plan-main-table th:nth-child(3),
350
+ .kr2-plan-main-table td:nth-child(3) { width: 90px; }
351
+ .kr2-plan-main-table th:nth-child(4),
352
+ .kr2-plan-main-table td:nth-child(4) { width: 190px; }
353
+ .kr2-plan-main-table th:nth-child(5),
354
+ .kr2-plan-main-table td:nth-child(5) { width: 105px; }
355
+ .kr2-plan-main-table th:nth-child(6),
356
+ .kr2-plan-main-table td:nth-child(6) { width: 90px; }
357
+ .kr2-plan-main-table th:nth-child(7),
358
+ .kr2-plan-main-table td:nth-child(7) { width: 90px; }
359
+ .kr2-plan-main-table td.kr2-plan-mat-col {
360
+ white-space: normal;
361
+ word-break: break-word;
362
+ }
363
+ .kr2-plan-target-group {
364
+ display: inline-flex;
365
+ align-items: center;
366
+ justify-content: center;
367
+ gap: 4px;
368
+ flex-wrap: wrap;
369
+ width: 100%;
370
+ }
336
371
  .kr2-plan-current {
337
372
  font-size: 12px;
338
373
  }
@@ -368,7 +403,17 @@ const CSS = `
368
403
  .kr2-plan-table .kr2-plan-name-inner {
369
404
  display: flex;
370
405
  align-items: center;
371
- gap: 8px;
406
+ flex-wrap: wrap;
407
+ gap: 4px 8px;
408
+ }
409
+ .kr2-plan-evo-target-line {
410
+ color: #4fc3f7;
411
+ font-weight: 700;
412
+ white-space: normal;
413
+ word-break: break-word;
414
+ }
415
+ .kr2-plan-evo-target-name {
416
+ color: #4fc3f7;
372
417
  }
373
418
  .kr2-plan-table .kr2-icon {
374
419
  width: 24px;
@@ -443,6 +488,212 @@ const CSS = `
443
488
  color: #d6dce3;
444
489
  margin-bottom: 8px;
445
490
  }
491
+ .kr2-plan-target-btn {
492
+ min-width: 56px;
493
+ height: 24px;
494
+ padding: 0 8px;
495
+ border: 1px solid #5f6b7c;
496
+ border-radius: 4px;
497
+ background: #2f343c;
498
+ color: #f6f7f9;
499
+ font-size: 12px;
500
+ text-align: center;
501
+ cursor: pointer;
502
+ }
503
+ .kr2-plan-target-btn.kr2-plan-target-active {
504
+ background: #2d72d2;
505
+ border-color: #2d72d2;
506
+ color: #fff;
507
+ }
508
+ .kr2-level-max-blue {
509
+ color: #4fc3f7;
510
+ font-weight: 700;
511
+ }
512
+ .kr2-plan-evo-wrap {
513
+ display: inline-block;
514
+ vertical-align: middle;
515
+ }
516
+ .kr2-plan-evo-btn {
517
+ min-width: 56px;
518
+ height: 24px;
519
+ padding: 0 8px;
520
+ border: 1px solid #5f6b7c;
521
+ border-radius: 4px;
522
+ background: #2f343c;
523
+ color: #f6f7f9;
524
+ font-size: 12px;
525
+ text-align: center;
526
+ white-space: nowrap;
527
+ cursor: pointer;
528
+ }
529
+ .kr2-plan-evo-btn:disabled {
530
+ opacity: 0.4;
531
+ cursor: not-allowed;
532
+ }
533
+ .kr2-plan-evo-btn.kr2-plan-evo-active {
534
+ background: #2d72d2;
535
+ border-color: #2d72d2;
536
+ color: #fff;
537
+ }
538
+ .kr2-evo-modal {
539
+ width: 420px;
540
+ max-width: 100%;
541
+ }
542
+ .kr2-evo-scroll {
543
+ max-height: 280px;
544
+ overflow-y: auto;
545
+ display: flex;
546
+ flex-direction: column;
547
+ gap: 6px;
548
+ padding: 12px;
549
+ }
550
+ .kr2-evo-option {
551
+ padding: 8px 10px;
552
+ border: 1px solid #5f6b7c;
553
+ border-radius: 4px;
554
+ background: #2f343c;
555
+ color: #f6f7f9;
556
+ text-align: left;
557
+ font-size: 13px;
558
+ cursor: pointer;
559
+ }
560
+ .kr2-evo-option:hover {
561
+ background: #383e47;
562
+ }
563
+ .kr2-evo-option.kr2-evo-option-active {
564
+ background: #1d3048;
565
+ border-color: #4f9dcc;
566
+ color: #d6e4f5;
567
+ }
568
+
569
+ .kr2-strong {
570
+ margin-top: 12px;
571
+ flex: 1;
572
+ min-height: 60vh;
573
+ overflow-x: hidden;
574
+ overflow-y: auto;
575
+ }
576
+ .kr2-strong-table {
577
+ border-collapse: separate;
578
+ border-spacing: 0;
579
+ }
580
+ .kr2-strong-cat-th {
581
+ position: relative;
582
+ cursor: pointer;
583
+ user-select: none;
584
+ }
585
+ .kr2-strong-cat-title {
586
+ margin-right: 4px;
587
+ }
588
+ .kr2-strong-cat-arrow {
589
+ color: #abb3bf;
590
+ font-size: 11px;
591
+ }
592
+ .kr2-strong-cat-menu {
593
+ position: absolute;
594
+ top: calc(100% + 4px);
595
+ left: 0;
596
+ z-index: 40;
597
+ min-width: 180px;
598
+ background: #252a31;
599
+ border: 1px solid #5f6b7c;
600
+ border-radius: 6px;
601
+ padding: 6px;
602
+ display: flex;
603
+ flex-direction: column;
604
+ gap: 4px;
605
+ }
606
+ .kr2-strong-cat-option {
607
+ display: flex;
608
+ align-items: center;
609
+ gap: 6px;
610
+ color: #f6f7f9;
611
+ font-size: 12px;
612
+ white-space: nowrap;
613
+ cursor: pointer;
614
+ }
615
+ .kr2-strong-cat-option input {
616
+ margin: 0;
617
+ }
618
+
619
+ .kr2-strong-cat {
620
+ white-space: nowrap;
621
+ }
622
+ .kr2-strong-table th,
623
+ .kr2-strong-table td {
624
+ text-align: center;
625
+ border-bottom: 1px solid rgba(255, 255, 255, 0.12);
626
+ }
627
+ .kr2-strong-table tbody tr:last-child td {
628
+ border-bottom: 0;
629
+ }
630
+ .kr2-strong-equip {
631
+ text-align: left !important;
632
+ white-space: normal;
633
+ }
634
+ .kr2-strong-level {
635
+ display: inline-flex;
636
+ align-items: center;
637
+ justify-content: center;
638
+ vertical-align: middle;
639
+ min-width: 30px;
640
+ height: 20px;
641
+ color: #4fc3f7;
642
+ font-weight: 700;
643
+ }
644
+ .kr2-strong-target {
645
+ color: #ffffff;
646
+ font-weight: 700;
647
+ }
648
+ .kr2-strong-stock {
649
+ white-space: normal;
650
+ }
651
+ .kr2-strong-stock-name {
652
+ color: #ffffff;
653
+ font-weight: 700;
654
+ }
655
+ .kr2-strong-stock-ok {
656
+ color: #f6f7f9;
657
+ }
658
+ .kr2-strong-stock-short {
659
+ color: #ff6b6b;
660
+ font-weight: 700;
661
+ }
662
+ .kr2-strong-stock-missing {
663
+ color: #abb3bf;
664
+ }
665
+ .kr2-strong-stock-notfound {
666
+ color: #ff6b6b;
667
+ font-weight: 700;
668
+ }
669
+ .kr2-strong-stock-notfound .kr2-strong-stock-name {
670
+ color: #ff6b6b;
671
+ }
672
+ .kr2-strong-stock-clear {
673
+ color: #4fc3f7;
674
+ font-weight: 700;
675
+ }
676
+ .kr2-strong-clear-row {
677
+ background: rgba(79, 195, 247, 0.14);
678
+ }
679
+ .kr2-strong-owned {
680
+ color: #f6f7f9;
681
+ font-weight: 700;
682
+ }
683
+ .kr2-strong-owned.kr2-strong-stock-short {
684
+ color: #ff6b6b;
685
+ }
686
+ .kr2-strong-owned.kr2-strong-stock-clear {
687
+ color: #4fc3f7;
688
+ }
689
+ .kr2-strong-clear-row td {
690
+ color: #4fc3f7;
691
+ }
692
+ .kr2-strong-clear-row .kr2-strong-target,
693
+ .kr2-strong-clear-row .kr2-strong-stock-name,
694
+ .kr2-strong-clear-row .kr2-strong-owned {
695
+ color: #4fc3f7;
696
+ }
446
697
  .kr2-search {
447
698
  width: 240px;
448
699
  padding: 6px 10px;
@@ -509,20 +760,24 @@ const CSS = `
509
760
  overflow-y: scroll;
510
761
  }
511
762
  .kr2-plan::-webkit-scrollbar,
763
+ .kr2-strong::-webkit-scrollbar,
512
764
  .kr2-list::-webkit-scrollbar {
513
765
  width: 10px;
514
766
  height: 10px;
515
767
  }
516
768
  .kr2-plan::-webkit-scrollbar-track,
769
+ .kr2-strong::-webkit-scrollbar-track,
517
770
  .kr2-list::-webkit-scrollbar-track {
518
771
  background: #1c2127;
519
772
  }
520
773
  .kr2-plan::-webkit-scrollbar-thumb,
774
+ .kr2-strong::-webkit-scrollbar-thumb,
521
775
  .kr2-list::-webkit-scrollbar-thumb {
522
776
  background: #5f6b7c;
523
777
  border-radius: 5px;
524
778
  }
525
779
  .kr2-plan::-webkit-scrollbar-thumb:hover,
780
+ .kr2-strong::-webkit-scrollbar-thumb:hover,
526
781
  .kr2-list::-webkit-scrollbar-thumb:hover {
527
782
  background: #8b95a1;
528
783
  }
@@ -1944,6 +2199,8 @@ function buildRows(staticData, masterEquips, fallbackNames, akashi, recommendati
1944
2199
  upgradesByEquip[key].push(
1945
2200
  Object.assign({}, r, {
1946
2201
  targetName: String(targetMaster.api_name || targetFallback.name || ("装备 " + r.upgrade_id)),
2202
+ targetCategory: String(targetMaster.api_type_name || targetFallback.type || ""),
2203
+ targetBase: baseById[targetId] || null,
1947
2204
  secretaries: secretaries.slice(),
1948
2205
  })
1949
2206
  )
@@ -2168,7 +2425,7 @@ function planInventoryLevels(row, inventoryByEquip) {
2168
2425
  return out
2169
2426
  }
2170
2427
 
2171
- function planCopyCosts(row, target, current) {
2428
+ function planCopyCosts(row, target, current, upgradeId) {
2172
2429
  const levels = target === "max" ? PLAN_LEVELS_MAX : PLAN_LEVELS_6
2173
2430
  const out = { screws: 0, dev: 0, fuel: 0, ammo: 0, steel: 0, bauxite: 0, materials: [] }
2174
2431
  for (const lv of levels) {
@@ -2192,10 +2449,31 @@ function planCopyCosts(row, target, current) {
2192
2449
  out.materials.push({ item: m, count: m.count || 1 })
2193
2450
  }
2194
2451
  }
2452
+ if (upgradeId != null && target === "max") {
2453
+ const upg = (row.upgrades || []).find((u) => String(u.upgrade_id) === String(upgradeId))
2454
+ if (upg) {
2455
+ const rec = buildRecommendation(upg.consume_improvement_min, upg.consume_improvement_max, 0.62)
2456
+ const ensure = rec.tone === "ensure"
2457
+ const expected = Number.isFinite(rec.expected) ? rec.expected : upg.consume_improvement_min / 0.62
2458
+ const screws = ensure ? upg.consume_improvement_max : expected
2459
+ const attempts = ensure ? 1 : expected
2460
+ const dev = ensure ? upg.consume_development_max : upg.consume_development_min * attempts
2461
+ out.screws += screws
2462
+ out.dev += dev
2463
+ const base = upg.targetBase || row.base || {}
2464
+ out.fuel += (base.consume_fuel || 0) * attempts
2465
+ out.ammo += (base.consume_ammo || 0) * attempts
2466
+ out.steel += (base.consume_steel || 0) * attempts
2467
+ out.bauxite += (base.consume_bauxite || 0) * attempts
2468
+ for (const m of upg.materials || []) {
2469
+ out.materials.push({ item: m, count: m.count || 1 })
2470
+ }
2471
+ }
2472
+ }
2195
2473
  return out
2196
2474
  }
2197
2475
 
2198
- function planRowCosts(row, target, qty, inventoryByEquip) {
2476
+ function planRowCosts(row, target, qty, inventoryByEquip, upgradeId) {
2199
2477
  const count = Math.max(1, Math.min(99, Math.round(Number(qty) || 1)))
2200
2478
  let starts = []
2201
2479
  if (count === 1) {
@@ -2206,7 +2484,7 @@ function planRowCosts(row, target, qty, inventoryByEquip) {
2206
2484
  }
2207
2485
  const out = { screws: 0, dev: 0, fuel: 0, ammo: 0, steel: 0, bauxite: 0, materials: [] }
2208
2486
  for (const current of starts) {
2209
- const c = planCopyCosts(row, target, current)
2487
+ const c = planCopyCosts(row, target, current, upgradeId)
2210
2488
  out.screws += c.screws
2211
2489
  out.dev += c.dev
2212
2490
  out.fuel += c.fuel
@@ -2282,11 +2560,80 @@ function planMaterialDevExpected(costs, kcDevData) {
2282
2560
  return total
2283
2561
  }
2284
2562
 
2285
- function PlanningPage({ rows, inventoryByEquip, useItemCounts, selection, onToggle, onTarget, onQty, onSelectAll, onMaterialClick, kcDevData, includeDevExpected, onToggleIncludeDevExpected }) {
2563
+ class EvolutionButton extends React.Component {
2564
+ state = { open: false, selected: null }
2565
+
2566
+ open = () => {
2567
+ const branches = this.props.branches || []
2568
+ if (branches.length <= 1) {
2569
+ const id = branches[0] ? String(branches[0].upgrade_id) : null
2570
+ if (id == null || !this.props.onSelect) return
2571
+ this.props.onSelect(this.props.rowId, this.props.value === id ? null : id)
2572
+ return
2573
+ }
2574
+ this.setState({ open: true, selected: this.props.value || null })
2575
+ }
2576
+
2577
+ close = () => {
2578
+ if (this.props.onSelect) this.props.onSelect(this.props.rowId, this.state.selected)
2579
+ this.setState({ open: false })
2580
+ }
2581
+
2582
+ render() {
2583
+ const branches = this.props.branches || []
2584
+ if (branches.length === 0) {
2585
+ return React.createElement("button", { type: "button", className: "kr2-plan-evo-btn", disabled: true }, "无进化")
2586
+ }
2587
+ const active = !!this.props.value
2588
+ const selected = branches.find((b) => String(b.upgrade_id) === String(this.props.value))
2589
+ const label = "进化"
2590
+ return React.createElement(
2591
+ "div",
2592
+ { className: "kr2-plan-evo-wrap" },
2593
+ React.createElement("button", { type: "button", className: "kr2-plan-evo-btn" + (active ? " kr2-plan-evo-active" : ""), onClick: this.open }, label),
2594
+ this.state.open
2595
+ ? React.createElement(
2596
+ "div",
2597
+ { className: "kr2-modal-backdrop", onClick: this.close },
2598
+ React.createElement(
2599
+ "div",
2600
+ { className: "kr2-modal kr2-evo-modal", onClick: (e) => e.stopPropagation() },
2601
+ React.createElement(
2602
+ "div",
2603
+ { className: "kr2-modal-head" },
2604
+ React.createElement("div", { className: "kr2-modal-title" }, "选择进化分支"),
2605
+ React.createElement(
2606
+ "div",
2607
+ { className: "kr2-modal-actions" },
2608
+ React.createElement("button", { className: "kr2-button", onClick: this.close }, "关闭")
2609
+ )
2610
+ ),
2611
+ React.createElement(
2612
+ "div",
2613
+ { className: "kr2-evo-scroll" },
2614
+ branches.map((b) =>
2615
+ React.createElement(
2616
+ "button",
2617
+ { key: String(b.upgrade_id), type: "button", className: "kr2-evo-option" + (this.state.selected === String(b.upgrade_id) ? " kr2-evo-option-active" : ""), onClick: () => this.setState({ selected: String(b.upgrade_id) }) },
2618
+ b.targetName
2619
+ )
2620
+ )
2621
+ )
2622
+ )
2623
+ )
2624
+ : null
2625
+ )
2626
+ }
2627
+ }
2628
+
2629
+ function PlanningPage({ rows, inventoryByEquip, useItemCounts, selection, onToggle, onTarget, onQty, onSelectAll, onMaterialClick, kcDevData, includeDevExpected, onToggleIncludeDevExpected, onEvo }) {
2286
2630
  const planRows = rows.map((row) => {
2287
2631
  const sel = (selection || {})[row.id] || { selected: true, target: "max", qty: 1 }
2288
- const costs = planRowCosts(row, sel.target, sel.qty, inventoryByEquip)
2289
- return { row, sel, costs, matDev: planMaterialDevExpected(costs, kcDevData), display: planCurrentDisplay(row, sel, inventoryByEquip) }
2632
+ const evoUpgradeId = sel.evoUpgradeId || null
2633
+ const evoBranch = evoUpgradeId ? (row.upgrades || []).find((u) => String(u.upgrade_id) === String(evoUpgradeId)) : null
2634
+ const target = evoUpgradeId ? "max" : sel.target
2635
+ const costs = planRowCosts(row, target, sel.qty, inventoryByEquip, evoUpgradeId)
2636
+ return { row, sel, costs, matDev: planMaterialDevExpected(costs, kcDevData), display: planCurrentDisplay(row, sel, inventoryByEquip), target, evoUpgradeId, evoBranch }
2290
2637
  })
2291
2638
  const selected = planRows.filter((p) => p.sel.selected)
2292
2639
  const totals = { screws: 0, dev: 0, fuel: 0, ammo: 0, steel: 0, bauxite: 0 }
@@ -2351,7 +2698,7 @@ function PlanningPage({ rows, inventoryByEquip, useItemCounts, selection, onTogg
2351
2698
  ),
2352
2699
  React.createElement(
2353
2700
  "table",
2354
- { className: "kr2-table kr2-plan-table" },
2701
+ { className: "kr2-table kr2-plan-table kr2-plan-main-table" },
2355
2702
  React.createElement(
2356
2703
  "thead",
2357
2704
  null,
@@ -2377,22 +2724,17 @@ function PlanningPage({ rows, inventoryByEquip, useItemCounts, selection, onTogg
2377
2724
  "tr",
2378
2725
  { key: p.row.id },
2379
2726
  React.createElement("td", null, React.createElement("input", { type: "checkbox", checked: !!p.sel.selected, onChange: () => onToggle(p.row.id) })),
2380
- React.createElement("td", { className: "kr2-plan-name" }, React.createElement("span", { className: "kr2-plan-name-inner" }, React.createElement(SlotitemIcon, { slotitemId: p.row.icon, className: "kr2-icon" }), " ", p.row.name)),
2727
+ React.createElement("td", { className: "kr2-plan-name" }, React.createElement("span", { className: "kr2-plan-name-inner" }, React.createElement(SlotitemIcon, { slotitemId: p.row.icon, className: "kr2-icon" }), " ", p.row.name, p.evoBranch ? React.createElement("span", { className: "kr2-plan-evo-target-line" }, "→ ", React.createElement("span", { className: "kr2-plan-evo-target-name" }, p.evoBranch.targetName)) : null)),
2381
2728
  React.createElement("td", { className: Math.round(Number(p.sel.qty || 1)) === 1 ? "kr2-plan-current" : "kr2-plan-current-stock" }, p.display),
2382
2729
  React.createElement(
2383
2730
  "td",
2384
2731
  null,
2385
2732
  React.createElement(
2386
- "label",
2387
- { style: { marginRight: 8 } },
2388
- React.createElement("input", { type: "radio", name: "plan-" + p.row.id, checked: p.sel.target !== "max", onChange: () => onTarget(p.row.id, "6") }),
2389
- "+6"
2390
- ),
2391
- React.createElement(
2392
- "label",
2393
- null,
2394
- React.createElement("input", { type: "radio", name: "plan-" + p.row.id, checked: p.sel.target === "max", onChange: () => onTarget(p.row.id, "max") }),
2395
- "MAX"
2733
+ "div",
2734
+ { className: "kr2-plan-target-group" },
2735
+ React.createElement("button", { type: "button", className: "kr2-plan-target-btn" + (!p.evoUpgradeId && p.target !== "max" ? " kr2-plan-target-active" : ""), onClick: () => onTarget(p.row.id, "6") }, "+6"),
2736
+ React.createElement("button", { type: "button", className: "kr2-plan-target-btn" + (!p.evoUpgradeId && p.target === "max" ? " kr2-plan-target-active" : ""), onClick: () => onTarget(p.row.id, "max") }, "max"),
2737
+ React.createElement(EvolutionButton, { rowId: p.row.id, branches: p.row.upgrades || [], value: p.evoUpgradeId, onSelect: onEvo })
2396
2738
  )
2397
2739
  ),
2398
2740
  React.createElement(
@@ -2447,6 +2789,161 @@ function PlanningPage({ rows, inventoryByEquip, useItemCounts, selection, onTogg
2447
2789
  )
2448
2790
  }
2449
2791
 
2792
+ class StrongPage extends React.Component {
2793
+ catRef = React.createRef()
2794
+ state = {
2795
+ categoryOpen: false,
2796
+ selectedCategories: readStrongCategories(),
2797
+ catPos: null,
2798
+ }
2799
+
2800
+ toggleCategoryOpen = () => {
2801
+ if (this.state.categoryOpen) {
2802
+ this.setState({ categoryOpen: false, catPos: null })
2803
+ return
2804
+ }
2805
+ const el = this.catRef.current
2806
+ if (!el) return
2807
+ const rect = el.getBoundingClientRect()
2808
+ this.setState({
2809
+ categoryOpen: true,
2810
+ catPos: { top: rect.bottom + 4, left: rect.left, width: rect.width },
2811
+ })
2812
+ }
2813
+
2814
+ toggleCategory = (name) => {
2815
+ const all = Array.from(new Set((this.props.rows || []).map((row) => row.category).filter(Boolean)))
2816
+ this.setState((prev) => {
2817
+ let next
2818
+ if (prev.selectedCategories == null) {
2819
+ next = all.filter((c) => c !== name)
2820
+ } else if (prev.selectedCategories.indexOf(name) >= 0) {
2821
+ next = prev.selectedCategories.filter((c) => c !== name)
2822
+ } else {
2823
+ next = prev.selectedCategories.concat([name])
2824
+ }
2825
+ if (next.length === all.length) next = null
2826
+ saveStrongCategories(next)
2827
+ return { selectedCategories: next }
2828
+ })
2829
+ }
2830
+
2831
+ render() {
2832
+ const { rows, inventoryByEquip, selection } = this.props
2833
+ const inventoryLoaded = inventoryByEquip && Object.keys(inventoryByEquip).length > 0
2834
+ const entries = []
2835
+ const levelText = (level) => {
2836
+ const n = Number(level)
2837
+ if (n >= 10) return "max"
2838
+ return "+" + String(n)
2839
+ }
2840
+ for (const row of rows || []) {
2841
+ const sel = (selection || {})[row.id] || { selected: true, target: "max", qty: 1 }
2842
+ const qty = Math.max(1, Math.min(99, Math.round(Number(sel.qty) || 1)))
2843
+ const evoUpgradeId = sel.evoUpgradeId || null
2844
+ const evoUpgrade = evoUpgradeId ? (row.upgrades || []).find((u) => String(u.upgrade_id) === String(evoUpgradeId)) : null
2845
+ const displayRow = evoUpgrade
2846
+ ? Object.assign({}, row, { id: row.id + ":evo:" + evoUpgrade.upgrade_id, name: evoUpgrade.targetName, category: evoUpgrade.targetCategory || row.category })
2847
+ : row
2848
+ const invId = evoUpgrade ? String(evoUpgrade.upgrade_id) : row.id
2849
+ const targetLevelValue = evoUpgrade ? 0 : (sel.target === "max" ? 10 : 6)
2850
+ const targetLevel = levelText(targetLevelValue)
2851
+ const inv = (inventoryByEquip || {})[invId]
2852
+ const levels = []
2853
+ if (inv && inv.levels) {
2854
+ for (const level of Object.keys(inv.levels)) {
2855
+ const count = Math.max(0, Math.round(Number(inv.levels[level]) || 0))
2856
+ if (count > 0) levels.push({ level: Number(level), count })
2857
+ }
2858
+ levels.sort((a, b) => b.level - a.level)
2859
+ }
2860
+ const rowEntries = []
2861
+ if (levels.length === 0) {
2862
+ rowEntries.push({ key: displayRow.id + ":none", row: displayRow, targetLevel, targetLevelValue, inventoryLevel: null, stock: inventoryLoaded ? 0 : null, notFound: true })
2863
+ } else {
2864
+ for (const lv of levels) rowEntries.push({ key: displayRow.id + ":" + String(lv.level), row: displayRow, targetLevel, targetLevelValue, inventoryLevel: lv.level, stock: lv.count })
2865
+ }
2866
+ const base = Math.floor(qty / rowEntries.length)
2867
+ let remainder = qty % rowEntries.length
2868
+ for (const item of rowEntries) {
2869
+ item.qty = base + (remainder > 0 ? 1 : 0)
2870
+ if (remainder > 0) remainder -= 1
2871
+ }
2872
+ for (const item of rowEntries) {
2873
+ if (item.qty > 0) entries.push(item)
2874
+ }
2875
+ }
2876
+ for (const item of entries) {
2877
+ item.clear = item.qty > 0 && item.stock != null && item.inventoryLevel === item.targetLevelValue && item.stock >= item.qty
2878
+ item.levelShort = item.inventoryLevel != null && item.inventoryLevel < item.targetLevelValue
2879
+ item.countShort = item.stock != null && item.qty > 0 && item.stock < item.qty
2880
+ item.countEnough = item.stock != null && item.stock >= item.qty
2881
+ }
2882
+ entries.sort((a, b) => (b.clear ? 1 : 0) - (a.clear ? 1 : 0))
2883
+ const categories = Array.from(new Set(entries.map((item) => item.row.category).filter(Boolean))).sort((a, b) => a.localeCompare(b, "zh-Hans-CN"))
2884
+ const selectedCategories = this.state.selectedCategories
2885
+ const visibleEntries = selectedCategories == null ? entries : entries.filter((item) => selectedCategories.indexOf(item.row.category) >= 0)
2886
+ const stockText = (item) => {
2887
+ const nameNode = React.createElement("span", { className: "kr2-strong-stock-name" }, item.row.name)
2888
+ if (item.notFound || item.stock == null) return nameNode
2889
+ const levelPart = levelText(item.inventoryLevel)
2890
+ return React.createElement("span", null, nameNode, " ", levelPart)
2891
+ }
2892
+ const stockClass = (item) => item.notFound || item.stock == null ? "kr2-strong-stock-notfound" : item.clear ? "kr2-strong-stock-clear" : item.levelShort ? "kr2-strong-stock-short" : "kr2-strong-stock-ok"
2893
+ const ownedClass = (item) => item.stock == null ? "kr2-strong-stock-missing" : item.clear || item.countEnough ? "kr2-strong-stock-clear" : item.countShort ? "kr2-strong-stock-short" : "kr2-strong-stock-ok"
2894
+ const catStyle = this.state.catPos ? { position: "fixed", top: this.state.catPos.top, left: this.state.catPos.left, minWidth: Math.max(180, this.state.catPos.width) } : null
2895
+ const categoryHead = React.createElement(
2896
+ "th",
2897
+ { className: "kr2-strong-cat-th", ref: this.catRef, onClick: this.toggleCategoryOpen },
2898
+ React.createElement("span", { className: "kr2-strong-cat-title" }, "装备分类"),
2899
+ React.createElement("span", { className: "kr2-strong-cat-arrow" }, this.state.categoryOpen ? "▲" : "▼"),
2900
+ this.state.categoryOpen
2901
+ ? React.createElement(
2902
+ "div",
2903
+ { className: "kr2-strong-cat-menu", style: catStyle, onClick: (e) => e.stopPropagation() },
2904
+ categories.map((cat) =>
2905
+ React.createElement(
2906
+ "label",
2907
+ { key: cat, className: "kr2-strong-cat-option" },
2908
+ React.createElement("input", { type: "checkbox", checked: selectedCategories == null || selectedCategories.indexOf(cat) >= 0, onChange: () => this.toggleCategory(cat) }),
2909
+ cat
2910
+ )
2911
+ )
2912
+ )
2913
+ : null
2914
+ )
2915
+ return React.createElement(
2916
+ "div",
2917
+ { className: "kr2-strong" },
2918
+ React.createElement(
2919
+ "table",
2920
+ { className: "kr2-table kr2-plan-table kr2-strong-table" },
2921
+ React.createElement(
2922
+ "thead",
2923
+ null,
2924
+ React.createElement("tr", null, categoryHead, React.createElement("th", null, "目标装备"), React.createElement("th", null, "目标数"), React.createElement("th", null, "库存"), React.createElement("th", null, "完成数"))
2925
+ ),
2926
+ React.createElement(
2927
+ "tbody",
2928
+ null,
2929
+ visibleEntries.length === 0
2930
+ ? React.createElement("tr", null, React.createElement("td", { colSpan: 5 }, "无匹配分类"))
2931
+ : visibleEntries.map((item) =>
2932
+ React.createElement(
2933
+ "tr",
2934
+ { key: item.key, className: item.clear ? "kr2-strong-clear-row" : null },
2935
+ React.createElement("td", { className: "kr2-strong-cat" }, item.row.category || "-"),
2936
+ React.createElement("td", { className: "kr2-strong-equip" }, item.row.name, " ", React.createElement("span", { className: "kr2-strong-level" }, item.targetLevel)),
2937
+ React.createElement("td", { className: "kr2-strong-target" }, String(item.qty)),
2938
+ React.createElement("td", { className: "kr2-strong-stock " + stockClass(item) }, stockText(item)),
2939
+ React.createElement("td", { className: "kr2-strong-owned " + ownedClass(item) }, item.stock == null ? "--" : item.clear ? "clear!" : String(item.stock))
2940
+ )
2941
+ )
2942
+ )
2943
+ )
2944
+ )
2945
+ }
2946
+ }
2450
2947
  function RateCell({ range, open, onToggle, tone }) {
2451
2948
  return React.createElement(
2452
2949
  "span",
@@ -2536,12 +3033,15 @@ class LevelTwoTable extends React.Component {
2536
3033
  const phase1 = this.props.phase1
2537
3034
  const upgrades = this.props.upgrades || null
2538
3035
  const rows = []
2539
- const pushRateRow = (step, range, label, key, p, subText, evolTarget) => {
3036
+ const pushRateRow = (step, range, label, key, p, subText, evolTarget, maxBlue) => {
2540
3037
  const normal = step ? step.consume_improvement_min : null
2541
3038
  const certain = step ? step.consume_improvement_max : null
2542
3039
  const rec = buildRecommendation(normal, certain, p)
2543
3040
  const materials = step ? step.materials || [] : []
2544
3041
  const hasMaterials = materials.some((item) => item && (item.item_name || item.item_material_key || item.item_equipment_id != null))
3042
+ const rangeNode = maxBlue
3043
+ ? React.createElement("span", null, "★9→", React.createElement("span", { className: "kr2-level-max-blue" }, "max"))
3044
+ : range
2545
3045
  rows.push(
2546
3046
  React.createElement(
2547
3047
  "tr",
@@ -2561,7 +3061,7 @@ class LevelTwoTable extends React.Component {
2561
3061
  ),
2562
3062
  React.createElement("div", { className: "kr2-evol-secretaries" }, subText)
2563
3063
  )
2564
- : range
3064
+ : rangeNode
2565
3065
  ),
2566
3066
  React.createElement("td", null, label),
2567
3067
  React.createElement("td", null, normal == null ? "--" : String(normal)),
@@ -2597,7 +3097,7 @@ class LevelTwoTable extends React.Component {
2597
3097
  return
2598
3098
  }
2599
3099
  const step = rate.source === "phase0" ? phase0 : phase1
2600
- pushRateRow(step, rate.range, rate.label, rate.range, rate.p)
3100
+ pushRateRow(step, rate.range, rate.label, rate.range, rate.p, "", "", rate.range === "★9→max" && !upgrades)
2601
3101
  })
2602
3102
 
2603
3103
  return React.createElement(
@@ -2713,7 +3213,7 @@ function EquipmentRow({ row, expanded, onToggle, onMaterialClick, inventoryByEqu
2713
3213
  { className: "kr2-level" },
2714
3214
  React.createElement(
2715
3215
  LevelSection,
2716
- { title: "6→MAX", defaultOpen: true, resourceText: "成功率 95 / 90 / 82 / 77 / 67 / 62 %" },
3216
+ { title: "6→max", defaultOpen: true, resourceText: "成功率 95 / 90 / 82 / 77 / 67 / 62 %" },
2717
3217
  React.createElement(LevelTwoTable, { phase0: row.phase0, phase1: row.phase1, upgrades: row.upgrades, onMaterialClick, inventoryByEquip, useItemCounts, onInventoryClick })
2718
3218
  )
2719
3219
  )
@@ -2805,6 +3305,100 @@ function saveFavorites(favorites) {
2805
3305
  saveFavoritesToLocalStorage(favorites)
2806
3306
  }
2807
3307
 
3308
+ const UI_STATE_STORAGE_KEY = "poi-plugin-koushu-rate:ui-state";
3309
+ const FAVORITES_ONLY_STORAGE_KEY = "poi-plugin-koushu-rate:favorites-only";
3310
+ const UI_STATE_FILE_NAME = "ui-state.json";
3311
+
3312
+ function getUiStateFilePath() {
3313
+ try {
3314
+ let remote = null
3315
+ try {
3316
+ remote = require("@electron/remote")
3317
+ } catch (_) {}
3318
+ if (!remote) {
3319
+ try {
3320
+ remote = require("electron").remote
3321
+ } catch (_) {}
3322
+ }
3323
+ const app = remote && (remote.app || (remote.default && remote.default.app))
3324
+ if (app && typeof app.getPath === "function") {
3325
+ return path.join(String(app.getPath("userData")), "poi-plugin-koushu-rate", UI_STATE_FILE_NAME)
3326
+ }
3327
+ } catch (_) {}
3328
+ return null
3329
+ }
3330
+
3331
+ function readUiStateFromLocalStorage() {
3332
+ const out = {}
3333
+ try {
3334
+ const storage = typeof localStorage !== "undefined" ? localStorage : (typeof window !== "undefined" ? window.localStorage : null)
3335
+ if (!storage) return out
3336
+ const raw = storage.getItem(UI_STATE_STORAGE_KEY)
3337
+ if (raw) {
3338
+ const parsed = JSON.parse(raw)
3339
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) Object.assign(out, parsed)
3340
+ }
3341
+ const legacy = storage.getItem(FAVORITES_ONLY_STORAGE_KEY)
3342
+ if (legacy != null && out.favoritesOnly == null) out.favoritesOnly = legacy === "1"
3343
+ } catch (_) {}
3344
+ return out
3345
+ }
3346
+
3347
+ function writeUiStateToLocalStorage(state) {
3348
+ try {
3349
+ const storage = typeof localStorage !== "undefined" ? localStorage : (typeof window !== "undefined" ? window.localStorage : null)
3350
+ if (storage) storage.setItem(UI_STATE_STORAGE_KEY, JSON.stringify(state || {}))
3351
+ } catch (_) {}
3352
+ }
3353
+
3354
+ function readUiState() {
3355
+ const file = getUiStateFilePath()
3356
+ let fileState = {}
3357
+ if (file) {
3358
+ try {
3359
+ if (fs.existsSync(file)) {
3360
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"))
3361
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) fileState = parsed
3362
+ }
3363
+ } catch (_) {}
3364
+ }
3365
+ return Object.assign({}, fileState, readUiStateFromLocalStorage())
3366
+ }
3367
+
3368
+ function saveUiState(patch) {
3369
+ const next = Object.assign({}, readUiState(), patch || {})
3370
+ for (const key of ["query", "day", "category", "activeTab"]) delete next[key]
3371
+ const file = getUiStateFilePath()
3372
+ if (file) {
3373
+ try {
3374
+ fs.mkdirSync(path.dirname(file), { recursive: true })
3375
+ fs.writeFileSync(file, JSON.stringify(next, null, 2), "utf8")
3376
+ } catch (_) {}
3377
+ }
3378
+ writeUiStateToLocalStorage(next)
3379
+ try {
3380
+ const storage = typeof localStorage !== "undefined" ? localStorage : (typeof window !== "undefined" ? window.localStorage : null)
3381
+ if (storage) storage.setItem(FAVORITES_ONLY_STORAGE_KEY, next.favoritesOnly ? "1" : "0")
3382
+ } catch (_) {}
3383
+ return next
3384
+ }
3385
+
3386
+ function readFavoritesOnly() {
3387
+ return !!readUiState().favoritesOnly
3388
+ }
3389
+
3390
+ function saveFavoritesOnly(value) {
3391
+ saveUiState({ favoritesOnly: !!value })
3392
+ }
3393
+
3394
+ function readStrongCategories() {
3395
+ const value = readUiState().strongCategories
3396
+ return Array.isArray(value) ? value : null
3397
+ }
3398
+
3399
+ function saveStrongCategories(value) {
3400
+ saveUiState({ strongCategories: Array.isArray(value) ? value : null })
3401
+ }
2808
3402
  const PLAN_SELECTION_STORAGE_KEY = "poi-plugin-koushu-rate:plan-selection";
2809
3403
 
2810
3404
  function readPlanSelection() {
@@ -2866,8 +3460,8 @@ class KoushuRateApp extends React.Component {
2866
3460
  useItemCounts: {},
2867
3461
  kcDevData: null,
2868
3462
  favorites: readFavorites(),
2869
- favoritesOnly: false,
2870
- starSort: null,
3463
+ favoritesOnly: readFavoritesOnly(),
3464
+ starSort: readUiState().starSort || null,
2871
3465
  activeTab: "list",
2872
3466
  planSelection: readPlanSelection(),
2873
3467
  includeDevExpected: readPlanIncludeDev(),
@@ -2957,13 +3551,19 @@ class KoushuRateApp extends React.Component {
2957
3551
  }
2958
3552
 
2959
3553
  toggleFavoritesOnly = () => {
2960
- this.setState((prev) => ({ favoritesOnly: !prev.favoritesOnly }))
3554
+ this.setState((prev) => {
3555
+ const favoritesOnly = !prev.favoritesOnly
3556
+ saveFavoritesOnly(favoritesOnly)
3557
+ return { favoritesOnly }
3558
+ })
2961
3559
  }
2962
3560
 
2963
3561
  toggleStarSort = () => {
2964
- this.setState((prev) => ({
2965
- starSort: prev.starSort === "desc" ? "asc" : prev.starSort === "asc" ? null : "desc",
2966
- }))
3562
+ this.setState((prev) => {
3563
+ const starSort = prev.starSort === "desc" ? "asc" : prev.starSort === "asc" ? null : "desc"
3564
+ saveUiState({ starSort })
3565
+ return { starSort }
3566
+ })
2967
3567
  }
2968
3568
 
2969
3569
  toggleCategory = () => {
@@ -3053,7 +3653,18 @@ class KoushuRateApp extends React.Component {
3053
3653
  setPlanTarget = (id, target) => {
3054
3654
  this.setState((prev) => {
3055
3655
  const cur = prev.planSelection[id] || this.planDefaultSel(id)
3056
- const planSelection = Object.assign({}, prev.planSelection, { [id]: Object.assign({}, cur, { target }) })
3656
+ const next = Object.assign({}, cur, { target, evoUpgradeId: null })
3657
+ const planSelection = Object.assign({}, prev.planSelection, { [id]: next })
3658
+ savePlanSelection(planSelection)
3659
+ return { planSelection }
3660
+ })
3661
+ }
3662
+
3663
+ setPlanEvo = (id, upgradeId) => {
3664
+ this.setState((prev) => {
3665
+ const cur = prev.planSelection[id] || this.planDefaultSel(id)
3666
+ const next = Object.assign({}, cur, { target: "max", evoUpgradeId: upgradeId == null ? null : String(upgradeId) })
3667
+ const planSelection = Object.assign({}, prev.planSelection, { [id]: next })
3057
3668
  savePlanSelection(planSelection)
3058
3669
  return { planSelection }
3059
3670
  })
@@ -3161,6 +3772,7 @@ class KoushuRateApp extends React.Component {
3161
3772
  React.createElement(
3162
3773
  "div",
3163
3774
  { className: "kr2-header" },
3775
+
3164
3776
  React.createElement(
3165
3777
  "div",
3166
3778
  { className: "kr2-title-row" },
@@ -3204,7 +3816,14 @@ class KoushuRateApp extends React.Component {
3204
3816
  ),
3205
3817
  React.createElement(
3206
3818
  "div",
3207
- { className: "kr2-toolbar", style: this.state.activeTab === "plan" ? { display: "none" } : null },
3819
+ { className: "kr2-nav" },
3820
+ React.createElement("button", { className: "kr2-nav-btn" + (this.state.activeTab === "list" ? " kr2-nav-active" : ""), onClick: () => this.setActiveTab("list") }, "改修列表"),
3821
+ React.createElement("button", { className: "kr2-nav-btn" + (this.state.activeTab === "plan" ? " kr2-nav-active" : ""), onClick: () => this.setActiveTab("plan") }, "素材计算"),
3822
+ React.createElement("button", { className: "kr2-nav-btn" + (this.state.activeTab === "strong" ? " kr2-nav-active" : ""), onClick: () => this.setActiveTab("strong") }, "我变强了!")
3823
+ ),
3824
+ React.createElement(
3825
+ "div",
3826
+ { className: "kr2-toolbar", style: this.state.activeTab === "plan" || this.state.activeTab === "strong" ? { display: "none" } : null },
3208
3827
  React.createElement("input", {
3209
3828
  className: "kr2-search",
3210
3829
  value: this.state.query,
@@ -3246,15 +3865,10 @@ class KoushuRateApp extends React.Component {
3246
3865
  : null
3247
3866
  )
3248
3867
  ),
3868
+
3249
3869
  React.createElement(
3250
3870
  "div",
3251
- { className: "kr2-nav" },
3252
- React.createElement("button", { className: "kr2-nav-btn" + (this.state.activeTab === "list" ? " kr2-nav-active" : ""), onClick: () => this.setActiveTab("list") }, "改修列表"),
3253
- React.createElement("button", { className: "kr2-nav-btn" + (this.state.activeTab === "plan" ? " kr2-nav-active" : ""), onClick: () => this.setActiveTab("plan") }, "素材计算")
3254
- ),
3255
- React.createElement(
3256
- "div",
3257
- { className: "kr2-days", style: this.state.activeTab === "plan" ? { display: "none" } : null },
3871
+ { className: "kr2-days", style: this.state.activeTab === "plan" || this.state.activeTab === "strong" ? { display: "none" } : null },
3258
3872
  React.createElement(
3259
3873
  "button",
3260
3874
  { className: "kr2-day" + (day === ALL_DAYS_KEY ? " kr2-day-active" : ""), onClick: () => this.setState({ day: ALL_DAYS_KEY }) },
@@ -3279,7 +3893,7 @@ class KoushuRateApp extends React.Component {
3279
3893
  : null,
3280
3894
  React.createElement(
3281
3895
  "div",
3282
- { className: "kr2-list-head", style: this.state.activeTab === "plan" ? { display: "none" } : null },
3896
+ { className: "kr2-list-head", style: this.state.activeTab === "plan" || this.state.activeTab === "strong" ? { display: "none" } : null },
3283
3897
  React.createElement("span", { className: "kr2-head-name" }, "装备"),
3284
3898
  React.createElement("span", { className: "kr2-head-secretary" }, "秘书舰"),
3285
3899
  React.createElement("span", { className: "kr2-head-meta" }, "可改修日期"),
@@ -3296,7 +3910,7 @@ class KoushuRateApp extends React.Component {
3296
3910
  ),
3297
3911
  React.createElement(
3298
3912
  "div",
3299
- { className: "kr2-list", style: this.state.activeTab === "plan" ? { display: "none" } : null },
3913
+ { className: "kr2-list", style: this.state.activeTab === "plan" || this.state.activeTab === "strong" ? { display: "none" } : null },
3300
3914
  rows.length === 0
3301
3915
  ? React.createElement("div", { className: "kr2-empty" }, favoritesOnly ? "还没有收藏装备" : "没有匹配的装备")
3302
3916
  : rows.map((row) =>
@@ -3323,6 +3937,7 @@ class KoushuRateApp extends React.Component {
3323
3937
  selection: this.state.planSelection || {},
3324
3938
  onToggle: this.togglePlanRow,
3325
3939
  onTarget: this.setPlanTarget,
3940
+ onEvo: this.setPlanEvo,
3326
3941
  onQty: this.setPlanQty,
3327
3942
  onSelectAll: this.selectAllPlan,
3328
3943
  onMaterialClick: this.openKcDevPopup,
@@ -3331,6 +3946,13 @@ class KoushuRateApp extends React.Component {
3331
3946
  onToggleIncludeDevExpected: this.toggleIncludeDevExpected,
3332
3947
  })
3333
3948
  : null,
3949
+ this.state.activeTab === "strong"
3950
+ ? React.createElement(StrongPage, {
3951
+ rows: this.state.rows.filter((row) => !!this.state.favorites[row.id]),
3952
+ inventoryByEquip,
3953
+ selection: this.state.planSelection || {},
3954
+ })
3955
+ : null,
3334
3956
  kcDevPopup
3335
3957
  ? React.createElement(
3336
3958
  "div",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poi-plugin-koushu-rate",
3
- "version": "2.0.12",
3
+ "version": "2.0.13",
4
4
  "description": "全装备改修资材计算与推荐",
5
5
  "main": "index.js",
6
6
  "files": [