@novha/calc-engines 1.5.0 → 1.6.1

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.
@@ -7,7 +7,8 @@ class CanadaIncomeTaxServiceImpl {
7
7
  this._rules = rules;
8
8
  }
9
9
  calculateNetIncome() {
10
- const grossTax = this.computeGrossTax(this._income, this._rules.taxBrackets);
10
+ const bracketBreakdown = this.computeTaxBracketBreakdown(this._income, this._rules.taxBrackets);
11
+ const grossTax = bracketBreakdown.reduce((total, b) => total + b.taxOnAmount, 0);
11
12
  const netTax = this.applyCredits(grossTax, this._rules.credits);
12
13
  const cpp = this.computeCPP(this._income, this._rules.contributions?.cpp);
13
14
  const ei = this.computeEI(this._income, this._rules.contributions?.ei);
@@ -19,8 +20,36 @@ class CanadaIncomeTaxServiceImpl {
19
20
  totalDeductions: netTax + cpp + ei,
20
21
  netIncome: this._income - netTax - cpp - ei,
21
22
  effectiveTaxRate: netTax / this._income,
23
+ taxBracketBreakdown: bracketBreakdown,
22
24
  };
23
25
  }
26
+ computeTaxBracketBreakdown(income, brackets) {
27
+ return brackets.map((b, index) => {
28
+ if (income <= b.from) {
29
+ return {
30
+ bracketIndex: index,
31
+ bracketName: `Bracket ${index + 1}`,
32
+ from: b.from,
33
+ to: b.to ?? null,
34
+ rate: b.rate,
35
+ amountInBracket: 0,
36
+ taxOnAmount: 0,
37
+ };
38
+ }
39
+ const upper = b.to ?? income;
40
+ const taxable = Math.min(income, upper) - b.from;
41
+ const taxOnAmount = taxable * b.rate;
42
+ return {
43
+ bracketIndex: index,
44
+ bracketName: `Bracket ${index + 1}`,
45
+ from: b.from,
46
+ to: b.to ?? null,
47
+ rate: b.rate,
48
+ amountInBracket: taxable,
49
+ taxOnAmount: taxOnAmount,
50
+ };
51
+ });
52
+ }
24
53
  computeGrossTax(income, brackets) {
25
54
  return brackets.reduce((total, b) => {
26
55
  if (income <= b.from)
@@ -48,4 +77,4 @@ class CanadaIncomeTaxServiceImpl {
48
77
  }
49
78
  }
50
79
  exports.CanadaIncomeTaxServiceImpl = CanadaIncomeTaxServiceImpl;
51
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FuYWRhSW5jb21lVGF4U2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5jb21lLXRheC9jYW5hZGEvQ2FuYWRhSW5jb21lVGF4U2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBV0EsTUFBYSwwQkFBMEI7SUFJbkMsWUFBWSxNQUFjLEVBQUUsS0FBcUI7UUFDN0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUVNLGtCQUFrQjtRQUVyQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM3RSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMxRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFdkUsT0FBTztZQUNILFdBQVcsRUFBRSxJQUFJLENBQUMsT0FBTztZQUN6QixTQUFTLEVBQUUsTUFBTTtZQUNqQixHQUFHO1lBQ0gsRUFBRTtZQUNGLGVBQWUsRUFBRSxNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUU7WUFDbEMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFO1lBQzNDLGdCQUFnQixFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTztTQUMxQyxDQUFDO0lBQ04sQ0FBQztJQUVPLGVBQWUsQ0FBQyxNQUFjLEVBQUUsUUFBc0I7UUFDMUQsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ2hDLElBQUksTUFBTSxJQUFJLENBQUMsQ0FBQyxJQUFJO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBRW5DLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksTUFBTSxDQUFDO1lBQzdCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFFakQsT0FBTyxLQUFLLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDcEMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ1YsQ0FBQztJQUVPLFlBQVksQ0FBQyxHQUFXLEVBQUUsVUFBcUMsRUFBRTtRQUNyRSxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FDOUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxFQUNuQyxDQUFDLENBQ0osQ0FBQztRQUVGLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxHQUFHLFlBQVksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFTyxVQUFVLENBQUMsTUFBYyxFQUFFLEdBQXFCO1FBQ3BELElBQUksQ0FBQyxHQUFHLElBQUksTUFBTSxJQUFJLEdBQUcsQ0FBQyxTQUFTO1lBQUUsT0FBTyxDQUFDLENBQUM7UUFFOUMsTUFBTSxhQUFhLEdBQUcsTUFBTSxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7UUFDN0MsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUNYLGFBQWEsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUN4QixHQUFHLENBQUMsZUFBZSxDQUN0QixDQUFDO0lBQ04sQ0FBQztJQUVPLFNBQVMsQ0FBQyxNQUFjLEVBQUUsRUFBbUI7UUFDakQsSUFBSSxDQUFDLEVBQUU7WUFBRSxPQUFPLENBQUMsQ0FBQztRQUVsQixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUM1QixNQUFNLEVBQ04sRUFBRSxDQUFDLG9CQUFvQixDQUMxQixDQUFDO1FBRUYsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUNYLGVBQWUsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUN6QixFQUFFLENBQUMsZUFBZSxDQUNyQixDQUFDO0lBQ04sQ0FBQztDQUNKO0FBdEVELGdFQXNFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRheEJyYWNrZXQgfSBmcm9tIFwiLi4vZG9tYWluL3R5cGVzXCI7XG5pbXBvcnQgeyBDYW5hZGFJbmNvbWVUYXhTZXJ2aWNlIH0gZnJvbSBcIi4vQ2FuYWRhSW5jb21lVGF4U2VydmljZVwiO1xuaW1wb3J0IHtcbiAgICBDUFBDb250cmlidXRpb24sXG4gICAgQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMsXG4gICAgRUlDb250cmlidXRpb24sXG4gICAgSW5jb21lVGF4UnVsZXMsXG4gICAgVGF4Q3JlZGl0XG59IGZyb20gXCIuL2RvbWFpbi90eXBlc1wiO1xuXG5cbmV4cG9ydCBjbGFzcyBDYW5hZGFJbmNvbWVUYXhTZXJ2aWNlSW1wbCBpbXBsZW1lbnRzIENhbmFkYUluY29tZVRheFNlcnZpY2Uge1xuICAgIHByaXZhdGUgX2luY29tZTogbnVtYmVyO1xuICAgIHByaXZhdGUgX3J1bGVzOiBJbmNvbWVUYXhSdWxlcztcblxuICAgIGNvbnN0cnVjdG9yKGluY29tZTogbnVtYmVyLCBydWxlczogSW5jb21lVGF4UnVsZXMpIHtcbiAgICAgICAgdGhpcy5faW5jb21lID0gaW5jb21lO1xuICAgICAgICB0aGlzLl9ydWxlcyA9IHJ1bGVzO1xuICAgIH1cblxuICAgIHB1YmxpYyBjYWxjdWxhdGVOZXRJbmNvbWUoKTogQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMge1xuXG4gICAgICAgIGNvbnN0IGdyb3NzVGF4ID0gdGhpcy5jb21wdXRlR3Jvc3NUYXgodGhpcy5faW5jb21lLCB0aGlzLl9ydWxlcy50YXhCcmFja2V0cyk7XG4gICAgICAgIGNvbnN0IG5ldFRheCA9IHRoaXMuYXBwbHlDcmVkaXRzKGdyb3NzVGF4LCB0aGlzLl9ydWxlcy5jcmVkaXRzKTtcbiAgICAgICAgY29uc3QgY3BwID0gdGhpcy5jb21wdXRlQ1BQKHRoaXMuX2luY29tZSwgdGhpcy5fcnVsZXMuY29udHJpYnV0aW9ucz8uY3BwKTtcbiAgICAgICAgY29uc3QgZWkgPSB0aGlzLmNvbXB1dGVFSSh0aGlzLl9pbmNvbWUsIHRoaXMuX3J1bGVzLmNvbnRyaWJ1dGlvbnM/LmVpKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZ3Jvc3NJbmNvbWU6IHRoaXMuX2luY29tZSxcbiAgICAgICAgICAgIGluY29tZVRheDogbmV0VGF4LFxuICAgICAgICAgICAgY3BwLFxuICAgICAgICAgICAgZWksXG4gICAgICAgICAgICB0b3RhbERlZHVjdGlvbnM6IG5ldFRheCArIGNwcCArIGVpLFxuICAgICAgICAgICAgbmV0SW5jb21lOiB0aGlzLl9pbmNvbWUgLSBuZXRUYXggLSBjcHAgLSBlaSxcbiAgICAgICAgICAgIGVmZmVjdGl2ZVRheFJhdGU6IG5ldFRheCAvIHRoaXMuX2luY29tZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNvbXB1dGVHcm9zc1RheChpbmNvbWU6IG51bWJlciwgYnJhY2tldHM6IFRheEJyYWNrZXRbXSk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBicmFja2V0cy5yZWR1Y2UoKHRvdGFsLCBiKSA9PiB7XG4gICAgICAgICAgICBpZiAoaW5jb21lIDw9IGIuZnJvbSkgcmV0dXJuIHRvdGFsO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgdXBwZXIgPSBiLnRvID8/IGluY29tZTtcbiAgICAgICAgICAgIGNvbnN0IHRheGFibGUgPSBNYXRoLm1pbihpbmNvbWUsIHVwcGVyKSAtIGIuZnJvbTtcbiAgICBcbiAgICAgICAgICAgIHJldHVybiB0b3RhbCArIHRheGFibGUgKiBiLnJhdGU7XG4gICAgICAgIH0sIDApO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXBwbHlDcmVkaXRzKHRheDogbnVtYmVyLCBjcmVkaXRzOiBSZWNvcmQ8c3RyaW5nLCBUYXhDcmVkaXQ+ID0ge30pOiBudW1iZXIge1xuICAgICAgICBjb25zdCB0b3RhbENyZWRpdHMgPSBPYmplY3QudmFsdWVzKGNyZWRpdHMpLnJlZHVjZShcbiAgICAgICAgICAgIChzdW0sIGMpID0+IHN1bSArIGMuYW1vdW50ICogYy5yYXRlLFxuICAgICAgICAgICAgMCxcbiAgICAgICAgKTtcbiAgICBcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIHRheCAtIHRvdGFsQ3JlZGl0cyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRlQ1BQKGluY29tZTogbnVtYmVyLCBjcHA/OiBDUFBDb250cmlidXRpb24pOiBudW1iZXIge1xuICAgICAgICBpZiAoIWNwcCB8fCBpbmNvbWUgPD0gY3BwLmV4ZW1wdGlvbikgcmV0dXJuIDA7XG4gICAgXG4gICAgICAgIGNvbnN0IGNvbnRyaWJ1dGFibGUgPSBpbmNvbWUgLSBjcHAuZXhlbXB0aW9uO1xuICAgICAgICByZXR1cm4gTWF0aC5taW4oXG4gICAgICAgICAgICBjb250cmlidXRhYmxlICogY3BwLnJhdGUsXG4gICAgICAgICAgICBjcHAubWF4Q29udHJpYnV0aW9uLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29tcHV0ZUVJKGluY29tZTogbnVtYmVyLCBlaT86IEVJQ29udHJpYnV0aW9uKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCFlaSkgcmV0dXJuIDA7XG4gICAgXG4gICAgICAgIGNvbnN0IGluc3VyYWJsZUluY29tZSA9IE1hdGgubWluKFxuICAgICAgICAgICAgaW5jb21lLFxuICAgICAgICAgICAgZWkubWF4SW5zdXJhYmxlRWFybmluZ3MsXG4gICAgICAgICk7XG4gICAgXG4gICAgICAgIHJldHVybiBNYXRoLm1pbihcbiAgICAgICAgICAgIGluc3VyYWJsZUluY29tZSAqIGVpLnJhdGUsXG4gICAgICAgICAgICBlaS5tYXhDb250cmlidXRpb24sXG4gICAgICAgICk7XG4gICAgfVxufSJdfQ==
80
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FuYWRhSW5jb21lVGF4U2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5jb21lLXRheC9jYW5hZGEvQ2FuYWRhSW5jb21lVGF4U2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBV0EsTUFBYSwwQkFBMEI7SUFJbkMsWUFBWSxNQUFjLEVBQUUsS0FBcUI7UUFDN0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUVNLGtCQUFrQjtRQUVyQixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDaEcsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakYsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoRSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDMUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRXZFLE9BQU87WUFDSCxXQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDekIsU0FBUyxFQUFFLE1BQU07WUFDakIsR0FB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OUMsTUFBTSxhQUFhLEdBQUcsTUFBTSxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7UUFDN0MsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUNYLGFBQWEsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUN4QixHQUFHLENBQUMsZUFBZSxDQUN0QixDQUFDO0lBQ04sQ0FBQztJQUVPLFNBQVMsQ0FBQyxNQUFjLEVBQUUsRUFBbUI7UUFDakQsSUFBSSxDQUFDLEVBQUU7WUFBRSxPQUFPLENBQUMsQ0FBQztRQUVsQixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUM1QixNQUFNLEVBQ04sRUFBRSxDQUFDLG9CQUFvQixDQUMxQixDQUFDO1FBRUYsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUNYLGVBQWUsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUN6QixFQUFFLENBQUMsZUFBZSxDQUNyQixDQUFDO0lBQ04sQ0FBQztDQUNKO0FBdEdELGdFQXNHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJyYWNrZXRBbGxvY2F0aW9uLCBUYXhCcmFja2V0IH0gZnJvbSBcIi4uL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgQ2FuYWRhSW5jb21lVGF4U2VydmljZSB9IGZyb20gXCIuL0NhbmFkYUluY29tZVRheFNlcnZpY2VcIjtcbmltcG9ydCB7XG4gICAgQ1BQQ29udHJpYnV0aW9uLFxuICAgIENvbXB1dGVkSW5jb21lVGF4VmFsdWVzLFxuICAgIEVJQ29udHJpYnV0aW9uLFxuICAgIEluY29tZVRheFJ1bGVzLFxuICAgIFRheENyZWRpdFxufSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuXG5leHBvcnQgY2xhc3MgQ2FuYWRhSW5jb21lVGF4U2VydmljZUltcGwgaW1wbGVtZW50cyBDYW5hZGFJbmNvbWVUYXhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF9pbmNvbWU6IG51bWJlcjtcbiAgICBwcml2YXRlIF9ydWxlczogSW5jb21lVGF4UnVsZXM7XG5cbiAgICBjb25zdHJ1Y3RvcihpbmNvbWU6IG51bWJlciwgcnVsZXM6IEluY29tZVRheFJ1bGVzKSB7XG4gICAgICAgIHRoaXMuX2luY29tZSA9IGluY29tZTtcbiAgICAgICAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgICB9XG5cbiAgICBwdWJsaWMgY2FsY3VsYXRlTmV0SW5jb21lKCk6IENvbXB1dGVkSW5jb21lVGF4VmFsdWVzIHtcblxuICAgICAgICBjb25zdCBicmFja2V0QnJlYWtkb3duID0gdGhpcy5jb21wdXRlVGF4QnJhY2tldEJyZWFrZG93bih0aGlzLl9pbmNvbWUsIHRoaXMuX3J1bGVzLnRheEJyYWNrZXRzKTtcbiAgICAgICAgY29uc3QgZ3Jvc3NUYXggPSBicmFja2V0QnJlYWtkb3duLnJlZHVjZSgodG90YWwsIGIpID0+IHRvdGFsICsgYi50YXhPbkFtb3VudCwgMCk7XG4gICAgICAgIGNvbnN0IG5ldFRheCA9IHRoaXMuYXBwbHlDcmVkaXRzKGdyb3NzVGF4LCB0aGlzLl9ydWxlcy5jcmVkaXRzKTtcbiAgICAgICAgY29uc3QgY3BwID0gdGhpcy5jb21wdXRlQ1BQKHRoaXMuX2luY29tZSwgdGhpcy5fcnVsZXMuY29udHJpYnV0aW9ucz8uY3BwKTtcbiAgICAgICAgY29uc3QgZWkgPSB0aGlzLmNvbXB1dGVFSSh0aGlzLl9pbmNvbWUsIHRoaXMuX3J1bGVzLmNvbnRyaWJ1dGlvbnM/LmVpKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZ3Jvc3NJbmNvbWU6IHRoaXMuX2luY29tZSxcbiAgICAgICAgICAgIGluY29tZVRheDogbmV0VGF4LFxuICAgICAgICAgICAgY3BwLFxuICAgICAgICAgICAgZWksXG4gICAgICAgICAgICB0b3RhbERlZHVjdGlvbnM6IG5ldFRheCArIGNwcCArIGVpLFxuICAgICAgICAgICAgbmV0SW5jb21lOiB0aGlzLl9pbmNvbWUgLSBuZXRUYXggLSBjcHAgLSBlaSxcbiAgICAgICAgICAgIGVmZmVjdGl2ZVRheFJhdGU6IG5ldFRheCAvIHRoaXMuX2luY29tZSxcbiAgICAgICAgICAgIHRheEJyYWNrZXRCcmVha2Rvd246IGJyYWNrZXRCcmVha2Rvd24sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRlVGF4QnJhY2tldEJyZWFrZG93bihpbmNvbWU6IG51bWJlciwgYnJhY2tldHM6IFRheEJyYWNrZXRbXSk6IEJyYWNrZXRBbGxvY2F0aW9uW10ge1xuICAgICAgICByZXR1cm4gYnJhY2tldHMubWFwKChiLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgaWYgKGluY29tZSA8PSBiLmZyb20pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBicmFja2V0SW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBicmFja2V0TmFtZTogYEJyYWNrZXQgJHtpbmRleCArIDF9YCxcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogYi5mcm9tLFxuICAgICAgICAgICAgICAgICAgICB0bzogYi50byA/PyBudWxsLFxuICAgICAgICAgICAgICAgICAgICByYXRlOiBiLnJhdGUsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudEluQnJhY2tldDogMCxcbiAgICAgICAgICAgICAgICAgICAgdGF4T25BbW91bnQ6IDAsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIGNvbnN0IHVwcGVyID0gYi50byA/PyBpbmNvbWU7XG4gICAgICAgICAgICBjb25zdCB0YXhhYmxlID0gTWF0aC5taW4oaW5jb21lLCB1cHBlcikgLSBiLmZyb207XG4gICAgICAgICAgICBjb25zdCB0YXhPbkFtb3VudCA9IHRheGFibGUgKiBiLnJhdGU7XG4gICAgXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGJyYWNrZXRJbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgYnJhY2tldE5hbWU6IGBCcmFja2V0ICR7aW5kZXggKyAxfWAsXG4gICAgICAgICAgICAgICAgZnJvbTogYi5mcm9tLFxuICAgICAgICAgICAgICAgIHRvOiBiLnRvID8/IG51bGwsXG4gICAgICAgICAgICAgICAgcmF0ZTogYi5yYXRlLFxuICAgICAgICAgICAgICAgIGFtb3VudEluQnJhY2tldDogdGF4YWJsZSxcbiAgICAgICAgICAgICAgICB0YXhPbkFtb3VudDogdGF4T25BbW91bnQsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNvbXB1dGVHcm9zc1RheChpbmNvbWU6IG51bWJlciwgYnJhY2tldHM6IFRheEJyYWNrZXRbXSk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBicmFja2V0cy5yZWR1Y2UoKHRvdGFsLCBiKSA9PiB7XG4gICAgICAgICAgICBpZiAoaW5jb21lIDw9IGIuZnJvbSkgcmV0dXJuIHRvdGFsO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgdXBwZXIgPSBiLnRvID8/IGluY29tZTtcbiAgICAgICAgICAgIGNvbnN0IHRheGFibGUgPSBNYXRoLm1pbihpbmNvbWUsIHVwcGVyKSAtIGIuZnJvbTtcbiAgICBcbiAgICAgICAgICAgIHJldHVybiB0b3RhbCArIHRheGFibGUgKiBiLnJhdGU7XG4gICAgICAgIH0sIDApO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXBwbHlDcmVkaXRzKHRheDogbnVtYmVyLCBjcmVkaXRzOiBSZWNvcmQ8c3RyaW5nLCBUYXhDcmVkaXQ+ID0ge30pOiBudW1iZXIge1xuICAgICAgICBjb25zdCB0b3RhbENyZWRpdHMgPSBPYmplY3QudmFsdWVzKGNyZWRpdHMpLnJlZHVjZShcbiAgICAgICAgICAgIChzdW0sIGMpID0+IHN1bSArIGMuYW1vdW50ICogYy5yYXRlLFxuICAgICAgICAgICAgMCxcbiAgICAgICAgKTtcbiAgICBcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIHRheCAtIHRvdGFsQ3JlZGl0cyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRlQ1BQKGluY29tZTogbnVtYmVyLCBjcHA/OiBDUFBDb250cmlidXRpb24pOiBudW1iZXIge1xuICAgICAgICBpZiAoIWNwcCB8fCBpbmNvbWUgPD0gY3BwLmV4ZW1wdGlvbikgcmV0dXJuIDA7XG4gICAgXG4gICAgICAgIGNvbnN0IGNvbnRyaWJ1dGFibGUgPSBpbmNvbWUgLSBjcHAuZXhlbXB0aW9uO1xuICAgICAgICByZXR1cm4gTWF0aC5taW4oXG4gICAgICAgICAgICBjb250cmlidXRhYmxlICogY3BwLnJhdGUsXG4gICAgICAgICAgICBjcHAubWF4Q29udHJpYnV0aW9uLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29tcHV0ZUVJKGluY29tZTogbnVtYmVyLCBlaT86IEVJQ29udHJpYnV0aW9uKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCFlaSkgcmV0dXJuIDA7XG4gICAgXG4gICAgICAgIGNvbnN0IGluc3VyYWJsZUluY29tZSA9IE1hdGgubWluKFxuICAgICAgICAgICAgaW5jb21lLFxuICAgICAgICAgICAgZWkubWF4SW5zdXJhYmxlRWFybmluZ3MsXG4gICAgICAgICk7XG4gICAgXG4gICAgICAgIHJldHVybiBNYXRoLm1pbihcbiAgICAgICAgICAgIGluc3VyYWJsZUluY29tZSAqIGVpLnJhdGUsXG4gICAgICAgICAgICBlaS5tYXhDb250cmlidXRpb24sXG4gICAgICAgICk7XG4gICAgfVxufSJdfQ==
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW5jb21lLXRheC9jYW5hZGEvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUYXhCcmFja2V0IH0gZnJvbSBcIi4uLy4uL2RvbWFpbi90eXBlc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEluY29tZVRheFJ1bGVzIHtcbiAgICB0YXhCcmFja2V0czogVGF4QnJhY2tldFtdO1xuICAgIGNyZWRpdHM/OiBSZWNvcmQ8c3RyaW5nLCBUYXhDcmVkaXQ+O1xuICAgIGNvbnRyaWJ1dGlvbnM/OiBDb250cmlidXRpb25zO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRheENyZWRpdCB7XG4gICAgYW1vdW50OiBudW1iZXI7XG4gICAgdHlwZTogJ25vblJlZnVuZGFibGUnIHwgJ3JlZnVuZGFibGUnO1xuICAgIHJhdGU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb250cmlidXRpb25zIHtcbiAgICBjcHA/OiBDUFBDb250cmlidXRpb247XG4gICAgZWk/OiBFSUNvbnRyaWJ1dGlvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDUFBDb250cmlidXRpb24ge1xuICAgIHJhdGU6IG51bWJlcjtcbiAgICBtYXhDb250cmlidXRpb246IG51bWJlcjtcbiAgICBleGVtcHRpb246IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFSUNvbnRyaWJ1dGlvbiB7XG4gICAgcmF0ZTogbnVtYmVyO1xuICAgIG1heEluc3VyYWJsZUVhcm5pbmdzOiBudW1iZXI7XG4gICAgbWF4Q29udHJpYnV0aW9uOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMge1xuICAgIGdyb3NzSW5jb21lOiBudW1iZXI7XG4gICAgaW5jb21lVGF4OiBudW1iZXI7XG4gICAgY3BwOiBudW1iZXI7XG4gICAgZWk6IG51bWJlcjtcbiAgICB0b3RhbERlZHVjdGlvbnM6IG51bWJlcjtcbiAgICBuZXRJbmNvbWU6IG51bWJlcjtcbiAgICBlZmZlY3RpdmVUYXhSYXRlOiBudW1iZXI7XG59XG5cbiJdfQ==
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW5jb21lLXRheC9jYW5hZGEvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmFja2V0QWxsb2NhdGlvbiwgVGF4QnJhY2tldCB9IGZyb20gXCIuLi8uLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJbmNvbWVUYXhSdWxlcyB7XG4gICAgdGF4QnJhY2tldHM6IFRheEJyYWNrZXRbXTtcbiAgICBjcmVkaXRzPzogUmVjb3JkPHN0cmluZywgVGF4Q3JlZGl0PjtcbiAgICBjb250cmlidXRpb25zPzogQ29udHJpYnV0aW9ucztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXhDcmVkaXQge1xuICAgIGFtb3VudDogbnVtYmVyO1xuICAgIHR5cGU6ICdub25SZWZ1bmRhYmxlJyB8ICdyZWZ1bmRhYmxlJztcbiAgICByYXRlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udHJpYnV0aW9ucyB7XG4gICAgY3BwPzogQ1BQQ29udHJpYnV0aW9uO1xuICAgIGVpPzogRUlDb250cmlidXRpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ1BQQ29udHJpYnV0aW9uIHtcbiAgICByYXRlOiBudW1iZXI7XG4gICAgbWF4Q29udHJpYnV0aW9uOiBudW1iZXI7XG4gICAgZXhlbXB0aW9uOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRUlDb250cmlidXRpb24ge1xuICAgIHJhdGU6IG51bWJlcjtcbiAgICBtYXhJbnN1cmFibGVFYXJuaW5nczogbnVtYmVyO1xuICAgIG1heENvbnRyaWJ1dGlvbjogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVkSW5jb21lVGF4VmFsdWVzIHtcbiAgICBncm9zc0luY29tZTogbnVtYmVyO1xuICAgIGluY29tZVRheDogbnVtYmVyO1xuICAgIGNwcDogbnVtYmVyO1xuICAgIGVpOiBudW1iZXI7XG4gICAgdG90YWxEZWR1Y3Rpb25zOiBudW1iZXI7XG4gICAgbmV0SW5jb21lOiBudW1iZXI7XG4gICAgZWZmZWN0aXZlVGF4UmF0ZTogbnVtYmVyO1xuICAgIHRheEJyYWNrZXRCcmVha2Rvd246IEJyYWNrZXRBbGxvY2F0aW9uW107XG59XG5cbiJdfQ==
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5jb21lLXRheC9kb21haW4vdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJ1bGVNZXRhIH0gZnJvbSBcIi4uLy4uL3NoYXJlZC9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBSdWxlSW5wdXQge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0eXBlOiAnbnVtYmVyJyB8ICdzZWxlY3QnIHwgJ3RleHQnO1xuICAgIHJlcXVpcmVkOiBib29sZWFuO1xuICAgIHVuaXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZU91dHB1dCB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHR5cGU6ICdudW1iZXInIHwgJ3N0cmluZyc7XG4gICAgdW5pdD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXhCcmFja2V0IHtcbiAgICBmcm9tOiBudW1iZXI7XG4gICAgdG86IG51bWJlciB8IG51bGw7XG4gICAgcmF0ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluY29tZVRheENhbGN1bGF0b3JTY2hlbWE8VD4ge1xuICAgIG1ldGE6IFJ1bGVNZXRhO1xuICAgIGlucHV0czogUnVsZUlucHV0W107XG4gICAgb3V0cHV0czogUnVsZU91dHB1dFtdO1xuICAgIHJ1bGVzOiBUO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFnZUJhc2VkUmViYXRlIHtcbiAgYWdlTWluOiBudW1iZXI7XG4gIGFtb3VudDogbnVtYmVyO1xufSJdfQ==
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5jb21lLXRheC9kb21haW4vdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJ1bGVNZXRhIH0gZnJvbSBcIi4uLy4uL3NoYXJlZC9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBSdWxlSW5wdXQge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0eXBlOiAnbnVtYmVyJyB8ICdzZWxlY3QnIHwgJ3RleHQnO1xuICAgIHJlcXVpcmVkOiBib29sZWFuO1xuICAgIHVuaXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZU91dHB1dCB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHR5cGU6ICdudW1iZXInIHwgJ3N0cmluZyc7XG4gICAgdW5pdD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXhCcmFja2V0IHtcbiAgICBmcm9tOiBudW1iZXI7XG4gICAgdG86IG51bWJlciB8IG51bGw7XG4gICAgcmF0ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluY29tZVRheENhbGN1bGF0b3JTY2hlbWE8VD4ge1xuICAgIG1ldGE6IFJ1bGVNZXRhO1xuICAgIGlucHV0czogUnVsZUlucHV0W107XG4gICAgb3V0cHV0czogUnVsZU91dHB1dFtdO1xuICAgIHJ1bGVzOiBUO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFnZUJhc2VkUmViYXRlIHtcbiAgICBhZ2VNaW46IG51bWJlcjtcbiAgICBhbW91bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCcmFja2V0QWxsb2NhdGlvbiB7XG4gICAgYnJhY2tldEluZGV4OiBudW1iZXI7XG4gICAgYnJhY2tldE5hbWU6IHN0cmluZztcbiAgICBmcm9tOiBudW1iZXI7XG4gICAgdG86IG51bWJlciB8IG51bGw7XG4gICAgcmF0ZTogbnVtYmVyO1xuICAgIGFtb3VudEluQnJhY2tldDogbnVtYmVyO1xuICAgIHRheE9uQW1vdW50OiBudW1iZXI7XG59Il19
@@ -9,7 +9,7 @@ class FranceIncomeTaxServiceImpl {
9
9
  }
10
10
  calculateNetIncome() {
11
11
  const taxablePerPart = this._familyParts * this._income / this._familyParts;
12
- const { tax: taxPerPart, marginalRate } = this.calculateProgressiveTax(taxablePerPart);
12
+ const { tax: taxPerPart, marginalRate, bracketBreakdown } = this.calculateProgressiveTax(taxablePerPart);
13
13
  const incomeTax = taxPerPart * this._familyParts;
14
14
  const socialContributions = this._income * this._rules.socialContributions.employee.rate;
15
15
  const totalDeductions = incomeTax + socialContributions;
@@ -22,27 +22,59 @@ class FranceIncomeTaxServiceImpl {
22
22
  netIncome: this.round(netIncome),
23
23
  averageTaxRate: this.round(incomeTax / this._income),
24
24
  marginalTaxRate: marginalRate,
25
+ taxBracketBreakdown: bracketBreakdown,
25
26
  };
26
27
  }
27
28
  calculateProgressiveTax(income) {
28
29
  let tax = 0;
29
30
  let marginalRate = 0;
30
- for (const bracket of this._rules.taxBrackets) {
31
+ const bracketBreakdown = [];
32
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
33
+ const bracket = this._rules.taxBrackets[index];
31
34
  const upperBound = bracket.to ?? income;
32
35
  if (income <= bracket.from) {
36
+ bracketBreakdown.push({
37
+ bracketIndex: index,
38
+ bracketName: `Bracket ${index + 1}`,
39
+ from: bracket.from,
40
+ to: bracket.to ?? null,
41
+ rate: bracket.rate,
42
+ amountInBracket: 0,
43
+ taxOnAmount: 0,
44
+ });
33
45
  break;
34
46
  }
35
47
  const taxableAmount = Math.min(upperBound, income) - bracket.from;
36
48
  if (taxableAmount > 0) {
37
49
  tax += taxableAmount * bracket.rate;
38
50
  marginalRate = bracket.rate;
51
+ bracketBreakdown.push({
52
+ bracketIndex: index,
53
+ bracketName: `Bracket ${index + 1}`,
54
+ from: bracket.from,
55
+ to: bracket.to ?? null,
56
+ rate: bracket.rate,
57
+ amountInBracket: taxableAmount,
58
+ taxOnAmount: taxableAmount * bracket.rate,
59
+ });
60
+ }
61
+ else {
62
+ bracketBreakdown.push({
63
+ bracketIndex: index,
64
+ bracketName: `Bracket ${index + 1}`,
65
+ from: bracket.from,
66
+ to: bracket.to ?? null,
67
+ rate: bracket.rate,
68
+ amountInBracket: 0,
69
+ taxOnAmount: 0,
70
+ });
39
71
  }
40
72
  }
41
- return { tax, marginalRate };
73
+ return { tax, marginalRate, bracketBreakdown };
42
74
  }
43
75
  round(value) {
44
76
  return Math.round(value * 100) / 100;
45
77
  }
46
78
  }
47
79
  exports.FranceIncomeTaxServiceImpl = FranceIncomeTaxServiceImpl;
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRnJhbmNlSW5jb21lVGF4U2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5jb21lLXRheC9mcmFuY2UvRnJhbmNlSW5jb21lVGF4U2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsTUFBYSwwQkFBMEI7SUFLbkMsWUFBWSxNQUFjLEVBQUUsS0FBcUIsRUFBRSxXQUFtQjtRQUNsRSxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNwQyxDQUFDO0lBRU0sa0JBQWtCO1FBRTNCLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzVFLE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN2RixNQUFNLFNBQVMsR0FBRyxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUNqRCxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQ3pGLE1BQU0sZUFBZSxHQUFHLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQztRQUN4RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQztRQUVqRCxPQUFPO1lBQ04sV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3pCLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztZQUNoQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDO1lBQ3BELGVBQWUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztZQUM1QyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7WUFDaEMsY0FBYyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDcEQsZUFBZSxFQUFFLFlBQVk7U0FDN0IsQ0FBQztJQUNILENBQUM7SUFHVSx1QkFBdUIsQ0FBQyxNQUFjO1FBSWhELElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztRQUVyQixLQUFLLE1BQU0sT0FBTyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDL0MsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEVBQUUsSUFBSSxNQUFNLENBQUM7WUFFeEMsSUFBSSxNQUFNLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUM1QixNQUFNO1lBQ1AsQ0FBQztZQUVELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFFbEUsSUFBSSxhQUFhLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLEdBQUcsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztnQkFDcEMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDN0IsQ0FBQztRQUNGLENBQUM7UUFFRCxPQUFPLEVBQUUsR0FBRyxFQUFFLFlBQVksRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFVSxLQUFLLENBQUMsS0FBYTtRQUM3QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUN0QyxDQUFDO0NBQ0Q7QUE1REQsZ0VBNERDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMsIEluY29tZVRheFJ1bGVzIH0gZnJvbSBcIi4vZG9tYWluL3R5cGVzXCI7XG5pbXBvcnQgeyBGcmFuY2VJbmNvbWVUYXhTZXJ2aWNlIH0gZnJvbSBcIi4vRnJhbmNlSW5jb21lVGF4U2VydmljZVwiO1xuXG5leHBvcnQgY2xhc3MgRnJhbmNlSW5jb21lVGF4U2VydmljZUltcGwgaW1wbGVtZW50cyBGcmFuY2VJbmNvbWVUYXhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF9pbmNvbWU6IG51bWJlcjtcbiAgICBwcml2YXRlIF9ydWxlczogSW5jb21lVGF4UnVsZXM7XG4gICAgcHJpdmF0ZSBfZmFtaWx5UGFydHM6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKGluY29tZTogbnVtYmVyLCBydWxlczogSW5jb21lVGF4UnVsZXMsIGZhbWlseVBhcnRzOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5faW5jb21lID0gaW5jb21lO1xuICAgICAgICB0aGlzLl9ydWxlcyA9IHJ1bGVzO1xuICAgICAgICB0aGlzLl9mYW1pbHlQYXJ0cyA9IGZhbWlseVBhcnRzO1xuICAgIH1cblxuICAgIHB1YmxpYyBjYWxjdWxhdGVOZXRJbmNvbWUoKTogQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMge1xuXG5cdFx0Y29uc3QgdGF4YWJsZVBlclBhcnQgPSB0aGlzLl9mYW1pbHlQYXJ0cyAqIHRoaXMuX2luY29tZSAvIHRoaXMuX2ZhbWlseVBhcnRzO1xuXHRcdGNvbnN0IHsgdGF4OiB0YXhQZXJQYXJ0LCBtYXJnaW5hbFJhdGUgfSA9IHRoaXMuY2FsY3VsYXRlUHJvZ3Jlc3NpdmVUYXgodGF4YWJsZVBlclBhcnQpO1xuXHRcdGNvbnN0IGluY29tZVRheCA9IHRheFBlclBhcnQgKiB0aGlzLl9mYW1pbHlQYXJ0cztcblx0XHRjb25zdCBzb2NpYWxDb250cmlidXRpb25zID0gdGhpcy5faW5jb21lICogdGhpcy5fcnVsZXMuc29jaWFsQ29udHJpYnV0aW9ucy5lbXBsb3llZS5yYXRlO1xuXHRcdGNvbnN0IHRvdGFsRGVkdWN0aW9ucyA9IGluY29tZVRheCArIHNvY2lhbENvbnRyaWJ1dGlvbnM7XG5cdFx0Y29uc3QgbmV0SW5jb21lID0gdGhpcy5faW5jb21lIC0gdG90YWxEZWR1Y3Rpb25zO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdGdyb3NzSW5jb21lOiB0aGlzLl9pbmNvbWUsXG5cdFx0XHRpbmNvbWVUYXg6IHRoaXMucm91bmQoaW5jb21lVGF4KSxcblx0XHRcdHNvY2lhbENvbnRyaWJ1dGlvbnM6IHRoaXMucm91bmQoc29jaWFsQ29udHJpYnV0aW9ucyksXG5cdFx0XHR0b3RhbERlZHVjdGlvbnM6IHRoaXMucm91bmQodG90YWxEZWR1Y3Rpb25zKSxcblx0XHRcdG5ldEluY29tZTogdGhpcy5yb3VuZChuZXRJbmNvbWUpLFxuXHRcdFx0YXZlcmFnZVRheFJhdGU6IHRoaXMucm91bmQoaW5jb21lVGF4IC8gdGhpcy5faW5jb21lKSxcblx0XHRcdG1hcmdpbmFsVGF4UmF0ZTogbWFyZ2luYWxSYXRlLFxuXHRcdH07XG5cdH1cblxuXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVQcm9ncmVzc2l2ZVRheChpbmNvbWU6IG51bWJlcik6IHtcbiAgICAgICAgdGF4OiBudW1iZXI7XG4gICAgICAgIG1hcmdpbmFsUmF0ZTogbnVtYmVyXG4gICAgfSB7XG5cdFx0bGV0IHRheCA9IDA7XG5cdFx0bGV0IG1hcmdpbmFsUmF0ZSA9IDA7XG5cblx0XHRmb3IgKGNvbnN0IGJyYWNrZXQgb2YgdGhpcy5fcnVsZXMudGF4QnJhY2tldHMpIHtcblx0XHRcdGNvbnN0IHVwcGVyQm91bmQgPSBicmFja2V0LnRvID8/IGluY29tZTtcblxuXHRcdFx0aWYgKGluY29tZSA8PSBicmFja2V0LmZyb20pIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IHRheGFibGVBbW91bnQgPSBNYXRoLm1pbih1cHBlckJvdW5kLCBpbmNvbWUpIC0gYnJhY2tldC5mcm9tO1xuXG5cdFx0XHRpZiAodGF4YWJsZUFtb3VudCA+IDApIHtcblx0XHRcdFx0dGF4ICs9IHRheGFibGVBbW91bnQgKiBicmFja2V0LnJhdGU7XG5cdFx0XHRcdG1hcmdpbmFsUmF0ZSA9IGJyYWNrZXQucmF0ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4geyB0YXgsIG1hcmdpbmFsUmF0ZSB9O1xuXHR9XG5cbiAgICBwcml2YXRlIHJvdW5kKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xuXHRcdHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogMTAwKSAvIDEwMDtcblx0fVxufVxuIl19
80
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRnJhbmNlSW5jb21lVGF4U2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5jb21lLXRheC9mcmFuY2UvRnJhbmNlSW5jb21lVGF4U2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSwwQkFBMEI7SUFLbkMsWUFBWSxNQUFjLEVBQUUsS0FBcUIsRUFBRSxXQUFtQjtRQUNsRSxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNwQyxDQUFDO0lBRU0sa0JBQWtCO1FBRTNCLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzVFLE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN6RyxNQUFNLFNBQVMsR0FBRyxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUNqRCxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQ3pGLE1BQU0sZUFBZSxHQUFHLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQztRQUN4RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQztRQUVqRCxPQUFPO1lBQ04sV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3pCLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztZQUNoQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFD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QyxLQUFLLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQ3RDLENBQUM7Q0FDRDtBQTVGRCxnRUE0RkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmFja2V0QWxsb2NhdGlvbiB9IGZyb20gXCIuLi9kb21haW4vdHlwZXNcIjtcbmltcG9ydCB7IENvbXB1dGVkSW5jb21lVGF4VmFsdWVzLCBJbmNvbWVUYXhSdWxlcyB9IGZyb20gXCIuL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgRnJhbmNlSW5jb21lVGF4U2VydmljZSB9IGZyb20gXCIuL0ZyYW5jZUluY29tZVRheFNlcnZpY2VcIjtcblxuZXhwb3J0IGNsYXNzIEZyYW5jZUluY29tZVRheFNlcnZpY2VJbXBsIGltcGxlbWVudHMgRnJhbmNlSW5jb21lVGF4U2VydmljZSB7XG4gICAgcHJpdmF0ZSBfaW5jb21lOiBudW1iZXI7XG4gICAgcHJpdmF0ZSBfcnVsZXM6IEluY29tZVRheFJ1bGVzO1xuICAgIHByaXZhdGUgX2ZhbWlseVBhcnRzOiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3RvcihpbmNvbWU6IG51bWJlciwgcnVsZXM6IEluY29tZVRheFJ1bGVzLCBmYW1pbHlQYXJ0czogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX2luY29tZSA9IGluY29tZTtcbiAgICAgICAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgICAgICAgdGhpcy5fZmFtaWx5UGFydHMgPSBmYW1pbHlQYXJ0cztcbiAgICB9XG5cbiAgICBwdWJsaWMgY2FsY3VsYXRlTmV0SW5jb21lKCk6IENvbXB1dGVkSW5jb21lVGF4VmFsdWVzIHtcblxuXHRcdGNvbnN0IHRheGFibGVQZXJQYXJ0ID0gdGhpcy5fZmFtaWx5UGFydHMgKiB0aGlzLl9pbmNvbWUgLyB0aGlzLl9mYW1pbHlQYXJ0cztcblx0XHRjb25zdCB7IHRheDogdGF4UGVyUGFydCwgbWFyZ2luYWxSYXRlLCBicmFja2V0QnJlYWtkb3duIH0gPSB0aGlzLmNhbGN1bGF0ZVByb2dyZXNzaXZlVGF4KHRheGFibGVQZXJQYXJ0KTtcblx0XHRjb25zdCBpbmNvbWVUYXggPSB0YXhQZXJQYXJ0ICogdGhpcy5fZmFtaWx5UGFydHM7XG5cdFx0Y29uc3Qgc29jaWFsQ29udHJpYnV0aW9ucyA9IHRoaXMuX2luY29tZSAqIHRoaXMuX3J1bGVzLnNvY2lhbENvbnRyaWJ1dGlvbnMuZW1wbG95ZWUucmF0ZTtcblx0XHRjb25zdCB0b3RhbERlZHVjdGlvbnMgPSBpbmNvbWVUYXggKyBzb2NpYWxDb250cmlidXRpb25zO1xuXHRcdGNvbnN0IG5ldEluY29tZSA9IHRoaXMuX2luY29tZSAtIHRvdGFsRGVkdWN0aW9ucztcblxuXHRcdHJldHVybiB7XG5cdFx0XHRncm9zc0luY29tZTogdGhpcy5faW5jb21lLFxuXHRcdFx0aW5jb21lVGF4OiB0aGlzLnJvdW5kKGluY29tZVRheCksXG5cdFx0XHRzb2NpYWxDb250cmlidXRpb25zOiB0aGlzLnJvdW5kKHNvY2lhbENvbnRyaWJ1dGlvbnMpLFxuXHRcdFx0dG90YWxEZWR1Y3Rpb25zOiB0aGlzLnJvdW5kKHRvdGFsRGVkdWN0aW9ucyksXG5cdFx0XHRuZXRJbmNvbWU6IHRoaXMucm91bmQobmV0SW5jb21lKSxcblx0XHRcdGF2ZXJhZ2VUYXhSYXRlOiB0aGlzLnJvdW5kKGluY29tZVRheCAvIHRoaXMuX2luY29tZSksXG5cdFx0XHRtYXJnaW5hbFRheFJhdGU6IG1hcmdpbmFsUmF0ZSxcblx0XHRcdHRheEJyYWNrZXRCcmVha2Rvd246IGJyYWNrZXRCcmVha2Rvd24sXG5cdFx0fTtcblx0fVxuXG5cbiAgICBwcml2YXRlIGNhbGN1bGF0ZVByb2dyZXNzaXZlVGF4KGluY29tZTogbnVtYmVyKToge1xuICAgICAgICB0YXg6IG51bWJlcjtcbiAgICAgICAgbWFyZ2luYWxSYXRlOiBudW1iZXI7XG4gICAgICAgIGJyYWNrZXRCcmVha2Rvd246IEJyYWNrZXRBbGxvY2F0aW9uW107XG4gICAgfSB7XG5cdFx0bGV0IHRheCA9IDA7XG5cdFx0bGV0IG1hcmdpbmFsUmF0ZSA9IDA7XG5cdFx0Y29uc3QgYnJhY2tldEJyZWFrZG93bjogQnJhY2tldEFsbG9jYXRpb25bXSA9IFtdO1xuXG5cdFx0Zm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMuX3J1bGVzLnRheEJyYWNrZXRzLmxlbmd0aDsgaW5kZXgrKykge1xuXHRcdFx0Y29uc3QgYnJhY2tldCA9IHRoaXMuX3J1bGVzLnRheEJyYWNrZXRzW2luZGV4XTtcblx0XHRcdGNvbnN0IHVwcGVyQm91bmQgPSBicmFja2V0LnRvID8/IGluY29tZTtcblxuXHRcdFx0aWYgKGluY29tZSA8PSBicmFja2V0LmZyb20pIHtcblx0XHRcdFx0YnJhY2tldEJyZWFrZG93bi5wdXNoKHtcblx0XHRcdFx0XHRicmFja2V0SW5kZXg6IGluZGV4LFxuXHRcdFx0XHRcdGJyYWNrZXROYW1lOiBgQnJhY2tldCAke2luZGV4ICsgMX1gLFxuXHRcdFx0XHRcdGZyb206IGJyYWNrZXQuZnJvbSxcblx0XHRcdFx0XHR0bzogYnJhY2tldC50byA/PyBudWxsLFxuXHRcdFx0XHRcdHJhdGU6IGJyYWNrZXQucmF0ZSxcblx0XHRcdFx0XHRhbW91bnRJbkJyYWNrZXQ6IDAsXG5cdFx0XHRcdFx0dGF4T25BbW91bnQ6IDAsXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgdGF4YWJsZUFtb3VudCA9IE1hdGgubWluKHVwcGVyQm91bmQsIGluY29tZSkgLSBicmFja2V0LmZyb207XG5cblx0XHRcdGlmICh0YXhhYmxlQW1vdW50ID4gMCkge1xuXHRcdFx0XHR0YXggKz0gdGF4YWJsZUFtb3VudCAqIGJyYWNrZXQucmF0ZTtcblx0XHRcdFx0bWFyZ2luYWxSYXRlID0gYnJhY2tldC5yYXRlO1xuXHRcdFx0XHRicmFja2V0QnJlYWtkb3duLnB1c2goe1xuXHRcdFx0XHRcdGJyYWNrZXRJbmRleDogaW5kZXgsXG5cdFx0XHRcdFx0YnJhY2tldE5hbWU6IGBCcmFja2V0ICR7aW5kZXggKyAxfWAsXG5cdFx0XHRcdFx0ZnJvbTogYnJhY2tldC5mcm9tLFxuXHRcdFx0XHRcdHRvOiBicmFja2V0LnRvID8/IG51bGwsXG5cdFx0XHRcdFx0cmF0ZTogYnJhY2tldC5yYXRlLFxuXHRcdFx0XHRcdGFtb3VudEluQnJhY2tldDogdGF4YWJsZUFtb3VudCxcblx0XHRcdFx0XHR0YXhPbkFtb3VudDogdGF4YWJsZUFtb3VudCAqIGJyYWNrZXQucmF0ZSxcblx0XHRcdFx0fSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRicmFja2V0QnJlYWtkb3duLnB1c2goe1xuXHRcdFx0XHRcdGJyYWNrZXRJbmRleDogaW5kZXgsXG5cdFx0XHRcdFx0YnJhY2tldE5hbWU6IGBCcmFja2V0ICR7aW5kZXggKyAxfWAsXG5cdFx0XHRcdFx0ZnJvbTogYnJhY2tldC5mcm9tLFxuXHRcdFx0XHRcdHRvOiBicmFja2V0LnRvID8/IG51bGwsXG5cdFx0XHRcdFx0cmF0ZTogYnJhY2tldC5yYXRlLFxuXHRcdFx0XHRcdGFtb3VudEluQnJhY2tldDogMCxcblx0XHRcdFx0XHR0YXhPbkFtb3VudDogMCxcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHsgdGF4LCBtYXJnaW5hbFJhdGUsIGJyYWNrZXRCcmVha2Rvd24gfTtcblx0fVxuXG4gICAgcHJpdmF0ZSByb3VuZCh2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCh2YWx1ZSAqIDEwMCkgLyAxMDA7XG5cdH1cbn1cbiJdfQ==
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW5jb21lLXRheC9mcmFuY2UvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSdWxlTWV0YSB9IGZyb20gXCIuLi8uLi8uLi9zaGFyZWQvZG9tYWluL3R5cGVzXCI7XG5pbXBvcnQgeyBSdWxlSW5wdXQsIFJ1bGVPdXRwdXQsIFRheEJyYWNrZXQgfSBmcm9tIFwiLi4vLi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5jb21lVGF4UnVsZXMge1xuICAgIHRheEJyYWNrZXRzOiBUYXhCcmFja2V0W107XG4gICAgcXVvdGllbnRGYW1pbGlhbDogUXVvdGllbnRGYW1pbGlhbDtcbiAgICBzb2NpYWxDb250cmlidXRpb25zOiBDb250cmlidXRpb25zO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnRyaWJ1dGlvbnMge1xuICAgIGVtcGxveWVlOiB7IHJhdGU6IG51bWJlcjsgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdW90aWVudEZhbWlsaWFsIHtcbiAgICBlbmFibGVkOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluY29tZVRheENhbGN1bGF0b3JTY2hlbWEge1xuICAgIG1ldGE6IFJ1bGVNZXRhO1xuICAgIGlucHV0czogUnVsZUlucHV0W107XG4gICAgb3V0cHV0czogUnVsZU91dHB1dFtdO1xuICAgIHJ1bGVzOiBJbmNvbWVUYXhSdWxlcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wdXRlZEluY29tZVRheFZhbHVlcyB7XG4gICAgZ3Jvc3NJbmNvbWU6IG51bWJlcjtcblx0aW5jb21lVGF4OiBudW1iZXI7XG5cdHNvY2lhbENvbnRyaWJ1dGlvbnM6IG51bWJlcjtcblx0dG90YWxEZWR1Y3Rpb25zOiBudW1iZXI7XG5cdG5ldEluY29tZTogbnVtYmVyO1xuXHRhdmVyYWdlVGF4UmF0ZTogbnVtYmVyO1xuXHRtYXJnaW5hbFRheFJhdGU6IG51bWJlcjtcbn0iXX0=
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW5jb21lLXRheC9mcmFuY2UvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSdWxlTWV0YSB9IGZyb20gXCIuLi8uLi8uLi9zaGFyZWQvZG9tYWluL3R5cGVzXCI7XG5pbXBvcnQgeyBCcmFja2V0QWxsb2NhdGlvbiwgUnVsZUlucHV0LCBSdWxlT3V0cHV0LCBUYXhCcmFja2V0IH0gZnJvbSBcIi4uLy4uL2RvbWFpbi90eXBlc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEluY29tZVRheFJ1bGVzIHtcbiAgICB0YXhCcmFja2V0czogVGF4QnJhY2tldFtdO1xuICAgIHF1b3RpZW50RmFtaWxpYWw6IFF1b3RpZW50RmFtaWxpYWw7XG4gICAgc29jaWFsQ29udHJpYnV0aW9uczogQ29udHJpYnV0aW9ucztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb250cmlidXRpb25zIHtcbiAgICBlbXBsb3llZTogeyByYXRlOiBudW1iZXI7IH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGllbnRGYW1pbGlhbCB7XG4gICAgZW5hYmxlZDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmNvbWVUYXhDYWxjdWxhdG9yU2NoZW1hIHtcbiAgICBtZXRhOiBSdWxlTWV0YTtcbiAgICBpbnB1dHM6IFJ1bGVJbnB1dFtdO1xuICAgIG91dHB1dHM6IFJ1bGVPdXRwdXRbXTtcbiAgICBydWxlczogSW5jb21lVGF4UnVsZXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMge1xuICAgIGdyb3NzSW5jb21lOiBudW1iZXI7XG5cdGluY29tZVRheDogbnVtYmVyO1xuXHRzb2NpYWxDb250cmlidXRpb25zOiBudW1iZXI7XG5cdHRvdGFsRGVkdWN0aW9uczogbnVtYmVyO1xuXHRuZXRJbmNvbWU6IG51bWJlcjtcblx0YXZlcmFnZVRheFJhdGU6IG51bWJlcjtcblx0bWFyZ2luYWxUYXhSYXRlOiBudW1iZXI7XG5cdHRheEJyYWNrZXRCcmVha2Rvd246IEJyYWNrZXRBbGxvY2F0aW9uW107XG59Il19
@@ -20,9 +20,10 @@ class SouthAfricaIncomeTaxServiceImpl {
20
20
  totalDeductions: 0,
21
21
  netIncome: grossIncome,
22
22
  effectiveTaxRate: 0,
23
+ taxBracketBreakdown: [],
23
24
  };
24
25
  }
