Writes each priced item's material and labor rates as a price table another app can read.
How the precision is kept
Rates are whole 1 ÷ 10000 dollars in the takeoff. For the table they are divided by 10000, converted to the table's unit and rounded to 6 decimals. For units that convert by 1 the rounding changes nothing; for a rate per square yard it does.
Open item. Keep the converted rate unrounded in the price table; rounding a per-square-yard rate ÷ 9 to 6 decimals changes it by up to half a millionth of a dollar per square foot.
Calculations under this policy
2 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
One table row per priced item, with its material rate, labor rate and waste.
rate = round(rate4 ÷ 10000 × factor × 10⁶) ÷ 10⁶
mat and lab are rate4 ÷ 10000 × factor, then Math.round(… × 1e6) ÷ 1e6. A whole-cent or 4-decimal rate with factor 1 is unchanged by this; a per-square-yard rate becomes a rounded ninth. Waste is basis points ÷ 10000 clamped to 0 … 5.
carbon.js
lines 95 to 112
TakeoffCraft 0.8.1
export function priceRows(est, items) {
const rows = [], skipped = [], seen = new Set();
const nameOf = new Map((items || []).map((i) => [i.id, i.name]));
for (const r of est.rows) {
if ((r.kind !== 'item' && r.kind !== 'condition') || r.error) continue;
const name = nameOf.get(r.itemId) || r.name;
const label = r.kind === 'condition' ? name + ' ' + r.type : name;
const u = PRICE_UNIT[r.unit];
const mat = (Number(r.mat) || 0) / 10000, lab = (Number(r.lab) || 0) / 10000;
if (!u) { skipped.push({ name: label, why: 'unit' }); continue; }
if (!(mat > 0 || lab > 0)) { skipped.push({ name: label, why: 'norate' }); continue; }
let id = slug(label), n = 2;
while (seen.has(id)) id = slug(label).slice(0, 52) + '-' + n++;
seen.add(id);
rows.push({ id, match: [norm(name).slice(0, 60)].filter(Boolean), classes: [], unit: u[0], density: null, mat: Math.round(mat * u[1] * 1e6) / 1e6, lab: Math.round(lab * u[1] * 1e6) / 1e6, waste: Math.min(5, Math.max(0, (Number(r.waste) || 0) / 10000)), source: 'TakeoffCraft rates', note: '' });
}
return { rows: rows.filter((x) => x.match.length), skipped };
}
In detail
Method
dollars = rate4 ÷ 10000; per-unit conversion × 1, × 1 ÷ 9 (square yard to square foot) or × 1 ÷ 100 (roofing square to square foot); rounded to 6 decimals; waste = basis points ÷ 10000, kept between 0 and 5.
Number types
64-bit numbers; the rates start as integers.
Limits
A rate per square yard divided by 9 is rounded to the nearest 0.000001 dollar. Acres and hectares have no entry in the table's units and are left out with the reason 'unit'.
Approach: 64-bit, direct
Every value is a 64-bit number from input to result. Formulas are closed form or a direct solve, and every comparison uses a stated tolerance.