{
  "name": "Grocery and utility shares in a multigenerational home, five methods compared",
  "page": "https://otherworldlabs.com/split-grocery-bills-multigenerational-household/",
  "endpoint": "https://otherworldlabs.com/split-grocery-bills-multigenerational-household/api.json",
  "question": "For one month, how do a house's four shared bills divide across the households living in it under each of five methods - per head, per share with children counted at a fraction the family sets, per household unit, by income, and by rooms - and how far apart are those five figures for one household?",
  "answers": "The month's four bills added up, what each method divides by, the month divided by each of those divisors, each column footed, each unit's gap between the widest and the narrowest of its own figures, and that unit's figures as a share of the month. Which of those are FIELDS of this endpoint and which are derived, because round 4's m-3 found this sentence promising figures the field list does not carry: `outputs` names 27 fields and they are the five averages, perIncomeHundred, the unitOne* family (the LOWEST-NUMBERED household unit only), widestGap, the five footings, footSpread and methodsShown. No field carries any further household unit, and no field carries a resident's figure at all. Every further unit's figure and every resident's figure is derived from the rules in `formula`, which states the per-unit and the per-resident rule for all five methods explicitly; an agent reproducing the whole table reads `formula` and not `outputs` alone, and machinery/pagegates/compare_reimpl.js, which takes its field list from `outputs`, therefore compares 27 fields on a page whose table is nine rows by seven columns at the shipped state.",
  "version": "2026-10-11",
  "licence": "Use the arithmetic freely. The figures are the caller's own.",
  "method": "This file describes the page's engine. The same functions produce the page's figures and this file's worked example: the page's <script id=\"core\"> exposes compute(state) and apiOutputs(state), and apiOutputs returns exactly the outputs named below.",
  "currency": "Any single currency. The page prints a dollar sign; nothing in the arithmetic depends on the currency.",
  "rounding": {
    "money": "two decimals by round2(x) = Math.round(x * 100) / 100 on the double, which puts a half toward positive infinity rather than away from zero: -0.125 would come out as -0.12 and not -0.13. round2 is applied where each figure is defined and again to every sum, difference and quotient built from figures already rounded, so no line is worked from a longer number than the one shown. No output of this engine can be negative: the four bills are clamped at nothing, every resident's income is clamped at nothing too (see rounding.income - it is the fifth typeable box that is clamped, and it was missing from this list), every method's figure is a non-negative proportion of a non-negative total, and a gap is the larger of two such figures less the smaller, so the negative half-cent is stated here for completeness and is unreachable from this page's own controls. Each of the four bill lines is a number box whose min is 0 and whose step is 0.01, and a reader can type a negative or a sub-cent figure into it: the figure used is round2 of it, clamped at nothing, and where that is not the figure typed the page prints BOTH numbers rather than coercing in silence. The same disclosure covers childFraction: see rounding.childFraction, which is new here, because the earlier version of this clause said only that the fraction was clamped and not rounded onto its step, and left out the precision the engine actually fixes it at.",
    "counts": "whole. residents[].unit is rounded to the nearest whole and clamped into 1 to 6, and because that box is a number field a reader can type past, a figure used at anything other than what was typed is DISCLOSED: the page prints both numbers. residentCount is clamped into 1 to 10 and residents[].isChild to 0 or 1, and neither is disclosed, because both are select boxes offering only legal values: no reader can reach the coercion, and a sentence that can never print is worse than no sentence. residents[].unitRooms is disclosed too, but ONLY for the one resident of each unit the engine reads the box from (see rounding.rooms): every other resident of the same unit still has their own box clamped, with no sentence, because the figure clamped is not a figure anything uses. An earlier version of this clause promised both numbers for every count; it was true of rooms and income and false of the unit box, which printed nothing, and false of residentCount, which cannot print anything. Recorded here rather than quietly narrowed.",
    "rooms": "counted in halves by round(x / 0.5) * 0.5, clamped into 0 to 10; a figure typed off the half is used at the half. Every resident's own rooms box is clamped this way, but the page prints both numbers only for the ONE resident of each household unit whose box the engine actually reads - the first of that unit's residents in residents[].order (see inputs, residents[].unitRooms) - because every other resident of the same unit has a rooms box the engine ignores entirely, and 'this working uses W' would name a figure nothing uses. REVIEW-closing.md B-1: an earlier version of the page disclosed every resident's own clamped figure regardless of whether their box was read, which was false wherever a second resident of a unit had an off-step figure - 2,858 of 4,000 swept states, reached by moving a resident into a unit that already has an earlier resident. The rooms counted is the sum of the per-unit figures, rounded to one decimal.",
    "childFraction": "TWO decimals, by round2, and then clamped into 0 to 1: the box is a number field whose min is 0, whose max is 1 and whose step is 0.05, and a reader can type past all three, so a child's share typed as 0.333 is used as 0.33 and a share typed as 1.4 is used as 1, and in either case the page prints both numbers. It is NOT rounded onto the 0.05 step - 0.07 is used as 0.07 - and the two decimals are not cosmetic: sharesCounted is round2(adults + children x the fraction) and every weight the share column divides is built from the same fixed fraction, so the weights come to the divisor and no unit's figure under that method can be above the month's total. An earlier version of this engine fixed the fraction at FOUR decimals and published neither the four nor the two: the divisor was rounded to two decimals while each numerator carried the fraction as typed, so at 0.333 the share column footed to $1,383.82 against a month of $1,385.00 with the page calling the $1.18 a cent-rounding gap, and on a one-adult-one-child household a single unit was charged $1,388.12 of a $1,385.00 month with its share of the month printed as 100.0% to 100.2%. The four decimals were also undocumented here, so a reimplementation written from this endpoint disagreed with the page on unitOneShare, footShare and footSpread at any fraction typed to five decimals. Both halves are fixed in the engine, and this clause is the published description of it. Recorded here rather than quietly narrowed.",
    "income": "whole dollars, clamped at nothing: the box is a number field whose min is 0 and whose step is 1, and a reader can type past both, so a figure typed with cents is rounded to the nearest dollar AND A NEGATIVE IS READ AS NOTHING, and in either case the page prints both numbers - a resident's income typed as -500 is used as 0 and the page says so in the same shape of words it uses for a bill line, naming the clamp and not only the rounding: \"Monthly income, resident 1 is counted in whole dollars and is never a negative: you typed -500 and this working uses 0.\" An earlier version of that sentence named only the whole dollars, which is a rule -500 obeys, so a reader was told a rule their figure did not break beside a figure that had changed anyway; the engine's arithmetic did not change and the sentence did. The clamp is what keeps incomeCounted non-negative and every income figure inside this endpoint's identities, so it is part of the engine and not a detail of the form. An earlier version of this clause named only the cents rounding and said nothing about a negative; an agent reading it beside the page would have reproduced six fields wrongly at that state (incomeCounted, perIncomeHundred, each unit's income figure, each unit's gap, each unit's share of the month, and widestGap). Recorded here rather than quietly narrowed. An income box left EMPTY is not a zero: it is a resident whose income is not known yet, which withholds the income method entirely.",
    "percentages": "each unit's share of the month is printed to one decimal, as round(x * 10) / 10 of (the unit's figure / the month's total x 100). It is a reading of the figure beside it and nothing on the page is worked from it, so it is not pinned to a finer precision."
  },
  "inputs": [
    {
      "name": "groceries",
      "type": "number",
      "unit": "money",
      "required": false,
      "range": "0 to 3000, in steps of 0.01",
      "note": "What the house spent this month on food and drink everybody eats. The form offers 0 to 3,000 in cents; a negative is read as nothing and a larger figure is used as typed, and where the figure used is not the figure typed the page prints both. A reader who holds one monthly total for all four lines and not the breakdown puts that total here and leaves the other three at nothing: the four lines are summed on entry and no output reads any one of them apart, so the figures are identical either way."
    },
    {
      "name": "utilities",
      "type": "number",
      "unit": "money",
      "required": false,
      "range": "0 to 2000, in steps of 0.01",
      "note": "Electricity, gas and water for the month."
    },
    {
      "name": "internet",
      "type": "number",
      "unit": "money",
      "required": false,
      "range": "0 to 500, in steps of 0.01",
      "note": "The internet and a shared phone line for the month."
    },
    {
      "name": "supplies",
      "type": "number",
      "unit": "money",
      "required": false,
      "range": "0 to 600, in steps of 0.01",
      "note": "Household supplies for the month: cleaning things, bin bags, bulbs and the like. Care costs - medication, aides, equipment - are not a line of this calculation and there is nowhere to enter them."
    },
    {
      "name": "residentCount",
      "type": "integer",
      "unit": "people",
      "required": true,
      "range": "1 to 10",
      "note": "How many people live in the house. Only the first residentCount entries of residents[] are read, so every sum over residents below is a sum over those and not over every entry a request carries. A value outside 1 to 10 is clamped into it and a fraction is rounded first."
    },
    {
      "name": "childFraction",
      "type": "number",
      "unit": "a part of one share",
      "required": false,
      "range": "0 to 1, in steps of 0.05",
      "note": "The fraction of a share a child counts as in the share method. It is the family's own choice; this engine has no default view and the page recommends no value. At 1 the share method is the head method; at 0 a child counts as nothing of a share. Values outside 0 to 1 are clamped, and the page prints both numbers when the clamp bites. A value off the 0.05 step is used as typed rather than rounded onto the step, so nothing is silently moved - but it IS fixed at two decimals first, and the page prints both numbers where that moves it: 0.333 is used as 0.33, 0.07 is used as 0.07. See rounding.childFraction for why the precision is part of the arithmetic and not a detail of the display."
    },
    {
      "name": "residents[].role",
      "type": "string",
      "required": false,
      "note": "A role, not a name: Adult 1, Child 2, Resident 3. Trimmed and cut to 24 characters; blank or whitespace becomes Resident n for the row's own number. Residents are counted here and never named."
    },
    {
      "name": "residents[].unit",
      "type": "integer",
      "unit": "the household unit's number",
      "required": true,
      "range": "1 to 6",
      "note": "Which household unit the resident belongs to - the group inside the house whose money is one pot. Residents sharing a unit number are one payer with one figure between them. The box is a number field a reader can type past: a figure is rounded to the nearest whole and clamped into 1 to 6, and because moving a resident into another unit changes who shares a pot and four of the five columns, the page prints both numbers whenever the figure used is not the figure typed."
    },
    {
      "name": "residents[].isChild",
      "type": "integer",
      "unit": "0 or 1",
      "required": false,
      "range": "0 or 1",
      "note": "1 where the resident is counted as a child, which matters in the share method alone. Anything of 1 or more is read as 1 and anything less as 0."
    },
    {
      "name": "residents[].unitRooms",
      "type": "number",
      "unit": "rooms",
      "required": false,
      "range": "0 to 10, in steps of 0.5",
      "note": "How many rooms that resident's household unit occupies. It is a property of the unit, so the engine reads it from the FIRST of the unit's residents in residents[] order and ignores the field on the rest; the page shows the field on that one card only."
    },
    {
      "name": "residents[].income",
      "type": "number or empty",
      "unit": "money a month",
      "required": false,
      "range": "0 to 20000, in steps of 1",
      "note": "That resident's own monthly income. EMPTY (absent, null, or a string of spaces) means not known yet and is the one input where a blank is a state of its own: while any live resident's income is empty the income method is withheld for everybody - incomeCounted, perIncomeHundred and every income figure are null - rather than computed from the residents who have one. A resident with no income of their own is entered as 0, which is a figure. A figure typed below nothing is read as nothing and the page prints both numbers (rounding.income), so -500 here is used as 0 and the other four columns are untouched."
    }
  ],
  "outputs": [
    {
      "name": "monthTotal",
      "unit": "money",
      "formula": "round2(groceries) + round2(utilities) + round2(internet) + round2(supplies), each clamped at 0, the sum rounded to the cent"
    },
    {
      "name": "residentsCounted",
      "unit": "people",
      "formula": "residentCount, clamped into 1 to 10"
    },
    {
      "name": "unitsCounted",
      "unit": "household units",
      "formula": "the number of distinct unit numbers among the live residents"
    },
    {
      "name": "sharesCounted",
      "unit": "shares",
      "formula": "adults + children x childFraction over the live residents, rounded to 2 decimals"
    },
    {
      "name": "roomsCounted",
      "unit": "rooms",
      "formula": "the sum over units of that unit's rooms, rounded to 1 decimal"
    },
    {
      "name": "incomeCounted",
      "unit": "money a month",
      "formula": "the sum of the live residents' incomes; null when any live resident's income is empty"
    },
    {
      "name": "aHead",
      "unit": "money",
      "formula": "round2(monthTotal / residentsCounted)"
    },
    {
      "name": "aShare",
      "unit": "money",
      "formula": "round2(monthTotal / sharesCounted); null when sharesCounted is 0"
    },
    {
      "name": "aUnit",
      "unit": "money",
      "formula": "round2(monthTotal / unitsCounted)"
    },
    {
      "name": "aRoom",
      "unit": "money",
      "formula": "round2(monthTotal / roomsCounted); null when roomsCounted is 0"
    },
    {
      "name": "perIncomeHundred",
      "unit": "money",
      "formula": "round2(round2(monthTotal x 100) / incomeCounted); null when incomeCounted is null or 0. The month for each 100 of monthly income, rounded to the cent; no unit figure is worked from it"
    },
    {
      "name": "unitOneHead",
      "unit": "money",
      "formula": "for the lowest-numbered live unit: round2(monthTotal x that unit's heads / residentsCounted)"
    },
    {
      "name": "unitOneShare",
      "unit": "money",
      "formula": "for that unit: round2(monthTotal x (its adults + its children x childFraction) / sharesCounted); null when sharesCounted is 0"
    },
    {
      "name": "unitOneUnit",
      "unit": "money",
      "formula": "round2(monthTotal / unitsCounted)"
    },
    {
      "name": "unitOneIncome",
      "unit": "money",
      "formula": "for that unit: round2(monthTotal x its residents' income / incomeCounted); null when incomeCounted is null or 0"
    },
    {
      "name": "unitOneRooms",
      "unit": "money",
      "formula": "for that unit: round2(monthTotal x its rooms / roomsCounted); null when roomsCounted is 0"
    },
    {
      "name": "unitOneGap",
      "unit": "money",
      "formula": "for that unit: round2(the largest of its five figures - the smallest of them), over the figures that are not null; null where fewer than two are"
    },
    {
      "name": "unitOneLowPct",
      "unit": "percent",
      "formula": "for that unit: round1(the smallest of its figures / monthTotal x 100); null when monthTotal is 0"
    },
    {
      "name": "unitOneHighPct",
      "unit": "percent",
      "formula": "for that unit: round1(the largest of its figures / monthTotal x 100); null when monthTotal is 0"
    },
    {
      "name": "widestGap",
      "unit": "money",
      "formula": "the largest unitGap over the live units; null where no unit has one"
    },
    {
      "name": "footHead",
      "unit": "money",
      "formula": "the sum over units of round2(monthTotal x heads / residentsCounted), added as printed"
    },
    {
      "name": "footShare",
      "unit": "money",
      "formula": "the sum over units of that unit's share figure, added as printed; null when sharesCounted is 0"
    },
    {
      "name": "footUnit",
      "unit": "money",
      "formula": "unitsCounted x round2(monthTotal / unitsCounted), added as printed"
    },
    {
      "name": "footIncome",
      "unit": "money",
      "formula": "the sum over units of that unit's income figure, added as printed; null when incomeCounted is null or 0"
    },
    {
      "name": "footRooms",
      "unit": "money",
      "formula": "the sum over units of that unit's rooms figure, added as printed; null when roomsCounted is 0"
    },
    {
      "name": "footSpread",
      "unit": "money",
      "formula": "round2(the largest of the column footings - the smallest), over the footings that are not null; null where fewer than two of them are a figure. This is the figure in the footed row's own gap cell: the gap column holds one row's widest figure less its narrowest, the footed row's figures are the column footings, so its gap is their spread. It is 0 wherever every column foots to monthTotal and a cent or two where rounding leaves a column short. It is NOT widestGap, which is the largest gap any one unit sees and is the figure at the top of the page."
    },
    {
      "name": "methodsShown",
      "unit": "a count of methods",
      "formula": "how many of the five methods have a figure at this state: head (at every state, because a roster is at least one person in at least one unit), unit (the same), share (withheld where sharesCounted is 0), income (withheld where incomeCounted is null or 0) and rooms (withheld where roomsCounted is 0). It is never fewer than 2. A row's gap is taken across exactly these columns, so it is also the count the page's gap label has to say: a label naming five methods where this is 3 is a false label even though every figure under it is right. It is also the count the income-waiting warning has to say, which round 4's B-1 is: while an income box is blank the income method is withheld, so methodsShown counts exactly the four methods that read no income, and it is 4 only where share and rooms are both live. The warning's sentence says methodsShown of those 4 have a figure here; it used to say four of them did, as a fixed string, which was false at 3,400 of the generator's 4,543 states and as low as two columns against a claim of four."
    }
  ],
  "formula": [
    "monthTotal = round2(groceries + utilities + internet + supplies), each line clamped at 0 and rounded to the cent first",
    "the live residents are residents[0 .. residentCount - 1]",
    "a unit is a distinct residents[].unit among the live residents; its heads, adults and children are counts of its own residents",
    "a unit's rooms = the unitRooms of the first of its residents in residents[] order",
    "a unit's income = the sum of its residents' incomes, and is unusable while any live resident's income is empty",
    "residentsCounted = the number of live residents; unitsCounted = the number of units",
    "sharesCounted = round2(adults + children x childFraction) over the live residents",
    "roomsCounted = round1(the sum of the units' rooms)",
    "incomeCounted = the sum of the live residents' incomes, or null while any is empty",
    "per head: a unit gets round2(monthTotal x its heads / residentsCounted); a resident gets round2(monthTotal / residentsCounted)",
    "per share: a unit gets round2(monthTotal x (its adults + its children x childFraction) / sharesCounted); a resident gets round2(monthTotal x (childFraction where a child, else 1) / sharesCounted); withheld when sharesCounted is 0",
    "per unit: a unit gets round2(monthTotal / unitsCounted); a resident gets round2(monthTotal / unitsCounted / its unit's heads)",
    "by income: a unit gets round2(monthTotal x its income / incomeCounted); a resident gets round2(monthTotal x their income / incomeCounted); withheld when incomeCounted is null or 0",
    "by rooms: a unit gets round2(monthTotal x its rooms / roomsCounted); a resident gets round2(monthTotal x its unit's rooms / roomsCounted / its unit's heads); withheld when roomsCounted is 0",
    "a unit's gap = round2(the largest of its figures - the smallest), over the figures that are not withheld - which is methodsShown of them, five where every column is live and as few as two where columns are dashed",
    "a unit's share of the month = round1(its figure / monthTotal x 100), taken over the smallest and the largest of the figures that unit has and printed as that pair; where the two READINGS come out at the same tenth of a percent the page prints that one percentage instead. The condition is the two rounded readings and not the two figures behind them, which is the correction the closing round made to this clause and to the page's own glossary entry: the readings are rounded to a tenth BEFORE they are compared, so a unit whose widest and narrowest figures are half a dollar apart in a month of 6,100.00 reads 50.0% at both ends and the cell prints one percentage beside a gap of 0.51. An earlier version of this clause said the single percentage was printed where the two ends are the same figure, which is every state a row's figures are all equal in and every one-person house - true of those states and false as the only ones. unitOneLowPct and unitOneHighPct are the two readings themselves and are unaffected; it is the cell's spelling that has the two cases. Recorded here rather than quietly narrowed.",
    "each column's footing = the sum of the per-unit figures AS PRINTED, so the column foots; where that sum is not monthTotal the difference is rounding and the page prints it",
    "footSpread = the footed row's own gap, by the same rule every other row of that column uses: round2(the largest footing - the smallest). The footed row is not footed in that column, because a gap is not a quantity that adds up",
    "A DISPLAY STATE, NOT A FIELD: the page ships with a worked example in every box, so a reader who types their own four bill lines and stops has a page whose shares are about the example's household. Where ANY ONE of the four bill lines differs from the example's AND every household figure is still exactly the example's - residentCount, childFraction, and every live resident's unit, isChild, unitRooms and income, a role being a label and not a figure - the page says so in one sentence in the glance and again above the table, and marks the five glance figures that are about that household. No figure changes: the state is about whose household the figures describe. This engine's outputs are the arithmetic and carry no such flag; a caller supplying its own inputs is never in that state. An earlier version of this clause said ALL FOUR bill lines, which understated when the page speaks: the engine raises the flag on the first line that differs, which is the better behaviour, because a reader who types one figure and stops is the reader this sentence exists for. The word is corrected here rather than the engine."
  ],
  "identities": [
    "footHead equals monthTotal whenever every unit's per-head figure divides evenly at the cent; where it does not, the two differ by at most a cent for each unit and the page prints the gap. The harness asserts the bound as at most 0.01 times the number of units, which is the bound this sentence now states.",
    "the same holds for footShare, footUnit, footIncome and footRooms",
    "aShare equals aHead when childFraction is 1, because a child then counts as one whole share",
    "unitOneGap is 0 or more, and widestGap is at least unitOneGap",
    "footSpread is 0 or more, and it is 0 whenever footHead, footShare, footUnit, footIncome and footRooms are all monthTotal; it is not widestGap and the two are equal only by coincidence",
    "methodsShown is between 2 and 5, and it is the number of the five METHOD columns a unit row prints a figure in. It is not a count of every figure on that row: a unit row also prints its gap and its reading of the month, and a resident row prints its gap, so the count this field carries is the live columns and nothing else. The closing round tightened the wording; the field did not change.",
    "unitOneLowPct is at most unitOneHighPct, and both are between 0 and 100 inclusive, because no unit's figure under any method can exceed the month's total",
    "every figure this engine returns is 0 or more",
    "with one live resident, every method that HAS a figure gives that resident monthTotal and the gap is 0; a withheld column is null for them as for everybody, and the count of the methods that have a figure is methodsShown, which with one resident can still be as low as 2 - so 'every method' means every method of the methodsShown that are live, and the page's own sentence for that state names the count",
    "for each of the five methods, the per-unit weights come to that method's divisor: the heads of each unit come to residentsCounted, each unit's adults plus its children at the fraction come to sharesCounted, a weight of one per unit comes to unitsCounted, each unit's income comes to incomeCounted, and each unit's rooms come to roomsCounted. This is the identity that keeps every unit figure at or below monthTotal and every share of the month at or below 100%: a divisor fixed at a different precision from the weights divided by it breaks it, which is what round 3 found at childFraction 0.333"
  ],
  "example": {
    "note": "The state the page ships filled in: four bills, six people in two household units, a child counted as half a share, every income entered. Every figure here is what the page's own apiOutputs returns for these inputs, asserted by the page's test harness.",
    "inputs": {
      "groceries": 900,
      "utilities": 340,
      "internet": 65,
      "supplies": 80,
      "residentCount": 6,
      "childFraction": 0.5,
      "residents": [
        {
          "role": "Adult 1",
          "unit": 1,
          "isChild": 0,
          "unitRooms": 3,
          "income": 3200
        },
        {
          "role": "Adult 2",
          "unit": 1,
          "isChild": 0,
          "unitRooms": 3,
          "income": 2400
        },
        {
          "role": "Child 1",
          "unit": 1,
          "isChild": 1,
          "unitRooms": 3,
          "income": 0
        },
        {
          "role": "Child 2",
          "unit": 1,
          "isChild": 1,
          "unitRooms": 3,
          "income": 0
        },
        {
          "role": "Adult 3",
          "unit": 2,
          "isChild": 0,
          "unitRooms": 2,
          "income": 1450
        },
        {
          "role": "Adult 4",
          "unit": 2,
          "isChild": 0,
          "unitRooms": 2,
          "income": 980
        },
        {
          "role": "Adult 5",
          "unit": 3,
          "isChild": 0,
          "unitRooms": 1,
          "income": 0
        },
        {
          "role": "Adult 6",
          "unit": 3,
          "isChild": 0,
          "unitRooms": 1,
          "income": 0
        },
        {
          "role": "Adult 7",
          "unit": 4,
          "isChild": 0,
          "unitRooms": 1,
          "income": 0
        },
        {
          "role": "Child 3",
          "unit": 4,
          "isChild": 1,
          "unitRooms": 1,
          "income": 0
        }
      ]
    },
    "outputs": {
      "monthTotal": 1385,
      "residentsCounted": 6,
      "unitsCounted": 2,
      "sharesCounted": 5,
      "roomsCounted": 5,
      "incomeCounted": 8030,
      "aHead": 230.83,
      "aShare": 277,
      "aUnit": 692.5,
      "aRoom": 277,
      "perIncomeHundred": 17.25,
      "unitOneHead": 923.33,
      "unitOneShare": 831,
      "unitOneUnit": 692.5,
      "unitOneIncome": 965.88,
      "unitOneRooms": 831,
      "unitOneGap": 273.38,
      "unitOneLowPct": 50,
      "unitOneHighPct": 69.7,
      "widestGap": 273.38,
      "footHead": 1385,
      "footShare": 1385,
      "footUnit": 1385,
      "footIncome": 1385,
      "footRooms": 1385,
      "footSpread": 0,
      "methodsShown": 5
    }
  },
  "not_covered": [
    "Whether a bill was shared at all. A parcel that is one person's own has nowhere to go here, and the page divides whatever is typed on its four lines.",
    "Care costs of any kind - medication, aides, equipment, a paid helper - which are not a line of this calculation.",
    "Anything a household agreed before this month, any debt between its members, and any arrears from an earlier month. This engine prices one month and keeps no running account.",
    "What anybody can afford. An income figure is a figure, not a judgment.",
    "A month somebody was away, a one-off repair, and somebody moving in halfway through the month. All three are a month's bills divided by a roster that changed, and this engine takes one roster.",
    "Tax of every kind. This is not a tax calculation and it computes nothing about anybody's tax."
  ],
  "no_advice": "Arithmetic on the figures the caller types, under a method the caller chooses. The engine recommends no method, makes no judgment about how a household ought to divide its bills, and is not advice."
}
