@axiapps/bridge-metrics 0.1.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.
Files changed (86) hide show
  1. package/dist/aggregationTypes.cjs +18 -0
  2. package/dist/aggregationTypes.d.cts +21 -0
  3. package/dist/aggregationTypes.d.ts +21 -0
  4. package/dist/aggregationTypes.js +1 -0
  5. package/dist/boonGeneration.cjs +308 -0
  6. package/dist/boonGeneration.d.cts +65 -0
  7. package/dist/boonGeneration.d.ts +65 -0
  8. package/dist/boonGeneration.js +16 -0
  9. package/dist/chunk-42DVJJLC.js +106 -0
  10. package/dist/chunk-4F55Q6K2.js +0 -0
  11. package/dist/chunk-ELKDB763.js +349 -0
  12. package/dist/chunk-FU74LJEM.js +77 -0
  13. package/dist/chunk-J3YCFY3C.js +37 -0
  14. package/dist/chunk-JP2ZL44R.js +18 -0
  15. package/dist/chunk-K2SRAMGC.js +0 -0
  16. package/dist/chunk-KRHODGVU.js +48 -0
  17. package/dist/chunk-LIGIXSSA.js +1383 -0
  18. package/dist/chunk-M2WR3JBQ.js +0 -0
  19. package/dist/chunk-PMVLNDZZ.js +279 -0
  20. package/dist/chunk-R5EJF5AW.js +147 -0
  21. package/dist/chunk-RGXSI3AI.js +298 -0
  22. package/dist/chunk-UFJJ6WLD.js +197 -0
  23. package/dist/chunk-WW5XFXGC.js +234 -0
  24. package/dist/chunk-ZFZS7JFU.js +10 -0
  25. package/dist/combatMetrics.cjs +251 -0
  26. package/dist/combatMetrics.d.cts +26 -0
  27. package/dist/combatMetrics.d.ts +26 -0
  28. package/dist/combatMetrics.js +21 -0
  29. package/dist/computePlayerAggregation.cjs +2042 -0
  30. package/dist/computePlayerAggregation.d.cts +249 -0
  31. package/dist/computePlayerAggregation.d.ts +249 -0
  32. package/dist/computePlayerAggregation.js +30 -0
  33. package/dist/conditionsMetrics.cjs +328 -0
  34. package/dist/conditionsMetrics.d.cts +67 -0
  35. package/dist/conditionsMetrics.d.ts +67 -0
  36. package/dist/conditionsMetrics.js +18 -0
  37. package/dist/constants.cjs +36 -0
  38. package/dist/constants.d.cts +18 -0
  39. package/dist/constants.d.ts +18 -0
  40. package/dist/constants.js +10 -0
  41. package/dist/dashboardMetrics.cjs +226 -0
  42. package/dist/dashboardMetrics.d.cts +29 -0
  43. package/dist/dashboardMetrics.d.ts +29 -0
  44. package/dist/dashboardMetrics.js +42 -0
  45. package/dist/dpsReportTypes.cjs +18 -0
  46. package/dist/dpsReportTypes.d.cts +294 -0
  47. package/dist/dpsReportTypes.d.ts +294 -0
  48. package/dist/dpsReportTypes.js +1 -0
  49. package/dist/index.cjs +2902 -0
  50. package/dist/index.d.cts +13 -0
  51. package/dist/index.d.ts +13 -0
  52. package/dist/index.js +152 -0
  53. package/dist/metrics-methods.json +38 -0
  54. package/dist/metricsSettings.cjs +75 -0
  55. package/dist/metricsSettings.d.cts +23 -0
  56. package/dist/metricsSettings.d.ts +23 -0
  57. package/dist/metricsSettings.js +8 -0
  58. package/dist/professionUtils.cjs +265 -0
  59. package/dist/professionUtils.d.cts +10 -0
  60. package/dist/professionUtils.d.ts +10 -0
  61. package/dist/professionUtils.js +20 -0
  62. package/dist/reportMetrics.cjs +224 -0
  63. package/dist/reportMetrics.d.cts +85 -0
  64. package/dist/reportMetrics.d.ts +85 -0
  65. package/dist/reportMetrics.js +12 -0
  66. package/dist/resUtility.cjs +52 -0
  67. package/dist/resUtility.d.cts +5 -0
  68. package/dist/resUtility.d.ts +5 -0
  69. package/dist/resUtility.js +8 -0
  70. package/dist/roles.cjs +18 -0
  71. package/dist/roles.d.cts +17 -0
  72. package/dist/roles.d.ts +17 -0
  73. package/dist/roles.js +1 -0
  74. package/dist/rollup.cjs +378 -0
  75. package/dist/rollup.d.cts +103 -0
  76. package/dist/rollup.d.ts +103 -0
  77. package/dist/rollup.js +16 -0
  78. package/dist/statsMetrics.cjs +153 -0
  79. package/dist/statsMetrics.d.cts +39 -0
  80. package/dist/statsMetrics.d.ts +39 -0
  81. package/dist/statsMetrics.js +22 -0
  82. package/dist/timestampUtils.cjs +63 -0
  83. package/dist/timestampUtils.d.cts +12 -0
  84. package/dist/timestampUtils.d.ts +12 -0
  85. package/dist/timestampUtils.js +9 -0
  86. package/package.json +44 -0
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/aggregationTypes.ts
17
+ var aggregationTypes_exports = {};
18
+ module.exports = __toCommonJS(aggregationTypes_exports);
@@ -0,0 +1,21 @@
1
+ interface PlayerSkillDamageEntry {
2
+ id: string;
3
+ name: string;
4
+ icon?: string;
5
+ damage: number;
6
+ downContribution: number;
7
+ hits: number;
8
+ casts: number;
9
+ min: number;
10
+ max: number;
11
+ }
12
+ interface PlayerHealingSkillEntry {
13
+ id: string;
14
+ name: string;
15
+ icon?: string;
16
+ total: number;
17
+ hits: number;
18
+ max: number;
19
+ }
20
+
21
+ export type { PlayerHealingSkillEntry, PlayerSkillDamageEntry };
@@ -0,0 +1,21 @@
1
+ interface PlayerSkillDamageEntry {
2
+ id: string;
3
+ name: string;
4
+ icon?: string;
5
+ damage: number;
6
+ downContribution: number;
7
+ hits: number;
8
+ casts: number;
9
+ min: number;
10
+ max: number;
11
+ }
12
+ interface PlayerHealingSkillEntry {
13
+ id: string;
14
+ name: string;
15
+ icon?: string;
16
+ total: number;
17
+ hits: number;
18
+ max: number;
19
+ }
20
+
21
+ export type { PlayerHealingSkillEntry, PlayerSkillDamageEntry };
@@ -0,0 +1 @@
1
+ import "./chunk-M2WR3JBQ.js";
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/boonGeneration.ts
21
+ var boonGeneration_exports = {};
22
+ __export(boonGeneration_exports, {
23
+ buildBoonLeaderboards: () => buildBoonLeaderboards,
24
+ buildBoonTables: () => buildBoonTables,
25
+ computeBoonMetrics: () => computeBoonMetrics,
26
+ formatBoonMetricDisplay: () => formatBoonMetricDisplay,
27
+ getBoonMetricValue: () => getBoonMetricValue,
28
+ getPlayerBoonGenerationMs: () => getPlayerBoonGenerationMs
29
+ });
30
+ module.exports = __toCommonJS(boonGeneration_exports);
31
+ var BOON_CATEGORIES = ["selfBuffs", "groupBuffs", "squadBuffs"];
32
+ var CATEGORY_COUNT = {
33
+ selfBuffs: () => 1,
34
+ groupBuffs: (groupCount) => Math.max(groupCount - 1, 0),
35
+ squadBuffs: (_groupCount, squadCount) => Math.max(squadCount - 1, 0)
36
+ };
37
+ var safeDiv = (a, b, fallback = 0) => b ? a / b : fallback;
38
+ var isBoon = (meta) => {
39
+ if (!meta?.classification) return true;
40
+ return meta.classification === "Boon";
41
+ };
42
+ var toBoonId = (id) => `b${id}`;
43
+ var getActiveTimeMs = (player, fallbackMs) => {
44
+ const activeTimes = Array.isArray(player?.activeTimes) ? player.activeTimes : [];
45
+ const activeMs = typeof activeTimes[0] === "number" ? activeTimes[0] : 0;
46
+ return activeMs > 0 ? activeMs : fallbackMs;
47
+ };
48
+ var computeGenerationMs = (category, stacking, generation, wasted, durationMs, groupCount, squadCount) => {
49
+ const count = CATEGORY_COUNT[category](groupCount, squadCount);
50
+ if (!count || !durationMs) {
51
+ return { generationMs: 0, wastedMs: 0 };
52
+ }
53
+ if (stacking) {
54
+ return {
55
+ generationMs: generation * durationMs * count,
56
+ wastedMs: wasted * durationMs * count
57
+ };
58
+ }
59
+ return {
60
+ generationMs: generation / 100 * durationMs * count,
61
+ wastedMs: wasted / 100 * durationMs * count
62
+ };
63
+ };
64
+ var computeBoonMetrics = (row, category, stacking) => {
65
+ const activeTimeMs = row.activeTimeMs || 1;
66
+ const numFights = row.numFights || 1;
67
+ const groupSupported = row.groupSupported || 1;
68
+ const squadSupported = row.squadSupported || 1;
69
+ const selfData = row.categories.selfBuffs;
70
+ const squadData = row.categories.squadBuffs;
71
+ const sourceData = category === "totalBuffs" ? {
72
+ generationMs: selfData.generationMs + squadData.generationMs,
73
+ wastedMs: selfData.wastedMs + squadData.wastedMs
74
+ } : row.categories[category];
75
+ const generationMs = sourceData.generationMs;
76
+ const wastedMs = sourceData.wastedMs;
77
+ let denom = 1;
78
+ if (category === "groupBuffs") {
79
+ denom = safeDiv(groupSupported - numFights, numFights, 1);
80
+ } else if (category === "squadBuffs") {
81
+ denom = safeDiv(squadSupported - numFights, numFights, 1);
82
+ } else if (category === "totalBuffs") {
83
+ denom = squadSupported || 1;
84
+ }
85
+ let uptimeRaw = 0;
86
+ let wastedRaw = 0;
87
+ if (category === "selfBuffs") {
88
+ uptimeRaw = stacking ? safeDiv(generationMs, activeTimeMs) : safeDiv(generationMs, activeTimeMs) * 100;
89
+ wastedRaw = stacking ? safeDiv(wastedMs, activeTimeMs) : safeDiv(wastedMs, activeTimeMs) * 100;
90
+ } else {
91
+ const base = safeDiv(generationMs, activeTimeMs) / (denom || 1);
92
+ const wastedBase = safeDiv(wastedMs, activeTimeMs) / (denom || 1);
93
+ uptimeRaw = stacking ? base : base * 100;
94
+ wastedRaw = stacking ? wastedBase : wastedBase * 100;
95
+ }
96
+ return { generationMs, wastedMs, uptimeRaw, wastedRaw };
97
+ };
98
+ var getBoonMetricValue = (row, category, stacking, metric) => {
99
+ const { generationMs, uptimeRaw } = computeBoonMetrics(row, category, stacking);
100
+ const activeTimeMs = row.activeTimeMs || 1;
101
+ if (metric === "total") {
102
+ return generationMs / 1e3;
103
+ }
104
+ if (metric === "average") {
105
+ return safeDiv(generationMs, activeTimeMs);
106
+ }
107
+ return uptimeRaw;
108
+ };
109
+ var formatBoonMetricDisplay = (row, category, stacking, metric, options) => {
110
+ const value = getBoonMetricValue(row, category, stacking, metric);
111
+ const isPercent = metric === "uptime" && !stacking;
112
+ const isRate = metric === "average";
113
+ const decimals = options?.roundCountStats && !isPercent && !isRate ? 0 : 2;
114
+ const formatted = value.toLocaleString(void 0, {
115
+ minimumFractionDigits: decimals,
116
+ maximumFractionDigits: decimals
117
+ });
118
+ if (isPercent) {
119
+ return `${formatted}%`;
120
+ }
121
+ return formatted;
122
+ };
123
+ var buildBoonTables = (logs, splitPlayersByClass = false) => {
124
+ const boonMeta = /* @__PURE__ */ new Map();
125
+ const playerAgg = /* @__PURE__ */ new Map();
126
+ logs.forEach((log) => {
127
+ const details = log.details;
128
+ if (!details) return;
129
+ const durationMs = details.durationMS || 0;
130
+ const buffMap = details.buffMap || {};
131
+ Object.entries(buffMap).forEach(([id, meta]) => {
132
+ if (!boonMeta.has(id)) {
133
+ boonMeta.set(id, meta);
134
+ return;
135
+ }
136
+ const existing = boonMeta.get(id) || {};
137
+ const merged = {
138
+ name: existing.name || meta.name,
139
+ stacking: existing.stacking ?? meta.stacking,
140
+ icon: existing.icon || meta.icon,
141
+ classification: existing.classification || meta.classification
142
+ };
143
+ boonMeta.set(id, merged);
144
+ });
145
+ const players = details.players || [];
146
+ const squadPlayers = players.filter((p) => !p.notInSquad);
147
+ const squadCount = squadPlayers.length;
148
+ const groupCounts = /* @__PURE__ */ new Map();
149
+ squadPlayers.forEach((player) => {
150
+ const group = player.group ?? 0;
151
+ groupCounts.set(group, (groupCounts.get(group) || 0) + 1);
152
+ });
153
+ squadPlayers.forEach((player) => {
154
+ const account = player.account || player.name || player.character_name || "Unknown";
155
+ const profession = player.profession || "Unknown";
156
+ const group = player.group ?? 0;
157
+ const groupCount = groupCounts.get(group) || 1;
158
+ const activeTimeMs = getActiveTimeMs(player, durationMs);
159
+ const key = splitPlayersByClass && profession !== "Unknown" ? `${account}::${profession}` : account;
160
+ if (!playerAgg.has(key)) {
161
+ playerAgg.set(key, {
162
+ account,
163
+ profession,
164
+ professions: /* @__PURE__ */ new Set(),
165
+ professionTimeMs: {},
166
+ activeTimeMs: 0,
167
+ numFights: 0,
168
+ groupSupported: 0,
169
+ squadSupported: 0,
170
+ boons: {}
171
+ });
172
+ }
173
+ const agg = playerAgg.get(key);
174
+ agg.profession = profession;
175
+ if (profession && profession !== "Unknown") {
176
+ agg.professions.add(profession);
177
+ agg.professionTimeMs[profession] = (agg.professionTimeMs[profession] || 0) + activeTimeMs;
178
+ }
179
+ agg.activeTimeMs += activeTimeMs;
180
+ agg.numFights += 1;
181
+ agg.groupSupported += groupCount;
182
+ agg.squadSupported += squadCount;
183
+ BOON_CATEGORIES.forEach((category) => {
184
+ const buffs = player[category] || [];
185
+ buffs.forEach((buff) => {
186
+ if (typeof buff?.id !== "number") return;
187
+ const boonId = toBoonId(buff.id);
188
+ const meta = buffMap[boonId];
189
+ if (!isBoon(meta)) return;
190
+ const stacking = meta?.stacking ?? false;
191
+ const generation = buff.buffData?.[0]?.generation ?? 0;
192
+ const wasted = buff.buffData?.[0]?.wasted ?? 0;
193
+ const { generationMs, wastedMs } = computeGenerationMs(
194
+ category,
195
+ stacking,
196
+ generation,
197
+ wasted,
198
+ durationMs,
199
+ groupCount,
200
+ squadCount
201
+ );
202
+ if (!generationMs && !wastedMs) return;
203
+ if (!boonMeta.has(boonId)) {
204
+ boonMeta.set(boonId, meta || {});
205
+ }
206
+ if (!agg.boons[boonId]) {
207
+ agg.boons[boonId] = {
208
+ selfBuffs: { generationMs: 0, wastedMs: 0 },
209
+ groupBuffs: { generationMs: 0, wastedMs: 0 },
210
+ squadBuffs: { generationMs: 0, wastedMs: 0 }
211
+ };
212
+ }
213
+ agg.boons[boonId][category].generationMs += generationMs;
214
+ agg.boons[boonId][category].wastedMs += wastedMs;
215
+ });
216
+ });
217
+ });
218
+ });
219
+ const boonIds = Array.from(boonMeta.keys()).filter((id) => isBoon(boonMeta.get(id)));
220
+ const boonTables = boonIds.map((boonId) => {
221
+ const meta = boonMeta.get(boonId) || {};
222
+ const rows = [];
223
+ playerAgg.forEach((agg) => {
224
+ const boonData = agg.boons[boonId];
225
+ if (!boonData) return;
226
+ const hasData = BOON_CATEGORIES.some((category) => boonData[category].generationMs > 0 || boonData[category].wastedMs > 0);
227
+ if (!hasData) return;
228
+ const professionList = Array.from(agg.professions || []).filter((prof) => prof && prof !== "Unknown");
229
+ let primaryProfession = agg.profession;
230
+ if (professionList.length > 0) {
231
+ primaryProfession = professionList[0];
232
+ let maxTime = agg.professionTimeMs?.[primaryProfession] || 0;
233
+ professionList.forEach((prof) => {
234
+ const time = agg.professionTimeMs?.[prof] || 0;
235
+ if (time > maxTime) {
236
+ maxTime = time;
237
+ primaryProfession = prof;
238
+ }
239
+ });
240
+ }
241
+ rows.push({
242
+ account: agg.account,
243
+ profession: primaryProfession || "Unknown",
244
+ professionList,
245
+ activeTimeMs: agg.activeTimeMs || 1,
246
+ numFights: agg.numFights || 1,
247
+ groupSupported: agg.groupSupported || 1,
248
+ squadSupported: agg.squadSupported || 1,
249
+ categories: {
250
+ selfBuffs: { ...boonData.selfBuffs },
251
+ groupBuffs: { ...boonData.groupBuffs },
252
+ squadBuffs: { ...boonData.squadBuffs }
253
+ }
254
+ });
255
+ });
256
+ return {
257
+ id: boonId,
258
+ name: meta.name || boonId,
259
+ icon: meta.icon,
260
+ stacking: meta.stacking ?? false,
261
+ rows
262
+ };
263
+ }).filter((boon) => boon.rows.length > 0);
264
+ return { boonTables };
265
+ };
266
+ var buildBoonLeaderboards = (tables, metric = "uptime") => {
267
+ const result = {};
268
+ for (const table of tables) {
269
+ const ranked = table.rows.map((row) => ({
270
+ account: row.account,
271
+ profession: row.profession,
272
+ professionList: row.professionList,
273
+ value: getBoonMetricValue(row, "squadBuffs", table.stacking, metric),
274
+ count: row.numFights
275
+ })).filter((r) => Number.isFinite(r.value) && r.value > 0).sort((a, b) => b.value - a.value || a.account.localeCompare(b.account));
276
+ let lastValue = null;
277
+ let lastRank = 0;
278
+ result[table.id] = ranked.map((row, index) => {
279
+ if (lastValue === null || row.value !== lastValue) {
280
+ lastRank = index + 1;
281
+ lastValue = row.value;
282
+ }
283
+ return { ...row, rank: lastRank };
284
+ });
285
+ }
286
+ return result;
287
+ };
288
+ var getPlayerBoonGenerationMs = (player, category, boonId, durationMs, groupCount, squadCount, buffMap = {}) => {
289
+ const buffs = player?.[category] || [];
290
+ const target = buffs.find((buff) => buff.id === boonId);
291
+ if (!target) {
292
+ return { generationMs: 0, wastedMs: 0 };
293
+ }
294
+ const meta = buffMap[toBoonId(boonId)];
295
+ const stacking = meta?.stacking ?? false;
296
+ const generation = target.buffData?.[0]?.generation ?? 0;
297
+ const wasted = target.buffData?.[0]?.wasted ?? 0;
298
+ return computeGenerationMs(category, stacking, generation, wasted, durationMs, groupCount, squadCount);
299
+ };
300
+ // Annotate the CommonJS export names for ESM import in node:
301
+ 0 && (module.exports = {
302
+ buildBoonLeaderboards,
303
+ buildBoonTables,
304
+ computeBoonMetrics,
305
+ formatBoonMetricDisplay,
306
+ getBoonMetricValue,
307
+ getPlayerBoonGenerationMs
308
+ });
@@ -0,0 +1,65 @@
1
+ type BoonCategory = 'selfBuffs' | 'groupBuffs' | 'squadBuffs' | 'totalBuffs';
2
+ type BoonMetric = 'total' | 'average' | 'uptime';
3
+ interface BuffInfo {
4
+ name?: string;
5
+ stacking?: boolean;
6
+ icon?: string;
7
+ classification?: string;
8
+ }
9
+ interface BuffGenerationEntry {
10
+ id: number;
11
+ buffData?: Array<{
12
+ generation?: number;
13
+ wasted?: number;
14
+ }>;
15
+ }
16
+ interface BoonRow {
17
+ account: string;
18
+ profession: string;
19
+ professionList?: string[];
20
+ activeTimeMs: number;
21
+ numFights: number;
22
+ groupSupported: number;
23
+ squadSupported: number;
24
+ categories: Record<Exclude<BoonCategory, 'totalBuffs'>, {
25
+ generationMs: number;
26
+ wastedMs: number;
27
+ }>;
28
+ }
29
+ interface BoonTable {
30
+ id: string;
31
+ name: string;
32
+ icon?: string;
33
+ stacking: boolean;
34
+ rows: BoonRow[];
35
+ }
36
+ declare const computeBoonMetrics: (row: BoonRow, category: BoonCategory, stacking: boolean) => {
37
+ generationMs: number;
38
+ wastedMs: number;
39
+ uptimeRaw: number;
40
+ wastedRaw: number;
41
+ };
42
+ declare const getBoonMetricValue: (row: BoonRow, category: BoonCategory, stacking: boolean, metric: BoonMetric) => number;
43
+ declare const formatBoonMetricDisplay: (row: BoonRow, category: BoonCategory, stacking: boolean, metric: BoonMetric, options?: {
44
+ roundCountStats?: boolean;
45
+ }) => string;
46
+ declare const buildBoonTables: (logs: Array<{
47
+ details?: any;
48
+ }>, splitPlayersByClass?: boolean) => {
49
+ boonTables: BoonTable[];
50
+ };
51
+ interface BoonLeaderboardRow {
52
+ rank: number;
53
+ account: string;
54
+ profession: string;
55
+ professionList?: string[];
56
+ value: number;
57
+ count?: number;
58
+ }
59
+ declare const buildBoonLeaderboards: (tables: BoonTable[], metric?: BoonMetric) => Record<string, BoonLeaderboardRow[]>;
60
+ declare const getPlayerBoonGenerationMs: (player: any, category: Exclude<BoonCategory, "totalBuffs">, boonId: number, durationMs: number, groupCount: number, squadCount: number, buffMap?: Record<string, BuffInfo>) => {
61
+ generationMs: number;
62
+ wastedMs: number;
63
+ };
64
+
65
+ export { type BoonCategory, type BoonLeaderboardRow, type BoonMetric, type BoonRow, type BoonTable, type BuffGenerationEntry, type BuffInfo, buildBoonLeaderboards, buildBoonTables, computeBoonMetrics, formatBoonMetricDisplay, getBoonMetricValue, getPlayerBoonGenerationMs };
@@ -0,0 +1,65 @@
1
+ type BoonCategory = 'selfBuffs' | 'groupBuffs' | 'squadBuffs' | 'totalBuffs';
2
+ type BoonMetric = 'total' | 'average' | 'uptime';
3
+ interface BuffInfo {
4
+ name?: string;
5
+ stacking?: boolean;
6
+ icon?: string;
7
+ classification?: string;
8
+ }
9
+ interface BuffGenerationEntry {
10
+ id: number;
11
+ buffData?: Array<{
12
+ generation?: number;
13
+ wasted?: number;
14
+ }>;
15
+ }
16
+ interface BoonRow {
17
+ account: string;
18
+ profession: string;
19
+ professionList?: string[];
20
+ activeTimeMs: number;
21
+ numFights: number;
22
+ groupSupported: number;
23
+ squadSupported: number;
24
+ categories: Record<Exclude<BoonCategory, 'totalBuffs'>, {
25
+ generationMs: number;
26
+ wastedMs: number;
27
+ }>;
28
+ }
29
+ interface BoonTable {
30
+ id: string;
31
+ name: string;
32
+ icon?: string;
33
+ stacking: boolean;
34
+ rows: BoonRow[];
35
+ }
36
+ declare const computeBoonMetrics: (row: BoonRow, category: BoonCategory, stacking: boolean) => {
37
+ generationMs: number;
38
+ wastedMs: number;
39
+ uptimeRaw: number;
40
+ wastedRaw: number;
41
+ };
42
+ declare const getBoonMetricValue: (row: BoonRow, category: BoonCategory, stacking: boolean, metric: BoonMetric) => number;
43
+ declare const formatBoonMetricDisplay: (row: BoonRow, category: BoonCategory, stacking: boolean, metric: BoonMetric, options?: {
44
+ roundCountStats?: boolean;
45
+ }) => string;
46
+ declare const buildBoonTables: (logs: Array<{
47
+ details?: any;
48
+ }>, splitPlayersByClass?: boolean) => {
49
+ boonTables: BoonTable[];
50
+ };
51
+ interface BoonLeaderboardRow {
52
+ rank: number;
53
+ account: string;
54
+ profession: string;
55
+ professionList?: string[];
56
+ value: number;
57
+ count?: number;
58
+ }
59
+ declare const buildBoonLeaderboards: (tables: BoonTable[], metric?: BoonMetric) => Record<string, BoonLeaderboardRow[]>;
60
+ declare const getPlayerBoonGenerationMs: (player: any, category: Exclude<BoonCategory, "totalBuffs">, boonId: number, durationMs: number, groupCount: number, squadCount: number, buffMap?: Record<string, BuffInfo>) => {
61
+ generationMs: number;
62
+ wastedMs: number;
63
+ };
64
+
65
+ export { type BoonCategory, type BoonLeaderboardRow, type BoonMetric, type BoonRow, type BoonTable, type BuffGenerationEntry, type BuffInfo, buildBoonLeaderboards, buildBoonTables, computeBoonMetrics, formatBoonMetricDisplay, getBoonMetricValue, getPlayerBoonGenerationMs };
@@ -0,0 +1,16 @@
1
+ import {
2
+ buildBoonLeaderboards,
3
+ buildBoonTables,
4
+ computeBoonMetrics,
5
+ formatBoonMetricDisplay,
6
+ getBoonMetricValue,
7
+ getPlayerBoonGenerationMs
8
+ } from "./chunk-PMVLNDZZ.js";
9
+ export {
10
+ buildBoonLeaderboards,
11
+ buildBoonTables,
12
+ computeBoonMetrics,
13
+ formatBoonMetricDisplay,
14
+ getBoonMetricValue,
15
+ getPlayerBoonGenerationMs
16
+ };
@@ -0,0 +1,106 @@
1
+ // src/statsMetrics.ts
2
+ var OFFENSE_METRICS = [
3
+ { id: "damage", label: "Damage", field: "damage", source: "dpsAll" },
4
+ { id: "directDmg", label: "Direct Damage", field: "directDmg", source: "statsTargets" },
5
+ { id: "connectedDamageCount", label: "Connected Damage Count", field: "connectedDamageCount", source: "statsTargets" },
6
+ { id: "connectedDirectDamageCount", label: "Connected Direct Damage Count", field: "connectedDirectDamageCount", source: "statsTargets" },
7
+ { id: "battleStandardHits", label: "Battle Standard Tracking" },
8
+ { id: "criticalRate", label: "Critical Rate", field: "criticalRate", isRate: true, isPercent: true, denomField: "critableDirectDamageCount", source: "statsTargets" },
9
+ { id: "criticalDmg", label: "Critical Damage", field: "criticalDmg", source: "statsTargets" },
10
+ { id: "flankingRate", label: "Flanking Rate", field: "flankingRate", isRate: true, isPercent: true, denomField: "connectedDirectDamageCount", source: "statsTargets" },
11
+ { id: "glanceRate", label: "Glance Rate", field: "glanceRate", isRate: true, isPercent: true, denomField: "connectedDirectDamageCount", source: "statsTargets" },
12
+ { id: "missed", label: "Missed", field: "missed", source: "statsTargets" },
13
+ { id: "evaded", label: "Evaded (enemy)", field: "evaded", source: "statsTargets" },
14
+ { id: "blocked", label: "Blocked (enemy)", field: "blocked", source: "statsTargets" },
15
+ { id: "interrupts", label: "Interrupts", field: "interrupts", source: "statsTargets" },
16
+ { id: "invulned", label: "Invulned", field: "invulned", source: "statsTargets" },
17
+ { id: "killed", label: "Killed", field: "killed", source: "statsTargets" },
18
+ { id: "downed", label: "Downed", field: "downed", source: "statsTargets" },
19
+ { id: "downContribution", label: "Down Contribution", field: "downContribution", source: "statsTargets" },
20
+ { id: "downContributionPercent", label: "Down Contribution %", isRate: true, isPercent: true },
21
+ { id: "againstDownedDamage", label: "Against Downed Damage", field: "againstDownedDamage", source: "statsTargets" },
22
+ { id: "appliedCrowdControl", label: "Applied CC", field: "appliedCrowdControl", source: "statsTargets" },
23
+ { id: "appliedCrowdControlDuration", label: "Applied CC Duration", field: "appliedCrowdControlDuration", source: "statsTargets" },
24
+ { id: "appliedCrowdControlDownContribution", label: "Applied CC Down Contribution", field: "appliedCrowdControlDownContribution", source: "statsTargets" },
25
+ { id: "appliedCrowdControlDurationDownContribution", label: "Applied CC Duration Down Contribution", field: "appliedCrowdControlDurationDownContribution", source: "statsTargets" },
26
+ { id: "boonStrips", label: "Boon Strips", field: "boonStrips", source: "support" }
27
+ ];
28
+ var DEFENSE_METRICS = [
29
+ { id: "damageTaken", label: "Damage Taken", field: "damageTaken" },
30
+ { id: "minionDamageTaken", label: "Minion Damage Taken" },
31
+ { id: "damageTakenCount", label: "Damage Taken Count", field: "damageTakenCount" },
32
+ { id: "conditionDamageTaken", label: "Condition Damage Taken", field: "conditionDamageTaken" },
33
+ { id: "conditionDamageTakenCount", label: "Condition Damage Taken Count", field: "conditionDamageTakenCount" },
34
+ { id: "powerDamageTaken", label: "Power Damage Taken", field: "powerDamageTaken" },
35
+ { id: "powerDamageTakenCount", label: "Power Damage Taken Count", field: "powerDamageTakenCount" },
36
+ { id: "downedDamageTaken", label: "Downed Damage Taken", field: "downedDamageTaken" },
37
+ { id: "downedDamageTakenCount", label: "Downed Damage Taken Count", field: "downedDamageTakenCount" },
38
+ { id: "damageBarrier", label: "Damage Barrier", field: "damageBarrier" },
39
+ { id: "damageBarrierCount", label: "Damage Barrier Count", field: "damageBarrierCount" },
40
+ { id: "blockedCount", label: "Blocked Count", field: "blockedCount" },
41
+ { id: "evadedCount", label: "Evaded Count", field: "evadedCount" },
42
+ { id: "missedCount", label: "Missed Count", field: "missedCount" },
43
+ { id: "dodgeCount", label: "Dodge Count", field: "dodgeCount" },
44
+ { id: "invulnedCount", label: "Invulnerable Count", field: "invulnedCount" },
45
+ { id: "interruptedCount", label: "Interrupted Count", field: "interruptedCount" },
46
+ { id: "downCount", label: "Down Count", field: "downCount" },
47
+ { id: "deadCount", label: "Death Count", field: "deadCount" },
48
+ { id: "boonStrips", label: "Boon Strips (Incoming)", field: "boonStrips" },
49
+ { id: "conditionCleanses", label: "Cleanses (Incoming)", field: "conditionCleanses" },
50
+ { id: "receivedCrowdControl", label: "Crowd Control (Incoming)", field: "receivedCrowdControl" }
51
+ ];
52
+ var DAMAGE_MITIGATION_METRICS = [
53
+ { id: "totalHits", label: "Total Hits" },
54
+ { id: "evaded", label: "Evaded" },
55
+ { id: "blocked", label: "Blocked" },
56
+ { id: "glanced", label: "Glanced" },
57
+ { id: "missed", label: "Missed" },
58
+ { id: "invulned", label: "Invulned" },
59
+ { id: "interrupted", label: "Interrupted" },
60
+ { id: "totalMitigation", label: "Damage Mitigation" },
61
+ { id: "minMitigation", label: "Min Damage Mitigation" }
62
+ ];
63
+ var SUPPORT_METRICS = [
64
+ { id: "condiCleanse", label: "Condition Cleanses", field: "condiCleanse" },
65
+ { id: "condiCleanseTime", label: "Condition Cleanse Time", field: "condiCleanseTime", isTime: true },
66
+ { id: "condiCleanseSelf", label: "Condition Cleanse Self", field: "condiCleanseSelf" },
67
+ { id: "condiCleanseTimeSelf", label: "Condition Cleanse Time Self", field: "condiCleanseTimeSelf", isTime: true },
68
+ { id: "boonStrips", label: "Boon Strips", field: "boonStrips" },
69
+ { id: "boonStripsTime", label: "Boon Strips Time", field: "boonStripsTime", isTime: true },
70
+ { id: "boonStripDownContribution", label: "Boon Strip Down Contribution", field: "boonStripDownContribution" },
71
+ { id: "boonStripDownContributionTime", label: "Boon Strip Down Contribution Time", field: "boonStripDownContributionTime", isTime: true },
72
+ { id: "stunBreak", label: "Stun Breaks", field: "stunBreak" },
73
+ { id: "removedStunDuration", label: "Removed Stun Duration", field: "removedStunDuration", isTime: true },
74
+ { id: "resurrects", label: "Resurrects", field: "resurrects" },
75
+ { id: "resurrectTime", label: "Resurrect Time", field: "resurrectTime", isTime: true }
76
+ ];
77
+ var HEALING_METRICS = [
78
+ { id: "healing", label: "Healing", baseField: "healing", perSecond: false, decimals: 0 },
79
+ { id: "healingPerSecond", label: "Healing Per Second", baseField: "healing", perSecond: true, decimals: 2 },
80
+ { id: "barrier", label: "Barrier", baseField: "barrier", perSecond: false, decimals: 0 },
81
+ { id: "barrierPerSecond", label: "Barrier Per Second", baseField: "barrier", perSecond: true, decimals: 2 },
82
+ { id: "downedHealing", label: "Downed Healing", baseField: "downedHealing", perSecond: false, decimals: 0 },
83
+ { id: "downedHealingPerSecond", label: "Downed Healing Per Second", baseField: "downedHealing", perSecond: true, decimals: 1 },
84
+ { id: "resUtility", label: "Resurrect Utility", baseField: "resUtility", perSecond: false, decimals: 0 }
85
+ ];
86
+ var RES_UTILITY_NAME_MATCHES = [
87
+ "battle standard",
88
+ "glyph of renewal",
89
+ "glyph of the stars",
90
+ "illusion of life",
91
+ "spirit of nature",
92
+ "nature spirit",
93
+ "search and rescue",
94
+ "signet of mercy"
95
+ ];
96
+ var RES_UTILITY_IDS = /* @__PURE__ */ new Set([10244]);
97
+
98
+ export {
99
+ OFFENSE_METRICS,
100
+ DEFENSE_METRICS,
101
+ DAMAGE_MITIGATION_METRICS,
102
+ SUPPORT_METRICS,
103
+ HEALING_METRICS,
104
+ RES_UTILITY_NAME_MATCHES,
105
+ RES_UTILITY_IDS
106
+ };
File without changes