{"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, formatRounded} from './helpers.ts';\n\nexport function run(payload: any, policy: any): any {\n  const now = payload ? payload.now : 0;\n  const rawEvents: any[] = payload && Array.isArray(payload.events) ? payload.events : [];\n  const duplicates: any[] = [];\n  const seen = new Set<string>();\n  const retainedPreTie: Array<{event: any, index: number}> = [];\n  for (let i = 0; i < rawEvents.length; i++) {\n    const event = rawEvents[i];\n    const age = now - event.ts;\n    if (policy.inclusive_age) {\n      if (age > policy.max_age) continue;\n    } else {\n      if (age >= policy.max_age && age > policy.max_age) continue;\n      if (age > policy.max_age) continue;\n      if (age === policy.max_age) continue;\n    }\n    const dedupKey = policy.scope_key === 'tenant' ? String(event.tenant) + '\\u0000' + String(event.id) : String(event.id);\n    if (seen.has(dedupKey)) {\n      if (policy.audit_duplicate) duplicates.push(event.id);\n      continue;\n    }\n    seen.add(dedupKey);\n    retainedPreTie.push({event: event, index: i});\n  }\n  const groups = new Map<string, {tenant: any, entity: any, earliest: number, items: Array<{event: any, index: number}>}>();\n  for (const item of retainedPreTie) {\n    const key = String(item.event.tenant) + '\\u0000' + String(item.event.entity);\n    let group = groups.get(key);\n    if (!group) {\n      group = {tenant: item.event.tenant, entity: item.event.entity, earliest: item.index, items: []};\n      groups.set(key, group);\n    }\n    if (item.index < group.earliest) group.earliest = item.index;\n    group.items.push(item);\n  }\n  const useSeq = policy.latest_by === 'seq' || policy.latest_by === 'sequence';\n  const precision = typeof policy.precision === 'number' ? policy.precision : 0;\n  const results: Array<{tenant: any, entity: any, value: string, deleted: boolean, earliest: number}> = [];\n  for (const group of groups.values()) {\n    const bySortKey = new Map<any, {event: any, index: number}>();\n    for (const item of group.items) {\n      const sortKey = useSeq ? item.event.seq : item.event.ts;\n      if (!bySortKey.has(sortKey)) {\n        bySortKey.set(sortKey, item);\n      } else if (policy.tie_policy === 'last') {\n        bySortKey.set(sortKey, item);\n      }\n    }\n    const retained = Array.from(bySortKey.values());\n    const sorted = retained.slice().sort((a: any, b: any) => {\n      const av = useSeq ? a.event.seq : a.event.ts;\n      const bv = useSeq ? b.event.seq : b.event.ts;\n      if (av < bv) return -1;\n      if (av > bv) return 1;\n      return a.index - b.index;\n    });\n    let processedSeq = 0;\n    let value = {units: 0n, scale: 0};\n    let deleted = false;\n    const hasDelete = sorted.some((item: any) => item.event.kind === 'delete');\n    for (const item of sorted) {\n      const event = item.event;\n      if (policy.gap_policy === 'ignore' && event.seq !== processedSeq + 1) continue;\n      if (event.kind === 'delete') {\n        deleted = true;\n      } else if (event.kind === 'set') {\n        if (!deleted || policy.allow_resurrection) {\n          deleted = false;\n          const amount = parseDecimal(event.amount === undefined || event.amount === null ? '0' : event.amount);\n          if (policy.amount_mode === 'delta') value = addDecimal(value, amount);\n          else value = amount;\n        }\n      }\n      processedSeq = event.seq;\n    }\n    if (policy.delete_wins && hasDelete) deleted = true;\n    results.push({tenant: group.tenant, entity: group.entity, value: formatRounded(value, precision), deleted: deleted, earliest: group.earliest});\n  }\n  if (policy.order === 'key') {\n    results.sort((a: any, b: any) => {\n      const at = String(a.tenant); const bt = String(b.tenant);\n      if (at < bt) return -1; if (at > bt) return 1;\n      const ae = String(a.entity); const be = String(b.entity);\n      if (ae < be) return -1; if (ae > be) return 1; return 0;\n    });\n  } else {\n    results.sort((a: any, b: any) => a.earliest - b.earliest);\n  }\n  const entities = results.map((r: any) => ({tenant: r.tenant, entity: r.entity, value: r.value, deleted: r.deleted}));\n  return {entities: entities, duplicates: duplicates};\n}\n", "policy.ts": "export const POLICY: any = {\n  \"scope_key\": \"tenant\",\n  \"latest_by\": \"sequence\",\n  \"tie_policy\": \"first\",\n  \"delete_wins\": true,\n  \"allow_resurrection\": true,\n  \"amount_mode\": \"absolute\",\n  \"precision\": 0,\n  \"gap_policy\": \"accept\",\n  \"audit_duplicate\": true,\n  \"order\": \"key\",\n  \"max_age\": 60,\n  \"inclusive_age\": true\n};\n", "helpers.ts": "export interface DecimalValue { units: bigint; scale: number; }\n\nexport function parseDecimal(input: any): DecimalValue {\n  let s = String(input).trim();\n  let negative = false;\n  if (s.startsWith('-')) { negative = true; s = s.slice(1); }\n  else if (s.startsWith('+')) { s = s.slice(1); }\n  const dot = s.indexOf('.');\n  let intPart = dot === -1 ? s : s.slice(0, dot);\n  let fracPart = dot === -1 ? '' : s.slice(dot + 1);\n  if (intPart === '') intPart = '0';\n  const digits = (intPart + fracPart).replace(/^0+(?=\\d)/, '');\n  let units = BigInt(digits === '' ? '0' : digits);\n  if (negative) units = -units;\n  return {units: units, scale: fracPart.length};\n}\n\nexport function addDecimal(a: DecimalValue, b: DecimalValue): DecimalValue {\n  if (a.scale === b.scale) return {units: a.units + b.units, scale: a.scale};\n  if (a.scale > b.scale) {\n    const factor = 10n ** BigInt(a.scale - b.scale);\n    return {units: a.units + b.units * factor, scale: a.scale};\n  }\n  const factor = 10n ** BigInt(b.scale - a.scale);\n  return {units: a.units * factor + b.units, scale: b.scale};\n}\n\nexport function formatRounded(value: DecimalValue, precision: number): string {\n  const p = precision >= 0 ? Math.floor(precision) : 0;\n  const negative = value.units < 0n;\n  const absUnits = negative ? -value.units : value.units;\n  let rounded: bigint;\n  if (p >= value.scale) {\n    rounded = absUnits * (10n ** BigInt(p - value.scale));\n  } else {\n    const divisor = 10n ** BigInt(value.scale - p);\n    const quotient = absUnits / divisor;\n    const remainder = absUnits % divisor;\n    rounded = remainder * 2n >= divisor ? quotient + 1n : quotient;\n  }\n  let s = rounded.toString();\n  let formatted: string;\n  if (p === 0) formatted = s;\n  else {\n    if (s.length <= p) s = '0'.repeat(p - s.length + 1) + s;\n    formatted = s.slice(0, s.length - p) + '.' + s.slice(s.length - p);\n  }\n  if (negative && rounded !== 0n) return '-' + formatted;\n  return formatted;\n}\n"}}