25
- const grossTax = this.calculateBracketTax(this._income);
26
+ const { grossTax, bracketBreakdown } = this.calculateBracketTaxWithBreakdown(this._income);
26
27
  const rebate = this.getRebate(this._age);
27
28
  const medicalAidCredit = this.calculateMedicalAidCredit(this._medicalAidMembers);
28
29
  const incomeTax = Math.max(0, grossTax - rebate - medicalAidCredit);
@@ -37,8 +38,55 @@ class SouthAfricaIncomeTaxServiceImpl {
37
38
  totalDeductions: this.round(totalDeductions),
38
39
  netIncome: this.round(netIncome),
39
40
  effectiveTaxRate: this.round(effectiveTaxRate, 4),
41
+ taxBracketBreakdown: bracketBreakdown,
40
42
  };
41
43
  }
44
+ calculateBracketTaxWithBreakdown(income) {
45
+ let tax = 0;
46
+ const bracketBreakdown = [];
47
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
48
+ const bracket = this._rules.taxBrackets[index];
49
+ if (income <= bracket.from) {
50
+ bracketBreakdown.push({
51
+ bracketIndex: index,
52
+ bracketName: `Bracket ${index + 1}`,
53
+ from: bracket.from,
54
+ to: bracket.to ?? null,
55
+ rate: bracket.rate,
56
+ amountInBracket: 0,
57
+ taxOnAmount: 0,
58
+ });
59
+ break;
60
+ }
61
+ const upper = bracket.to ?? income;
62
+ const taxableAmount = Math.min(upper, income) - bracket.from;
63
+ if (taxableAmount > 0) {
64
+ const taxOnAmount = taxableAmount * bracket.rate;
65
+ tax += taxOnAmount;
66
+ bracketBreakdown.push({
67
+ bracketIndex: index,
68
+ bracketName: `Bracket ${index + 1}`,
69
+ from: bracket.from,
70
+ to: bracket.to ?? null,
71
+ rate: bracket.rate,
72
+ amountInBracket: taxableAmount,
73
+ taxOnAmount: taxOnAmount,
74
+ });
75
+ }
76
+ else {
77
+ bracketBreakdown.push({
78
+ bracketIndex: index,
79
+ bracketName: `Bracket ${index + 1}`,
80
+ from: bracket.from,
81
+ to: bracket.to ?? null,
82
+ rate: bracket.rate,
83
+ amountInBracket: 0,
84
+ taxOnAmount: 0,
85
+ });
86
+ }
87
+ }
88
+ return { grossTax: tax, bracketBreakdown };
89
+ }
42
90
  calculateBracketTax(income) {
43
91
  let tax = 0;
44
92
  for (const bracket of this._rules.taxBrackets) {
@@ -94,4 +142,4 @@ class SouthAfricaIncomeTaxServiceImpl {
94
142
  }
95
143
  }
96
144
  exports.SouthAfricaIncomeTaxServiceImpl = SouthAfricaIncomeTaxServiceImpl;
97
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU291dGhBZnJpY2FJbmNvbWVUYXhTZXJ2aWNlSW1wbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9pbmNvbWUtdGF4L3NvdXRoLWFmcmljYS9Tb3V0aEFmcmljYUluY29tZVRheFNlcnZpY2VJbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUdBLE1BQWEsK0JBQStCO0lBTXhDLFlBQVksTUFBYyxFQUFFLEdBQVcsRUFBRSxLQUFxQixFQUFFLG9CQUE0QixDQUFDO1FBRnJGLHVCQUFrQixHQUFXLENBQUMsQ0FBQztRQUduQyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztRQUNoQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsaUJBQWlCLENBQUM7SUFDaEQsQ0FBQztJQUVELGtCQUFrQjtRQUNkLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFFakMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbEQsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQzVCLE9BQU87Z0JBQ0gsV0FBVztnQkFDWCxTQUFTLEVBQUUsQ0FBQztnQkFDWixHQUFHLEVBQUUsQ0FBQztnQkFDTixlQUFlLEVBQUUsQ0FBQztnQkFDbEIsU0FBUyxFQUFFLFdBQVc7Z0JBQ3RCLGdCQUFnQixFQUFFLENBQUM7YUFDdEIsQ0FBQztRQUNOLENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXhELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pDLE1B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QUFDLEdBQUcsQ0FBQyxlQUFlLENBQ2xDLENBQUM7UUFFRixPQUFPLElBQUksQ0FBQyxHQUFHLENBQ1gsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksRUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQ3hDLENBQUM7SUFDTixDQUFDO0lBRU8seUJBQXlCLENBQUMsT0FBZTtRQUM3QyxJQUFJLE9BQU8sSUFBSSxDQUFDO1lBQUUsT0FBTyxDQUFDLENBQUM7UUFFM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUM7UUFFeEQsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUVyQyxJQUFJLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNmLGFBQWEsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDO1FBQzVDLENBQUM7UUFFRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNkLGFBQWE7Z0JBQ1QsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDO1FBQ3BELENBQUM7UUFFRCxPQUFPLENBQ0gsYUFBYTtZQUNiLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsZ0JBQWdCLENBQ25ELENBQUM7SUFDTixDQUFDO0lBRU8sS0FBSyxDQUFDLEtBQWEsRUFBRSxRQUFRLEdBQUcsQ0FBQztRQUNyQyxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDM0MsQ0FBQztDQUNKO0FBaklELDBFQWlJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXB1dGVkSW5jb21lVGF4VmFsdWVzLCBJbmNvbWVUYXhSdWxlcyB9IGZyb20gXCIuL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgU291dGhBZnJpY2FJbmNvbWVUYXhTZXJ2aWNlIH0gZnJvbSBcIi4vU291dGhBZnJpY2FJbmNvbWVUYXhTZXJ2aWNlXCI7XG5cbmV4cG9ydCBjbGFzcyBTb3V0aEFmcmljYUluY29tZVRheFNlcnZpY2VJbXBsIGltcGxlbWVudHMgU291dGhBZnJpY2FJbmNvbWVUYXhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF9pbmNvbWU6IG51bWJlcjtcbiAgICBwcml2YXRlIF9hZ2U6IG51bWJlcjtcbiAgICBwcml2YXRlIF9ydWxlczogSW5jb21lVGF4UnVsZXM7XG4gICAgcHJpdmF0ZSBfbWVkaWNhbEFpZE1lbWJlcnM6IG51bWJlciA9IDA7XG5cbiAgICBjb25zdHJ1Y3RvcihpbmNvbWU6IG51bWJlciwgYWdlOiBudW1iZXIsIHJ1bGVzOiBJbmNvbWVUYXhSdWxlcywgbWVkaWNhbEFpZE1lbWJlcnM6IG51bWJlciA9IDApIHtcbiAgICAgICAgdGhpcy5faW5jb21lID0gaW5jb21lO1xuICAgICAgICB0aGlzLl9hZ2UgPSBhZ2U7XG4gICAgICAgIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gICAgICAgIHRoaXMuX21lZGljYWxBaWRNZW1iZXJzID0gbWVkaWNhbEFpZE1lbWJlcnM7XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlTmV0SW5jb21lKCk6IENvbXB1dGVkSW5jb21lVGF4VmFsdWVzIHtcbiAgICAgICAgY29uc3QgZ3Jvc3NJbmNvbWUgPSB0aGlzLl9pbmNvbWU7XG5cbiAgICAgICAgY29uc3QgdGhyZXNob2xkID0gdGhpcy5nZXRUYXhUaHJlc2hvbGQodGhpcy5fYWdlKTtcblxuICAgICAgICBpZiAodGhpcy5faW5jb21lIDw9IHRocmVzaG9sZCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBncm9zc0luY29tZSxcbiAgICAgICAgICAgICAgICBpbmNvbWVUYXg6IDAsXG4gICAgICAgICAgICAgICAgdWlmOiAwLFxuICAgICAgICAgICAgICAgIHRvdGFsRGVkdWN0aW9uczogMCxcbiAgICAgICAgICAgICAgICBuZXRJbmNvbWU6IGdyb3NzSW5jb21lLFxuICAgICAgICAgICAgICAgIGVmZmVjdGl2ZVRheFJhdGU6IDAsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZ3Jvc3NUYXggPSB0aGlzLmNhbGN1bGF0ZUJyYWNrZXRUYXgodGhpcy5faW5jb21lKTtcblxuICAgICAgICBjb25zdCByZWJhdGUgPSB0aGlzLmdldFJlYmF0ZSh0aGlzLl9hZ2UpO1xuICAgICAgICBjb25zdCBtZWRpY2FsQWlkQ3JlZGl0ID1cbiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlTWVkaWNhbEFpZENyZWRpdCh0aGlzLl9tZWRpY2FsQWlkTWVtYmVycyk7XG4gICAgICAgIGNvbnN0IGluY29tZVRheCA9IE1hdGgubWF4KDAsIGdyb3NzVGF4IC0gcmViYXRlIC0gbWVkaWNhbEFpZENyZWRpdCk7XG5cbiAgICAgICAgY29uc3QgdWlmID0gdGhpcy5jYWxjdWxhdGVVaWYodGhpcy5faW5jb21lKTtcblxuICAgICAgICBjb25zdCB0b3RhbERlZHVjdGlvbnMgPSBpbmNvbWVUYXggKyB1aWY7XG4gICAgICAgIGNvbnN0IG5ldEluY29tZSA9IGdyb3NzSW5jb21lIC0gdG90YWxEZWR1Y3Rpb25zO1xuICAgICAgICBjb25zdCBlZmZlY3RpdmVUYXhSYXRlID0gaW5jb21lVGF4IC8gZ3Jvc3NJbmNvbWU7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGdyb3NzSW5jb21lLFxuICAgICAgICAgICAgaW5jb21lVGF4OiB0aGlzLnJvdW5kKGluY29tZVRheCksXG4gICAgICAgICAgICB1aWY6IHRoaXMucm91bmQodWlmKSxcbiAgICAgICAgICAgIHRvdGFsRGVkdWN0aW9uczogdGhpcy5yb3VuZCh0b3RhbERlZHVjdGlvbnMpLFxuICAgICAgICAgICAgbmV0SW5jb21lOiB0aGlzLnJvdW5kKG5ldEluY29tZSksXG4gICAgICAgICAgICBlZmZlY3RpdmVUYXhSYXRlOiB0aGlzLnJvdW5kKGVmZmVjdGl2ZVRheFJhdGUsIDQpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgY2FsY3VsYXRlQnJhY2tldFRheChpbmNvbWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGxldCB0YXggPSAwO1xuXG4gICAgICAgIGZvciAoY29uc3QgYnJhY2tldCBvZiB0aGlzLl9ydWxlcy50YXhCcmFja2V0cykge1xuICAgICAgICAgICAgaWYgKGluY29tZSA8PSBicmFja2V0LmZyb20pIGJyZWFrO1xuXG4gICAgICAgICAgICBjb25zdCB1cHBlciA9IGJyYWNrZXQudG8gPz8gaW5jb21lO1xuICAgICAgICAgICAgY29uc3QgdGF4YWJsZUFtb3VudCA9IE1hdGgubWluKHVwcGVyLCBpbmNvbWUpIC0gYnJhY2tldC5mcm9tO1xuXG4gICAgICAgICAgICBpZiAodGF4YWJsZUFtb3VudCA+IDApIHtcbiAgICAgICAgICAgICAgICB0YXggKz0gdGF4YWJsZUFtb3VudCAqIGJyYWNrZXQucmF0ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0YXg7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRUYXhUaHJlc2hvbGQoYWdlOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCB0aHJlc2hvbGRzID0gdGhpcy5fcnVsZXMudGF4VGhyZXNob2xkcztcblxuICAgICAgICBpZiAoYWdlID49IDc1KSByZXR1cm4gdGhyZXNob2xkcy5hZ2U3NVBsdXM7XG4gICAgICAgIGlmIChhZ2UgPj0gNjUpIHJldHVybiB0aHJlc2hvbGRzLmFnZTY1VG83NDtcblxuICAgICAgICByZXR1cm4gdGhyZXNob2xkcy51bmRlcjY1O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UmViYXRlKGFnZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IHJlYmF0ZSA9IHRoaXMuX3J1bGVzLnJlYmF0ZXMucHJpbWFyeS5hbW91bnQ7XG5cbiAgICAgICAgaWYgKGFnZSA+PSB0aGlzLl9ydWxlcy5yZWJhdGVzLnNlY29uZGFyeS5hZ2VNaW4pIHtcbiAgICAgICAgICAgIHJlYmF0ZSArPSB0aGlzLl9ydWxlcy5yZWJhdGVzLnNlY29uZGFyeS5hbW91bnQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWdlID49IHRoaXMuX3J1bGVzLnJlYmF0ZXMudGVydGlhcnkuYWdlTWluKSB7XG4gICAgICAgICAgICByZWJhdGUgKz0gdGhpcy5fcnVsZXMucmViYXRlcy50ZXJ0aWFyeS5hbW91bnQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmViYXRlO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2FsY3VsYXRlVWlmKGluY29tZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgY2FwcGVkSW5jb21lID0gTWF0aC5taW4oXG4gICAgICAgICAgICBpbmNvbWUsXG4gICAgICAgICAgICB0aGlzLl9ydWxlcy51aWYuYW5udWFsSW5jb21lQ2FwLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBNYXRoLm1pbihcbiAgICAgICAgICAgIGNhcHBlZEluY29tZSAqIHRoaXMuX3J1bGVzLnVpZi5yYXRlLFxuICAgICAgICAgICAgdGhpcy5fcnVsZXMudWlmLm1heEFubnVhbENvbnRyaWJ1dGlvbixcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbGN1bGF0ZU1lZGljYWxBaWRDcmVkaXQobWVtYmVyczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKG1lbWJlcnMgPD0gMCkgcmV0dXJuIDA7XG5cbiAgICAgICAgY29uc3QgbW9udGhseSA9IHRoaXMuX3J1bGVzLm1lZGljYWxBaWRUYXhDcmVkaXQubW9udGhseTtcblxuICAgICAgICBsZXQgbW9udGhseUNyZWRpdCA9IG1vbnRobHkudGF4cGF5ZXI7XG5cbiAgICAgICAgaWYgKG1lbWJlcnMgPj0gMikge1xuICAgICAgICAgICAgbW9udGhseUNyZWRpdCArPSBtb250aGx5LmZpcnN0RGVwZW5kYW50O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lbWJlcnMgPiAyKSB7XG4gICAgICAgICAgICBtb250aGx5Q3JlZGl0ICs9XG4gICAgICAgICAgICAgICAgKG1lbWJlcnMgLSAyKSAqIG1vbnRobHkuYWRkaXRpb25hbERlcGVuZGFudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBtb250aGx5Q3JlZGl0ICpcbiAgICAgICAgICAgIHRoaXMuX3J1bGVzLm1lZGljYWxBaWRUYXhDcmVkaXQuYW5udWFsTXVsdGlwbGllclxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgcm91bmQodmFsdWU6IG51bWJlciwgZGVjaW1hbHMgPSAyKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIE51bWJlcih2YWx1ZS50b0ZpeGVkKGRlY2ltYWxzKSk7XG4gICAgfVxufSJdfQ==
145
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU291dGhBZnJpY2FJbmNvbWVUYXhTZXJ2aWNlSW1wbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9pbmNvbWUtdGF4L3NvdXRoLWFmcmljYS9Tb3V0aEFmcmljYUluY29tZVRheFNlcnZpY2VJbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUlBLE1BQWEsK0JBQStCO0lBTXhDLFlBQVksTUFBYyxFQUFFLEdBQVcsRUFBRSxLQUFxQixFQUFFLG9CQUE0QixDQUFDO1FBRnJGLHVCQUFrQixHQUFXLENBQUMsQ0FBQztRQUduQyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztRQUNoQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsaUJBQWlCLENBQUM7SUFDaEQsQ0FBQztJQUVELGtCQUFrQjtRQUNkLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFFakMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbEQsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQzVCLE9BQU87Z0JBQ0gsV0FBVztnQkFDWCxTQUFTLEVBQUUsQ0FBQztnQkFDWixHQUFHLEVBQUUsQ0FBQztnQkFDTixlQUFlLEVBQUUsQ0FBQztnQkFDbEIsU0FBUyxFQUFFLFdBQVc7Z0JBQ3RCLGdCQUFnQixFQUFFLENBQUM7Z0JBQ25CLG1CQUFtQixFQUFFLEVBQUU7YUFDMUIsQ0FBQztRQUNOLENBQUM7UUFFRCxNQUFNLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLEdBQUcsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUUzRixNQUFNLE1BQU0sR0FBRyxJQUFJLENB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QU0sQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUM7UUFFeEQsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUVyQyxJQUFJLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNmLGFBQWEsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDO1FBQzVDLENBQUM7UUFFRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNkLGFBQWE7Z0JBQ1QsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDO1FBQ3BELENBQUM7UUFFRCxPQUFPLENBQ0gsYUFBYTtZQUNiLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsZ0JBQWdCLENBQ25ELENBQUM7SUFDTixDQUFDO0lBRU8sS0FBSyxDQUFDLEtBQWEsRUFBRSxRQUFRLEdBQUcsQ0FBQztRQUNyQyxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDM0MsQ0FBQztDQUNKO0FBdExELDBFQXNMQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJyYWNrZXRBbGxvY2F0aW9uIH0gZnJvbSBcIi4uL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMsIEluY29tZVRheFJ1bGVzIH0gZnJvbSBcIi4vZG9tYWluL3R5cGVzXCI7XG5pbXBvcnQgeyBTb3V0aEFmcmljYUluY29tZVRheFNlcnZpY2UgfSBmcm9tIFwiLi9Tb3V0aEFmcmljYUluY29tZVRheFNlcnZpY2VcIjtcblxuZXhwb3J0IGNsYXNzIFNvdXRoQWZyaWNhSW5jb21lVGF4U2VydmljZUltcGwgaW1wbGVtZW50cyBTb3V0aEFmcmljYUluY29tZVRheFNlcnZpY2Uge1xuICAgIHByaXZhdGUgX2luY29tZTogbnVtYmVyO1xuICAgIHByaXZhdGUgX2FnZTogbnVtYmVyO1xuICAgIHByaXZhdGUgX3J1bGVzOiBJbmNvbWVUYXhSdWxlcztcbiAgICBwcml2YXRlIF9tZWRpY2FsQWlkTWVtYmVyczogbnVtYmVyID0gMDtcblxuICAgIGNvbnN0cnVjdG9yKGluY29tZTogbnVtYmVyLCBhZ2U6IG51bWJlciwgcnVsZXM6IEluY29tZVRheFJ1bGVzLCBtZWRpY2FsQWlkTWVtYmVyczogbnVtYmVyID0gMCkge1xuICAgICAgICB0aGlzLl9pbmNvbWUgPSBpbmNvbWU7XG4gICAgICAgIHRoaXMuX2FnZSA9IGFnZTtcbiAgICAgICAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgICAgICAgdGhpcy5fbWVkaWNhbEFpZE1lbWJlcnMgPSBtZWRpY2FsQWlkTWVtYmVycztcbiAgICB9XG5cbiAgICBjYWxjdWxhdGVOZXRJbmNvbWUoKTogQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMge1xuICAgICAgICBjb25zdCBncm9zc0luY29tZSA9IHRoaXMuX2luY29tZTtcblxuICAgICAgICBjb25zdCB0aHJlc2hvbGQgPSB0aGlzLmdldFRheFRocmVzaG9sZCh0aGlzLl9hZ2UpO1xuXG4gICAgICAgIGlmICh0aGlzLl9pbmNvbWUgPD0gdGhyZXNob2xkKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGdyb3NzSW5jb21lLFxuICAgICAgICAgICAgICAgIGluY29tZVRheDogMCxcbiAgICAgICAgICAgICAgICB1aWY6IDAsXG4gICAgICAgICAgICAgICAgdG90YWxEZWR1Y3Rpb25zOiAwLFxuICAgICAgICAgICAgICAgIG5ldEluY29tZTogZ3Jvc3NJbmNvbWUsXG4gICAgICAgICAgICAgICAgZWZmZWN0aXZlVGF4UmF0ZTogMCxcbiAgICAgICAgICAgICAgICB0YXhCcmFja2V0QnJlYWtkb3duOiBbXSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGdyb3NzVGF4LCBicmFja2V0QnJlYWtkb3duIH0gPSB0aGlzLmNhbGN1bGF0ZUJyYWNrZXRUYXhXaXRoQnJlYWtkb3duKHRoaXMuX2luY29tZSk7XG5cbiAgICAgICAgY29uc3QgcmViYXRlID0gdGhpcy5nZXRSZWJhdGUodGhpcy5fYWdlKTtcbiAgICAgICAgY29uc3QgbWVkaWNhbEFpZENyZWRpdCA9XG4gICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZU1lZGljYWxBaWRDcmVkaXQodGhpcy5fbWVkaWNhbEFpZE1lbWJlcnMpO1xuICAgICAgICBjb25zdCBpbmNvbWVUYXggPSBNYXRoLm1heCgwLCBncm9zc1RheCAtIHJlYmF0ZSAtIG1lZGljYWxBaWRDcmVkaXQpO1xuXG4gICAgICAgIGNvbnN0IHVpZiA9IHRoaXMuY2FsY3VsYXRlVWlmKHRoaXMuX2luY29tZSk7XG5cbiAgICAgICAgY29uc3QgdG90YWxEZWR1Y3Rpb25zID0gaW5jb21lVGF4ICsgdWlmO1xuICAgICAgICBjb25zdCBuZXRJbmNvbWUgPSBncm9zc0luY29tZSAtIHRvdGFsRGVkdWN0aW9ucztcbiAgICAgICAgY29uc3QgZWZmZWN0aXZlVGF4UmF0ZSA9IGluY29tZVRheCAvIGdyb3NzSW5jb21lO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBncm9zc0luY29tZSxcbiAgICAgICAgICAgIGluY29tZVRheDogdGhpcy5yb3VuZChpbmNvbWVUYXgpLFxuICAgICAgICAgICAgdWlmOiB0aGlzLnJvdW5kKHVpZiksXG4gICAgICAgICAgICB0b3RhbERlZHVjdGlvbnM6IHRoaXMucm91bmQodG90YWxEZWR1Y3Rpb25zKSxcbiAgICAgICAgICAgIG5ldEluY29tZTogdGhpcy5yb3VuZChuZXRJbmNvbWUpLFxuICAgICAgICAgICAgZWZmZWN0aXZlVGF4UmF0ZTogdGhpcy5yb3VuZChlZmZlY3RpdmVUYXhSYXRlLCA0KSxcbiAgICAgICAgICAgIHRheEJyYWNrZXRCcmVha2Rvd246IGJyYWNrZXRCcmVha2Rvd24sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVCcmFja2V0VGF4V2l0aEJyZWFrZG93bihpbmNvbWU6IG51bWJlcik6IHsgZ3Jvc3NUYXg6IG51bWJlcjsgYnJhY2tldEJyZWFrZG93bjogQnJhY2tldEFsbG9jYXRpb25bXSB9IHtcbiAgICAgICAgbGV0IHRheCA9IDA7XG4gICAgICAgIGNvbnN0IGJyYWNrZXRCcmVha2Rvd246IEJyYWNrZXRBbGxvY2F0aW9uW10gPSBbXTtcblxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5fcnVsZXMudGF4QnJhY2tldHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICBjb25zdCBicmFja2V0ID0gdGhpcy5fcnVsZXMudGF4QnJhY2tldHNbaW5kZXhdO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoaW5jb21lIDw9IGJyYWNrZXQuZnJvbSkge1xuICAgICAgICAgICAgICAgIGJyYWNrZXRCcmVha2Rvd24ucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGJyYWNrZXRJbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIGJyYWNrZXROYW1lOiBgQnJhY2tldCAke2luZGV4ICsgMX1gLFxuICAgICAgICAgICAgICAgICAgICBmcm9tOiBicmFja2V0LmZyb20sXG4gICAgICAgICAgICAgICAgICAgIHRvOiBicmFja2V0LnRvID8/IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHJhdGU6IGJyYWNrZXQucmF0ZSxcbiAgICAgICAgICAgICAgICAgICAgYW1vdW50SW5CcmFja2V0OiAwLFxuICAgICAgICAgICAgICAgICAgICB0YXhPbkFtb3VudDogMCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdXBwZXIgPSBicmFja2V0LnRvID8/IGluY29tZTtcbiAgICAgICAgICAgIGNvbnN0IHRheGFibGVBbW91bnQgPSBNYXRoLm1pbih1cHBlciwgaW5jb21lKSAtIGJyYWNrZXQuZnJvbTtcblxuICAgICAgICAgICAgaWYgKHRheGFibGVBbW91bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGF4T25BbW91bnQgPSB0YXhhYmxlQW1vdW50ICogYnJhY2tldC5yYXRlO1xuICAgICAgICAgICAgICAgIHRheCArPSB0YXhPbkFtb3VudDtcbiAgICAgICAgICAgICAgICBicmFja2V0QnJlYWtkb3duLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBicmFja2V0SW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBicmFja2V0TmFtZTogYEJyYWNrZXQgJHtpbmRleCArIDF9YCxcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogYnJhY2tldC5mcm9tLFxuICAgICAgICAgICAgICAgICAgICB0bzogYnJhY2tldC50byA/PyBudWxsLFxuICAgICAgICAgICAgICAgICAgICByYXRlOiBicmFja2V0LnJhdGUsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudEluQnJhY2tldDogdGF4YWJsZUFtb3VudCxcbiAgICAgICAgICAgICAgICAgICAgdGF4T25BbW91bnQ6IHRheE9uQW1vdW50LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBicmFja2V0QnJlYWtkb3duLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBicmFja2V0SW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBicmFja2V0TmFtZTogYEJyYWNrZXQgJHtpbmRleCArIDF9YCxcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogYnJhY2tldC5mcm9tLFxuICAgICAgICAgICAgICAgICAgICB0bzogYnJhY2tldC50byA/PyBudWxsLFxuICAgICAgICAgICAgICAgICAgICByYXRlOiBicmFja2V0LnJhdGUsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudEluQnJhY2tldDogMCxcbiAgICAgICAgICAgICAgICAgICAgdGF4T25BbW91bnQ6IDAsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBncm9zc1RheDogdGF4LCBicmFja2V0QnJlYWtkb3duIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVCcmFja2V0VGF4KGluY29tZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IHRheCA9IDA7XG5cbiAgICAgICAgZm9yIChjb25zdCBicmFja2V0IG9mIHRoaXMuX3J1bGVzLnRheEJyYWNrZXRzKSB7XG4gICAgICAgICAgICBpZiAoaW5jb21lIDw9IGJyYWNrZXQuZnJvbSkgYnJlYWs7XG5cbiAgICAgICAgICAgIGNvbnN0IHVwcGVyID0gYnJhY2tldC50byA/PyBpbmNvbWU7XG4gICAgICAgICAgICBjb25zdCB0YXhhYmxlQW1vdW50ID0gTWF0aC5taW4odXBwZXIsIGluY29tZSkgLSBicmFja2V0LmZyb207XG5cbiAgICAgICAgICAgIGlmICh0YXhhYmxlQW1vdW50ID4gMCkge1xuICAgICAgICAgICAgICAgIHRheCArPSB0YXhhYmxlQW1vdW50ICogYnJhY2tldC5yYXRlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRheDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFRheFRocmVzaG9sZChhZ2U6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IHRocmVzaG9sZHMgPSB0aGlzLl9ydWxlcy50YXhUaHJlc2hvbGRzO1xuXG4gICAgICAgIGlmIChhZ2UgPj0gNzUpIHJldHVybiB0aHJlc2hvbGRzLmFnZTc1UGx1cztcbiAgICAgICAgaWYgKGFnZSA+PSA2NSkgcmV0dXJuIHRocmVzaG9sZHMuYWdlNjVUbzc0O1xuXG4gICAgICAgIHJldHVybiB0aHJlc2hvbGRzLnVuZGVyNjU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZWJhdGUoYWdlOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBsZXQgcmViYXRlID0gdGhpcy5fcnVsZXMucmViYXRlcy5wcmltYXJ5LmFtb3VudDtcblxuICAgICAgICBpZiAoYWdlID49IHRoaXMuX3J1bGVzLnJlYmF0ZXMuc2Vjb25kYXJ5LmFnZU1pbikge1xuICAgICAgICAgICAgcmViYXRlICs9IHRoaXMuX3J1bGVzLnJlYmF0ZXMuc2Vjb25kYXJ5LmFtb3VudDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhZ2UgPj0gdGhpcy5fcnVsZXMucmViYXRlcy50ZXJ0aWFyeS5hZ2VNaW4pIHtcbiAgICAgICAgICAgIHJlYmF0ZSArPSB0aGlzLl9ydWxlcy5yZWJhdGVzLnRlcnRpYXJ5LmFtb3VudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZWJhdGU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVVaWYoaW5jb21lOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBjYXBwZWRJbmNvbWUgPSBNYXRoLm1pbihcbiAgICAgICAgICAgIGluY29tZSxcbiAgICAgICAgICAgIHRoaXMuX3J1bGVzLnVpZi5hbm51YWxJbmNvbWVDYXAsXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIE1hdGgubWluKFxuICAgICAgICAgICAgY2FwcGVkSW5jb21lICogdGhpcy5fcnVsZXMudWlmLnJhdGUsXG4gICAgICAgICAgICB0aGlzLl9ydWxlcy51aWYubWF4QW5udWFsQ29udHJpYnV0aW9uLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2FsY3VsYXRlTWVkaWNhbEFpZENyZWRpdChtZW1iZXJzOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBpZiAobWVtYmVycyA8PSAwKSByZXR1cm4gMDtcblxuICAgICAgICBjb25zdCBtb250aGx5ID0gdGhpcy5fcnVsZXMubWVkaWNhbEFpZFRheENyZWRpdC5tb250aGx5O1xuXG4gICAgICAgIGxldCBtb250aGx5Q3JlZGl0ID0gbW9udGhseS50YXhwYXllcjtcblxuICAgICAgICBpZiAobWVtYmVycyA+PSAyKSB7XG4gICAgICAgICAgICBtb250aGx5Q3JlZGl0ICs9IG1vbnRobHkuZmlyc3REZXBlbmRhbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWVtYmVycyA+IDIpIHtcbiAgICAgICAgICAgIG1vbnRobHlDcmVkaXQgKz1cbiAgICAgICAgICAgICAgICAobWVtYmVycyAtIDIpICogbW9udGhseS5hZGRpdGlvbmFsRGVwZW5kYW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIG1vbnRobHlDcmVkaXQgKlxuICAgICAgICAgICAgdGhpcy5fcnVsZXMubWVkaWNhbEFpZFRheENyZWRpdC5hbm51YWxNdWx0aXBsaWVyXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByb3VuZCh2YWx1ZTogbnVtYmVyLCBkZWNpbWFscyA9IDIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gTnVtYmVyKHZhbHVlLnRvRml4ZWQoZGVjaW1hbHMpKTtcbiAgICB9XG59Il19
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW5jb21lLXRheC9zb3V0aC1hZnJpY2EvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZ2VCYXNlZFJlYmF0ZSwgVGF4QnJhY2tldCB9IGZyb20gXCIuLi8uLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJbmNvbWVUYXhSdWxlcyB7XG4gIHRheEJyYWNrZXRzOiBUYXhCcmFja2V0W107XG4gIHJlYmF0ZXM6IFRheFJlYmF0ZXM7XG4gIHRheFRocmVzaG9sZHM6IFRheFRocmVzaG9sZHM7XG4gIG1lZGljYWxBaWRUYXhDcmVkaXQ6IE1lZGljYWxBaWRUYXhDcmVkaXQ7XG4gIHVpZjogVWlmUnVsZXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGF4UmViYXRlcyB7XG4gIHByaW1hcnk6IEFnZUJhc2VkUmViYXRlO1xuICBzZWNvbmRhcnk6IEFnZUJhc2VkUmViYXRlO1xuICB0ZXJ0aWFyeTogQWdlQmFzZWRSZWJhdGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGF4VGhyZXNob2xkcyB7XG4gIHVuZGVyNjU6IG51bWJlcjtcbiAgYWdlNjVUbzc0OiBudW1iZXI7XG4gIGFnZTc1UGx1czogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1lZGljYWxBaWRUYXhDcmVkaXQge1xuICBtb250aGx5OiBNZWRpY2FsQWlkTW9udGhseUNyZWRpdDtcbiAgYW5udWFsTXVsdGlwbGllcjogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1lZGljYWxBaWRNb250aGx5Q3JlZGl0IHtcbiAgdGF4cGF5ZXI6IG51bWJlcjtcbiAgZmlyc3REZXBlbmRhbnQ6IG51bWJlcjtcbiAgYWRkaXRpb25hbERlcGVuZGFudDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVpZlJ1bGVzIHtcbiAgcmF0ZTogbnVtYmVyO1xuICBhbm51YWxJbmNvbWVDYXA6IG51bWJlcjtcbiAgbWF4QW5udWFsQ29udHJpYnV0aW9uOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZWRJbmNvbWVUYXhWYWx1ZXMge1xuICBncm9zc0luY29tZTogbnVtYmVyO1xuICBpbmNvbWVUYXg6IG51bWJlcjtcbiAgdWlmOiBudW1iZXI7XG4gIHRvdGFsRGVkdWN0aW9uczogbnVtYmVyO1xuICBuZXRJbmNvbWU6IG51bWJlcjtcbiAgZWZmZWN0aXZlVGF4UmF0ZTogbnVtYmVyO1xufVxuIl19
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW5jb21lLXRheC9zb3V0aC1hZnJpY2EvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZ2VCYXNlZFJlYmF0ZSwgQnJhY2tldEFsbG9jYXRpb24sIFRheEJyYWNrZXQgfSBmcm9tIFwiLi4vLi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5jb21lVGF4UnVsZXMge1xuICB0YXhCcmFja2V0czogVGF4QnJhY2tldFtdO1xuICByZWJhdGVzOiBUYXhSZWJhdGVzO1xuICB0YXhUaHJlc2hvbGRzOiBUYXhUaHJlc2hvbGRzO1xuICBtZWRpY2FsQWlkVGF4Q3JlZGl0OiBNZWRpY2FsQWlkVGF4Q3JlZGl0O1xuICB1aWY6IFVpZlJ1bGVzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRheFJlYmF0ZXMge1xuICBwcmltYXJ5OiBBZ2VCYXNlZFJlYmF0ZTtcbiAgc2Vjb25kYXJ5OiBBZ2VCYXNlZFJlYmF0ZTtcbiAgdGVydGlhcnk6IEFnZUJhc2VkUmViYXRlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRheFRocmVzaG9sZHMge1xuICB1bmRlcjY1OiBudW1iZXI7XG4gIGFnZTY1VG83NDogbnVtYmVyO1xuICBhZ2U3NVBsdXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZWRpY2FsQWlkVGF4Q3JlZGl0IHtcbiAgbW9udGhseTogTWVkaWNhbEFpZE1vbnRobHlDcmVkaXQ7XG4gIGFubnVhbE11bHRpcGxpZXI6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZWRpY2FsQWlkTW9udGhseUNyZWRpdCB7XG4gIHRheHBheWVyOiBudW1iZXI7XG4gIGZpcnN0RGVwZW5kYW50OiBudW1iZXI7XG4gIGFkZGl0aW9uYWxEZXBlbmRhbnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVaWZSdWxlcyB7XG4gIHJhdGU6IG51bWJlcjtcbiAgYW5udWFsSW5jb21lQ2FwOiBudW1iZXI7XG4gIG1heEFubnVhbENvbnRyaWJ1dGlvbjogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVkSW5jb21lVGF4VmFsdWVzIHtcbiAgICBncm9zc0luY29tZTogbnVtYmVyO1xuICAgIGluY29tZVRheDogbnVtYmVyO1xuICAgIHVpZjogbnVtYmVyO1xuICAgIHRvdGFsRGVkdWN0aW9uczogbnVtYmVyO1xuICAgIG5ldEluY29tZTogbnVtYmVyO1xuICAgIGVmZmVjdGl2ZVRheFJhdGU6IG51bWJlcjtcbiAgICB0YXhCcmFja2V0QnJlYWtkb3duOiBCcmFja2V0QWxsb2NhdGlvbltdO1xufVxuIl19
@@ -5,6 +5,7 @@ export declare class CanadaIncomeTaxServiceImpl implements CanadaIncomeTaxServic
5
5
  private _rules;
6
6
  constructor(income: number, rules: IncomeTaxRules);
7
7
  calculateNetIncome(): ComputedIncomeTaxValues;
8
+ private computeTaxBracketBreakdown;
8
9
  private computeGrossTax;
9
10
  private applyCredits;
10
11
  private computeCPP;
@@ -1,4 +1,4 @@
1
- import { TaxBracket } from "../../domain/types";
1
+ import { BracketAllocation, TaxBracket } from "../../domain/types";
2
2
  export interface IncomeTaxRules {
3
3
  taxBrackets: TaxBracket[];
4
4
  credits?: Record<string, TaxCredit>;
@@ -31,4 +31,5 @@ export interface ComputedIncomeTaxValues {
31
31
  totalDeductions: number;
32
32
  netIncome: number;
33
33
  effectiveTaxRate: number;
34
+ taxBracketBreakdown: BracketAllocation[];
34
35
  }
@@ -25,3 +25,12 @@ export interface AgeBasedRebate {
25
25
  ageMin: number;
26
26
  amount: number;
27
27
  }
28
+ export interface BracketAllocation {
29
+ bracketIndex: number;
30
+ bracketName: string;
31
+ from: number;
32
+ to: number | null;
33
+ rate: number;
34
+ amountInBracket: number;
35
+ taxOnAmount: number;
36
+ }
@@ -1,5 +1,5 @@
1
1
  import { RuleMeta } from "../../../shared/domain/types";
2
- import { RuleInput, RuleOutput, TaxBracket } from "../../domain/types";
2
+ import { BracketAllocation, RuleInput, RuleOutput, TaxBracket } from "../../domain/types";
3
3
  export interface IncomeTaxRules {
4
4
  taxBrackets: TaxBracket[];
5
5
  quotientFamilial: QuotientFamilial;
@@ -27,4 +27,5 @@ export interface ComputedIncomeTaxValues {
27
27
  netIncome: number;
28
28
  averageTaxRate: number;
29
29
  marginalTaxRate: number;
30
+ taxBracketBreakdown: BracketAllocation[];
30
31
  }
@@ -7,6 +7,7 @@ export declare class SouthAfricaIncomeTaxServiceImpl implements SouthAfricaIncom
7
7
  private _medicalAidMembers;
8
8
  constructor(income: number, age: number, rules: IncomeTaxRules, medicalAidMembers?: number);
9
9
  calculateNetIncome(): ComputedIncomeTaxValues;
10
+ private calculateBracketTaxWithBreakdown;
10
11
  private calculateBracketTax;
11
12
  private getTaxThreshold;
12
13
  private getRebate;
@@ -1,4 +1,4 @@
1
- import { AgeBasedRebate, TaxBracket } from "../../domain/types";
1
+ import { AgeBasedRebate, BracketAllocation, TaxBracket } from "../../domain/types";
2
2
  export interface IncomeTaxRules {
3
3
  taxBrackets: TaxBracket[];
4
4
  rebates: TaxRebates;
@@ -37,4 +37,5 @@ export interface ComputedIncomeTaxValues {
37
37
  totalDeductions: number;
38
38
  netIncome: number;
39
39
  effectiveTaxRate: number;
40
+ taxBracketBreakdown: BracketAllocation[];
40
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novha/calc-engines",
3
- "version": "1.5.0",
3
+ "version": "1.6.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/types/index.d.ts",
6
6
  "scripts": {
@@ -1,4 +1,4 @@
1
- import { TaxBracket } from "../domain/types";
1
+ import { BracketAllocation, TaxBracket } from "../domain/types";
2
2
  import { CanadaIncomeTaxService } from "./CanadaIncomeTaxService";
3
3
  import {
4
4
  CPPContribution,
@@ -20,7 +20,8 @@ export class CanadaIncomeTaxServiceImpl implements CanadaIncomeTaxService {
20
20
 
21
21
  public calculateNetIncome(): ComputedIncomeTaxValues {
22
22
 
23
- const grossTax = this.computeGrossTax(this._income, this._rules.taxBrackets);
23
+ const bracketBreakdown = this.computeTaxBracketBreakdown(this._income, this._rules.taxBrackets);
24
+ const grossTax = bracketBreakdown.reduce((total, b) => total + b.taxOnAmount, 0);
24
25
  const netTax = this.applyCredits(grossTax, this._rules.credits);
25
26
  const cpp = this.computeCPP(this._income, this._rules.contributions?.cpp);
26
27
  const ei = this.computeEI(this._income, this._rules.contributions?.ei);
@@ -33,9 +34,40 @@ export class CanadaIncomeTaxServiceImpl implements CanadaIncomeTaxService {
33
34
  totalDeductions: netTax + cpp + ei,
34
35
  netIncome: this._income - netTax - cpp - ei,
35
36
  effectiveTaxRate: netTax / this._income,
37
+ taxBracketBreakdown: bracketBreakdown,
36
38
  };
37
39
  }
38
40
 
41
+ private computeTaxBracketBreakdown(income: number, brackets: TaxBracket[]): BracketAllocation[] {
42
+ return brackets.map((b, index) => {
43
+ if (income <= b.from) {
44
+ return {
45
+ bracketIndex: index,
46
+ bracketName: `Bracket ${index + 1}`,
47
+ from: b.from,
48
+ to: b.to ?? null,
49
+ rate: b.rate,
50
+ amountInBracket: 0,
51
+ taxOnAmount: 0,
52
+ };
53
+ }
54
+
55
+ const upper = b.to ?? income;
56
+ const taxable = Math.min(income, upper) - b.from;
57
+ const taxOnAmount = taxable * b.rate;
58
+
59
+ return {
60
+ bracketIndex: index,
61
+ bracketName: `Bracket ${index + 1}`,
62
+ from: b.from,
63
+ to: b.to ?? null,
64
+ rate: b.rate,
65
+ amountInBracket: taxable,
66
+ taxOnAmount: taxOnAmount,
67
+ };
68
+ });
69
+ }
70
+
39
71
  private computeGrossTax(income: number, brackets: TaxBracket[]): number {
40
72
  return brackets.reduce((total, b) => {
41
73
  if (income <= b.from) return total;
@@ -1,4 +1,4 @@
1
- import { TaxBracket } from "../../domain/types";
1
+ import { BracketAllocation, TaxBracket } from "../../domain/types";
2
2
 
3
3
  export interface IncomeTaxRules {
4
4
  taxBrackets: TaxBracket[];
@@ -37,5 +37,6 @@ export interface ComputedIncomeTaxValues {
37
37
  totalDeductions: number;
38
38
  netIncome: number;
39
39
  effectiveTaxRate: number;
40
+ taxBracketBreakdown: BracketAllocation[];
40
41
  }
41
42
 
@@ -27,6 +27,16 @@ export interface IncomeTaxCalculatorSchema<T> {
27
27
  }
28
28
 
29
29
  export interface AgeBasedRebate {
30
- ageMin: number;
31
- amount: number;
30
+ ageMin: number;
31
+ amount: number;
32
+ }
33
+
34
+ export interface BracketAllocation {
35
+ bracketIndex: number;
36
+ bracketName: string;
37
+ from: number;
38
+ to: number | null;
39
+ rate: number;
40
+ amountInBracket: number;
41
+ taxOnAmount: number;
32
42
  }
@@ -1,3 +1,4 @@
1
+ import { BracketAllocation } from "../domain/types";
1
2
  import { ComputedIncomeTaxValues, IncomeTaxRules } from "./domain/types";
2
3
  import { FranceIncomeTaxService } from "./FranceIncomeTaxService";
3
4
 
@@ -15,7 +16,7 @@ export class FranceIncomeTaxServiceImpl implements FranceIncomeTaxService {
15
16
  public calculateNetIncome(): ComputedIncomeTaxValues {
16
17
 
17
18
  const taxablePerPart = this._familyParts * this._income / this._familyParts;
18
- const { tax: taxPerPart, marginalRate } = this.calculateProgressiveTax(taxablePerPart);
19
+ const { tax: taxPerPart, marginalRate, bracketBreakdown } = this.calculateProgressiveTax(taxablePerPart);
19
20
  const incomeTax = taxPerPart * this._familyParts;
20
21
  const socialContributions = this._income * this._rules.socialContributions.employee.rate;
21
22
  const totalDeductions = incomeTax + socialContributions;
@@ -29,21 +30,34 @@ export class FranceIncomeTaxServiceImpl implements FranceIncomeTaxService {
29
30
  netIncome: this.round(netIncome),
30
31
  averageTaxRate: this.round(incomeTax / this._income),
31
32
  marginalTaxRate: marginalRate,
33
+ taxBracketBreakdown: bracketBreakdown,
32
34
  };
33
35
  }
34
36
 
35
37
 
36
38
  private calculateProgressiveTax(income: number): {
37
39
  tax: number;
38
- marginalRate: number
40
+ marginalRate: number;
41
+ bracketBreakdown: BracketAllocation[];
39
42
  } {
40
43
  let tax = 0;
41
44
  let marginalRate = 0;
45
+ const bracketBreakdown: BracketAllocation[] = [];
42
46
 
43
- for (const bracket of this._rules.taxBrackets) {
47
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
48
+ const bracket = this._rules.taxBrackets[index];
44
49
  const upperBound = bracket.to ?? income;
45
50
 
46
51
  if (income <= bracket.from) {
52
+ bracketBreakdown.push({
53
+ bracketIndex: index,
54
+ bracketName: `Bracket ${index + 1}`,
55
+ from: bracket.from,
56
+ to: bracket.to ?? null,
57
+ rate: bracket.rate,
58
+ amountInBracket: 0,
59
+ taxOnAmount: 0,
60
+ });
47
61
  break;
48
62
  }
49
63
 
@@ -52,10 +66,29 @@ export class FranceIncomeTaxServiceImpl implements FranceIncomeTaxService {
52
66
  if (taxableAmount > 0) {
53
67
  tax += taxableAmount * bracket.rate;
54
68
  marginalRate = bracket.rate;
69
+ bracketBreakdown.push({
70
+ bracketIndex: index,
71
+ bracketName: `Bracket ${index + 1}`,
72
+ from: bracket.from,
73
+ to: bracket.to ?? null,
74
+ rate: bracket.rate,
75
+ amountInBracket: taxableAmount,
76
+ taxOnAmount: taxableAmount * bracket.rate,
77
+ });
78
+ } else {
79
+ bracketBreakdown.push({
80
+ bracketIndex: index,
81
+ bracketName: `Bracket ${index + 1}`,
82
+ from: bracket.from,
83
+ to: bracket.to ?? null,
84
+ rate: bracket.rate,
85
+ amountInBracket: 0,
86
+ taxOnAmount: 0,
87
+ });
55
88
  }
56
89
  }
57
90
 
58
- return { tax, marginalRate };
91
+ return { tax, marginalRate, bracketBreakdown };
59
92
  }
60
93
 
61
94
  private round(value: number): number {
@@ -1,5 +1,5 @@
1
1
  import { RuleMeta } from "../../../shared/domain/types";
2
- import { RuleInput, RuleOutput, TaxBracket } from "../../domain/types";
2
+ import { BracketAllocation, RuleInput, RuleOutput, TaxBracket } from "../../domain/types";
3
3
 
4
4
  export interface IncomeTaxRules {
5
5
  taxBrackets: TaxBracket[];
@@ -30,4 +30,5 @@ export interface ComputedIncomeTaxValues {
30
30
  netIncome: number;
31
31
  averageTaxRate: number;
32
32
  marginalTaxRate: number;
33
+ taxBracketBreakdown: BracketAllocation[];
33
34
  }
@@ -1,3 +1,4 @@
1
+ import { BracketAllocation } from "../domain/types";
1
2
  import { ComputedIncomeTaxValues, IncomeTaxRules } from "./domain/types";
2
3
  import { SouthAfricaIncomeTaxService } from "./SouthAfricaIncomeTaxService";
3
4
 
@@ -27,10 +28,11 @@ export class SouthAfricaIncomeTaxServiceImpl implements SouthAfricaIncomeTaxServ
27
28
  totalDeductions: 0,
28
29
  netIncome: grossIncome,
29
30
  effectiveTaxRate: 0,
31
+ taxBracketBreakdown: [],
30
32
  };
31
33
  }
32
34
 
33
- const grossTax = this.calculateBracketTax(this._income);
35
+ const { grossTax, bracketBreakdown } = this.calculateBracketTaxWithBreakdown(this._income);
34
36
 
35
37
  const rebate = this.getRebate(this._age);
36
38
  const medicalAidCredit =
@@ -50,9 +52,61 @@ export class SouthAfricaIncomeTaxServiceImpl implements SouthAfricaIncomeTaxServ
50
52
  totalDeductions: this.round(totalDeductions),
51
53
  netIncome: this.round(netIncome),
52
54
  effectiveTaxRate: this.round(effectiveTaxRate, 4),
55
+ taxBracketBreakdown: bracketBreakdown,
53
56
  };
54
57
  }
55
58
 
59
+ private calculateBracketTaxWithBreakdown(income: number): { grossTax: number; bracketBreakdown: BracketAllocation[] } {
60
+ let tax = 0;
61
+ const bracketBreakdown: BracketAllocation[] = [];
62
+
63
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
64
+ const bracket = this._rules.taxBrackets[index];
65
+
66
+ if (income <= bracket.from) {
67
+ bracketBreakdown.push({
68
+ bracketIndex: index,
69
+ bracketName: `Bracket ${index + 1}`,
70
+ from: bracket.from,
71
+ to: bracket.to ?? null,
72
+ rate: bracket.rate,
73
+ amountInBracket: 0,
74
+ taxOnAmount: 0,
75
+ });
76
+ break;
77
+ }
78
+
79
+ const upper = bracket.to ?? income;
80
+ const taxableAmount = Math.min(upper, income) - bracket.from;
81
+
82
+ if (taxableAmount > 0) {
83
+ const taxOnAmount = taxableAmount * bracket.rate;
84
+ tax += taxOnAmount;
85
+ bracketBreakdown.push({
86
+ bracketIndex: index,
87
+ bracketName: `Bracket ${index + 1}`,
88
+ from: bracket.from,
89
+ to: bracket.to ?? null,
90
+ rate: bracket.rate,
91
+ amountInBracket: taxableAmount,
92
+ taxOnAmount: taxOnAmount,
93
+ });
94
+ } else {
95
+ bracketBreakdown.push({
96
+ bracketIndex: index,
97
+ bracketName: `Bracket ${index + 1}`,
98
+ from: bracket.from,
99
+ to: bracket.to ?? null,
100
+ rate: bracket.rate,
101
+ amountInBracket: 0,
102
+ taxOnAmount: 0,
103
+ });
104
+ }
105
+ }
106
+
107
+ return { grossTax: tax, bracketBreakdown };
108
+ }
109
+
56
110
  private calculateBracketTax(income: number): number {
57
111
  let tax = 0;
58
112
 
@@ -1,4 +1,4 @@
1
- import { AgeBasedRebate, TaxBracket } from "../../domain/types";
1
+ import { AgeBasedRebate, BracketAllocation, TaxBracket } from "../../domain/types";
2
2
 
3
3
  export interface IncomeTaxRules {
4
4
  taxBrackets: TaxBracket[];
@@ -38,10 +38,11 @@ export interface UifRules {
38
38
  }
39
39
 
40
40
  export interface ComputedIncomeTaxValues {
41
- grossIncome: number;
42
- incomeTax: number;
43
- uif: number;
44
- totalDeductions: number;
45
- netIncome: number;
46
- effectiveTaxRate: number;
41
+ grossIncome: number;
42
+ incomeTax: number;
43
+ uif: number;
44
+ totalDeductions: number;
45
+ netIncome: number;
46
+ effectiveTaxRate: number;
47
+ taxBracketBreakdown: BracketAllocation[];
47
48
  }