{"files": {"main.ts": "import {run} from './core.ts';\nimport {POLICY} from './policy.ts';\nexport function evaluate(payload: any): any { return run(payload, POLICY); }\n", "core.ts": "import {parseDecimal, addDecimal, formatDecimal} from './helpers.ts';\nimport type {Dec} from './helpers.ts';\nexport function run(payload: any, policy: any): any {\n  const now: number = payload.now;\n  const events: any[] = Array.isArray(payload.events) ? payload.events : [];\n  const maxAge: number = policy.max_age;\n  const inclusiveAge: boolean = !!policy.inclusive_age;\n  const auditDuplicate: boolean = !!policy.audit_duplicate;\n  const scopeTenant: boolean = policy.scope_key === 'tenant';\n  const duplicates: string[] = [];\n  const seen = new Set<string>();\n  const after: Array<{ev: any, idx: number}> = [];\n  for (let i = 0; i < events.length; i++) {\n    const ev = events[i];\n    const age = now - ev.ts;\n    if (inclusiveAge ? age > maxAge : age >= maxAge) continue;\n    const key = scopeTenant ? ev.tenant + '\\u0000' + ev.id : ev.id;\n    if (seen.has(key)) {\n      if (auditDuplicate) duplicates.push(ev.id);\n      continue;\n    }\n    seen.add(key);\n    after.push({ev, idx: i});\n  }\n  const groups = new Map<string, {tenant: string, entity: string, earliest: number, items: Array<{ev: any, idx: number}>}>();\n  for (const item of after) {\n    const gk = item.ev.tenant + '\\u0000' + item.ev.entity;\n    let g = groups.get(gk);\n    if (!g) { g = {tenant: item.ev.tenant, entity: item.ev.entity, earliest: item.idx, items: []}; groups.set(gk, g); }\n    if (item.idx < g.earliest) g.earliest = item.idx;\n    g.items.push(item);\n  }\n  const sortField: string = (policy.latest_by === 'seq') ? 'seq' : 'ts';\n  const tieLast: boolean = policy.tie_policy === 'last';\n  const entitiesWithOrder: Array<{tenant: string, entity: string, value: string, deleted: boolean, earliest: number}> = [];\n  for (const g of groups.values()) {\n    const byValue = new Map<any, {ev: any, idx: number}>();\n    for (const item of g.items) {\n      const v = item.ev[sortField];\n      const existing = byValue.get(v);\n      if (!existing) byValue.set(v, item);\n      else if (tieLast ? item.idx > existing.idx : item.idx < existing.idx) byValue.set(v, item);\n    }\n    const retained = Array.from(byValue.values()).slice().sort((a: any, b: any) => {\n      const av = a.ev[sortField]; const bv = b.ev[sortField];\n      if (av < bv) return -1; if (av > bv) return 1; return a.idx - b.idx;\n    });\n    let processedSeq = 0;\n    let value: Dec = {units: 0n, scale: 0};\n    let deleted = false;\n    let anyDelete = false;\n    for (const item of retained) {\n      const ev = item.ev;\n      if (ev.kind === 'delete') anyDelete = true;\n      if (policy.gap_policy === 'ignore') {\n        if (ev.seq !== processedSeq + 1) continue;\n      }\n      processedSeq = ev.seq;\n      if (ev.kind === 'delete') {\n        deleted = true;\n      } else if (ev.kind === 'set') {\n        if (!deleted || policy.allow_resurrection) {\n          deleted = false;\n          const amt = parseDecimal(String(ev.amount));\n          if (policy.amount_mode === 'absolute') value = amt; else value = addDecimal(value, amt);\n        }\n      }\n    }\n    if (policy.delete_wins && anyDelete) deleted = true;\n    entitiesWithOrder.push({tenant: g.tenant, entity: g.entity, value: formatDecimal(value, policy.precision), deleted, earliest: g.earliest});\n  }\n  let entities: any[];\n  if (policy.order === 'key') {\n    entities = entitiesWithOrder.slice().sort((a: any, b: any) => a.tenant < b.tenant ? -1 : a.tenant > b.tenant ? 1 : a.entity < b.entity ? -1 : a.entity > b.entity ? 1 : 0).map((e: any) => ({tenant: e.tenant, entity: e.entity, value: e.value, deleted: e.deleted}));\n  } else {\n    entities = entitiesWithOrder.slice().sort((a: any, b: any) => a.earliest - b.earliest).map((e: any) => ({tenant: e.tenant, entity: e.entity, value: e.value, deleted: e.deleted}));\n  }\n  return {entities, duplicates};\n}\n", "policy.ts": "export const POLICY: any = {\"allow_resurrection\": false, \"amount_mode\": \"delta\", \"audit_duplicate\": false, \"delete_wins\": false, \"gap_policy\": \"ignore\", \"inclusive_age\": false, \"latest_by\": \"timestamp\", \"max_age\": 120, \"order\": \"input\", \"precision\": 2, \"scope_key\": \"global\", \"tie_policy\": \"last\"};\n", "helpers.ts": "export interface Dec { units: bigint; scale: number; }\nfunction pow10(n: number): bigint { return 10n ** BigInt(n); }\nexport function parseDecimal(s: string): Dec {\n  let t = String(s).trim();\n  let neg = false;\n  if (t.startsWith('-')) { neg = true; t = t.slice(1); } else if (t.startsWith('+')) { t = t.slice(1); }\n  const dot = t.indexOf('.');\n  let intPart = dot >= 0 ? t.slice(0, dot) : t;\n  let fracPart = dot >= 0 ? t.slice(dot + 1) : '';\n  if (intPart === '') intPart = '0';\n  const digits = intPart + fracPart;\n  let units = BigInt(digits === '' ? '0' : digits);\n  if (neg) units = -units;\n  return {units, scale: fracPart.length};\n}\nexport function addDecimal(a: Dec, b: Dec): Dec {\n  if (a.scale === b.scale) return {units: a.units + b.units, scale: a.scale};\n  if (a.scale > b.scale) return {units: a.units + b.units * pow10(a.scale - b.scale), scale: a.scale};\n  return {units: a.units * pow10(b.scale - a.scale) + b.units, scale: b.scale};\n}\nexport function formatDecimal(value: Dec, precision: number): string {\n  let scaled: bigint;\n  const neg = value.units < 0n;\n  const absUnits = neg ? -value.units : value.units;\n  if (value.scale <= precision) {\n    scaled = absUnits * pow10(precision - value.scale);\n  } else {\n    const divisor = pow10(value.scale - precision);\n    const q = absUnits / divisor;\n    const r = absUnits % divisor;\n    scaled = (r * 2n >= divisor) ? q + 1n : q;\n  }\n  const sign = neg && scaled !== 0n ? '-' : '';\n  if (precision === 0) return sign + scaled.toString();\n  const base = pow10(precision);\n  const intPart = scaled / base;\n  const fracPart = scaled % base;\n  return sign + intPart.toString() + '.' + fracPart.toString().padStart(precision, '0');\n}\n"}}