{"files":{"main.ts":"import {run} from './core.ts';\nimport {POLICY} from './policy.ts';\nexport function evaluate(payload: any): any { return run(payload, POLICY); }\n","policy.ts":"export const POLICY: any = {delete_wins:false,latest_by:'timestamp',scope_key:'global',tie_policy:'last',allow_resurrection:false,amount_mode:'delta',gap_policy:'ignore',precision:2,inclusive_age:false,max_age:120,audit_duplicate:false,order:'input'};\n","helpers.ts":"export function fracLen(s: string): number { const i = String(s).indexOf('.'); return i < 0 ? 0 : String(s).length - i - 1; }\nexport function toScaled(s: string, scale: number): bigint {\n  const str = String(s);\n  const i = str.indexOf('.');\n  const ip = i < 0 ? str : str.slice(0, i);\n  const fp = i < 0 ? '' : str.slice(i + 1);\n  return BigInt((ip || '0') + fp.padEnd(scale, '0'));\n}\nexport function fmt(v: bigint, scale: number, p: number): string {\n  const div = 10n ** BigInt(scale - p);\n  const q = (v + div / 2n) / div;\n  if (p === 0) return q.toString();\n  const s = q.toString().padStart(p + 1, '0');\n  return s.slice(0, s.length - p) + '.' + s.slice(s.length - p);\n}\n","core.ts":"import {fracLen, toScaled, fmt} from './helpers.ts';\nexport function run(payload: any, policy: any): any {\n  const now = payload.now;\n  const events: any[] = payload.events || [];\n  const p = policy.precision;\n  let scale = p;\n  for (const e of events) scale = Math.max(scale, fracLen(e.amount));\n  const seen = new Set<string>();\n  const duplicates: any[] = [];\n  const kept: {e: any; idx: number}[] = [];\n  events.forEach((e, idx) => {\n    const age = now - e.ts;\n    if (age > policy.max_age) return;\n    if (age === policy.max_age && !policy.inclusive_age) return;\n    const key = policy.scope_key === 'tenant' ? JSON.stringify([e.tenant, e.id]) : JSON.stringify(e.id);\n    if (seen.has(key)) { if (policy.audit_duplicate) duplicates.push(e.id); return; }\n    seen.add(key);\n    kept.push({e, idx});\n  });\n  const groups = new Map<string, {tenant: any; entity: any; first: number; evs: any[]}>();\n  for (const k of kept) {\n    const g = JSON.stringify([k.e.tenant, k.e.entity]);\n    let o = groups.get(g);\n    if (!o) { o = {tenant: k.e.tenant, entity: k.e.entity, first: k.idx, evs: []}; groups.set(g, o); }\n    o.evs.push(k.e);\n  }\n  const field = (policy.latest_by === 'seq') ? 'seq' : 'ts';\n  const out: any[] = [];\n  const list = Array.from(groups.values());\n  for (const g of list) {\n    const byVal = new Map<number, any>();\n    for (const e of g.evs) {\n      if (!byVal.has(e[field]) || policy.tie_policy === 'last') byVal.set(e[field], e);\n    }\n    const sorted = Array.from(byVal.values()).sort((a, b) => a[field] - b[field]);\n    let seq = 0, value = 0n, deleted = false, anyDel = false;\n    for (const e of g.evs) if (e.kind === 'delete') anyDel = true;\n    for (const e of sorted) {\n      if (policy.gap_policy === 'ignore' && e.seq !== seq + 1) continue;\n      seq = e.seq;\n      if (e.kind === 'delete') deleted = true;\n      else {\n        if (!deleted || policy.allow_resurrection) {\n          deleted = false;\n          const a = toScaled(e.amount, scale);\n          value = policy.amount_mode === 'absolute' ? a : value + a;\n        }\n      }\n    }\n    if (policy.delete_wins && anyDel) deleted = true;\n    out.push({tenant: g.tenant, entity: g.entity, value: fmt(value, scale, p), deleted, _f: g.first});\n  }\n  if (policy.order === 'key') {\n    out.sort((a, b) => a.tenant < b.tenant ? -1 : a.tenant > b.tenant ? 1 : a.entity < b.entity ? -1 : a.entity > b.entity ? 1 : 0);\n  } else out.sort((a, b) => a._f - b._f);\n  return {entities: out.map(o => ({tenant: o.tenant, entity: o.entity, value: o.value, deleted: o.deleted})), duplicates};\n}\n"}}