1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[82586],{82586:(e,t,s)=>{s.r(t),s.d(t,{GREASE_OPENING:()=>q,_everyFixtureIsOwned:()=>B,addressCarriesOwnState:()=>H,buildGreaseShare:()=>_,default:()=>K,restoreFromShare:()=>W});var a=s(95155),n=s(12115),i=s(33789),o=s(33534),l=s(16110),r=s(69869),d=s(49480),h=s(12513),u=s(27784);let m=[1,2],c={lowGpm:10,highGpm:100},p=[{key:"potSink",label:"Three compartment pot sink",dfu:3,hint:"the main wash, rinse and sanitize sink"},{key:"dishwasher",label:"Commercial dishwasher",dfu:4,hint:"a door type or conveyor machine, not a domestic unit"},{key:"mopSink",label:"Mop or service sink",dfu:3,hint:"the floor mounted janitorial basin"},{key:"floorDrain",label:"Floor drain, 2 inch",dfu:2,hint:"count every one that drains kitchen floor area"},{key:"prepSink",label:"Food prep sink",dfu:2,hint:"a vegetable or produce sink, separate from the pot sink"}],g=[{minDfu:1,maxDfu:8,gallons:500},{minDfu:9,maxDfu:21,gallons:750},{minDfu:22,maxDfu:35,gallons:1e3},{minDfu:36,maxDfu:90,gallons:1250},{minDfu:91,maxDfu:172,gallons:1500},{minDfu:173,maxDfu:216,gallons:2e3},{minDfu:217,maxDfu:307,gallons:2500}],f=Math.max(...g.map(e=>e.maxDfu)),x=Math.max(...g.map(e=>e.gallons)),b=[30,45,60],y=b[0],w=[{key:"standard",label:"Standard commercial restaurant, 5 gallons a meal",gallonsPerMeal:5},{key:"fastfood",label:"Fast food or limited service, 2.5 gallons a meal",gallonsPerMeal:2.5}],v=[{key:"dishwasher-and-disposal",label:"Commercial dishwasher and a garbage disposal",factor:1.25},{key:"dishwasher-only",label:"Commercial dishwasher, no disposal",factor:1},{key:"neither",label:"No dishwasher and no disposal",factor:.75}],j=["The minimum interceptor size your own sewer authority enforces. The Uniform Plumbing Code floor for an outdoor gravity interceptor is 500 gallons, the published research says many municipalities raise that to 1,000, and it does not say which ones. That figure is an input on this page because guessing it is the difference between a tank that gets signed off and one that gets dug back up.","Which of the published methods your authority applies. They are all real, they are all in force somewhere, and on one ordinary restaurant they disagree by a factor of about ten. Nothing on this page can tell you which one your plan checker opens.","Whether any size is code compliant. This page never says that about anything, no matter how many boxes are filled in.","A model number or a specific certified unit. A hydromechanical interceptor is certified to ASME A112.14.3 or PDI-G101 at a rated flow, and the published research names only four points on that ladder, so this page reports the rating you need rather than pretending to know the catalog above it.","How often the interceptor has to be pumped out. Authorities set pump-out frequency separately from size, often as a percentage of grease capacity, and they enforce it with records.","Whether a hydromechanical unit is allowed here at all. Plenty of districts require an outdoor gravity tank for any full service kitchen regardless of what the fixture arithmetic says, and that is a policy decision rather than a calculation.","A drainage fixture unit value for any fixture outside the five published ones counted here. A wok range, a rotisserie, a hand sink or a can wash all drain, and inventing a DFU for them would be inventing a code value.","The peak operational flow the IPC volumetric method asks for. This page substitutes the fixture drain-down flow and says so, because the conversion table a plan checker uses is not in its source.","Anything about a grease removal device, an automatic skimmer, or a chemical or biological dosing system. Those are sized by their manufacturers against test data that is not published here."],N={minBayInches:1,maxBayInches:120,maxBays:8,maxFixtureCount:99,maxSeats:2e3,maxHoursPerDay:24,maxLocalMinimumGallons:1e5};function k(e,t){let s=10**t;return Math.round(e*s)/s}let $=e=>null==e,P=e=>null==e||!Number.isFinite(e),M=e=>"number"!=typeof e||!Number.isFinite(e)||!Number.isInteger(e)||e<0||e>N.maxFixtureCount?null:e,G=e=>
1`${k(e,1).toLocaleString()} gallons`;function T(e){return $(e)?null:Number.isFinite(e)?e<=0?"A minimum interceptor size has to be above zero gallons. Leave the box empty if you have not asked your authority yet.":e>N.maxLocalMinimumGallons?`A local minimum above ${N.maxLocalMinimumGallons.toLocaleString()} gallons is larger than any published municipal floor, so check the figure and the units before entering it again.`:null:"The minimum your authority publishes has to be a number of gallons."}let C={computed:!1,totalCubicInches:0,totalGallons:0,effectiveGallons:0,drainDownGpm:0,capFloorGpm:0,requiredGpm:0,governedBy:"none",requiredPounds:0,cappedFixtureGallons:0},D="This page will not tell you what size interceptor to install, because the sewer authority that has to accept it sets its own minimum, that minimum governs whatever the arithmetic says, and so their figure is an input here rather than something estimated in its place. It runs four published methods and they disagree, on one ordinary hundred seat restaurant by about ten to one, which is the most useful thing it can show you and also the reason no free page can hand you a single number. A hydromechanical interceptor rated in gallons a minute and a gravity interceptor rated in gallons of holding volume are different products tested to different standards, so the two halves of this page are never added together and a figure from one of them is not a size for the other. Two figures here are assumptions rather than published values and both are named where they are used: the peak flow feeding the IPC method is this page substituting the fixture drain-down flow because its source never says how to obtain one, and the point at which two methods count as disagreeing is a threshold this page chose, which changes only which sentence gets printed. Nothing on this page ever says a sizing is compliant, no combination of inputs will make it say so, and the plan checker who signs the drawings is the only person who can.",F="toolbreezy:grease-interceptor-calculator",I="flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",S=e=>""===e.trim()?null:(0,d.jO)(e),E=e=>k(e,1).toLocaleString(void 0,{maximumFractionDigits:1}),A=e=>k(e,2).toLocaleString(void 0,{maximumFractionDigits:2}),L={1:"One minute, which needs the larger interceptor",2:"Two minutes"},U={30:"30 minutes, the model code minimum",45:"45 minutes, a common local amendment",60:"60 minutes, for a high grease kitchen"},O={"drain-down":"the drain-down calculation","volumetric-cap":"the UPC 1014.2.1 volumetric cap"},z="unanswered",R=["bl","bw","bd","bc","dp","rt","st","hr","wf","lf","lm","f_potSink","f_dishwasher","f_mopSink","f_floorDrain","f_prepSink"],B=!0;function H(e){return(0,r.Yc)(new URLSearchParams(e.replace(/^\?/,"")),R)}let q={len:"",wid:"",dep:"",bays:"3",drain:z,counts:{},retention:z,seats:"",hours:"",waste:z,loading:z,localMin:""},_=e=>{let t=(e=>({bl:e.len||null,bw:e.wid||null,bd:e.dep||null,bc:e.bays||null,dp:e.drain,rt:e.retention,st:e.seats||null,hr:e.hours||null,wf:e.waste,lf:e.loading,lm:e.localMin||null,f_potSink:e.counts.potSink||null,f_dishwasher:e.counts.dishwasher||null,f_mopSink:e.counts.mopSink||null,f_floorDrain:e.counts.floorDrain||null,f_prepSink:e.counts.prepSink||null}))(e);return(0,r.CZ)(R.map(e=>({key:e,value:t[e]})))};function W(e){if(!(0,r.Yc)(e,R))return null;let t=(t,s)=>(e.get(t)??"").slice(0,s),s=(t,s)=>{let a=e.get(t);return null===a?z:a.slice(0,s)},a={};for(let t of p){let s=e.get(`f_${t.key}`);null!==s&&(a[t.key]=s.slice(0,3))}return{len:t("bl",10),wid:t("bw",10),dep:t("bd",10),bays:t("bc",3),drain:s("dp",12),counts:a,retention:s("rt",12),seats:t("st",8),hours:t("hr",6),waste:s("wf",24),loading:s("lf",32),localMin:t("lm",10)}}function K(){let[e,t]=(0,n.useState)(""),[s,r]=(0,n.useState)(""),[d,R]=(0,n.useState)(""),[B,q]=(0,n.useState)("3"),[K,Y]=(0,n.useState)(z),[V,Z]=(0,n.useState)({}
1),[J,Q]=(0,n.useState)(z),[X,ee]=(0,n.useState)(""),[et,es]=(0,n.useState)(""),[ea,en]=(0,n.useState)(z),[ei,eo]=(0,n.useState)(z),[el,er]=(0,n.useState)("");(0,n.useEffect)(()=>{let e=new URLSearchParams(window.location.search);if(H(window.location.search)){let s=W(e);t(s.len),r(s.wid),R(s.dep),q(s.bays),Y(s.drain),Q(s.retention),ee(s.seats),es(s.hours),en(s.waste),eo(s.loading),er(s.localMin),Z(s.counts);return}let s=(0,h.y5)(F);if(s.found){t(s.str("bl","",10)),r(s.str("bw","",10)),R(s.str("bd","",10)),q(s.str("bc","3",3)),Y(s.str("dp",z,12)),Q(s.str("rt",z,12)),ee(s.str("st","",8)),es(s.str("hr","",6)),en(s.str("wf",z,24)),eo(s.str("lf",z,32)),er(s.str("lm","",10));let e=s.obj("fx"),a={};for(let t of p){let s=e.str(t.key,"",3);""!==s&&(a[t.key]=s)}Z(a)}},[]),(0,u.Vd)(F,()=>JSON.stringify({bl:e,bw:s,bd:d,bc:B,dp:K,rt:J,st:X,hr:et,wf:ea,lf:ei,lm:el,fx:V}),[e,s,d,B,K,J,X,et,ea,ei,el,V],{debounceMs:250});let ed=(0,n.useMemo)(()=>{let e={};for(let t of p){let s=V[t.key];void 0!==s&&""!==s.trim()&&(e[t.key]=S(s))}return e},[V]),eh=(0,n.useMemo)(()=>(function(e){let t=function(e){let t,s=[],a=[],n=(t=e.drainPeriodMinutes,m.includes(t)?t:null);$(e.drainPeriodMinutes)||null!==n||a.push("The drain-down window was not one this page recognizes, so it has been cleared. Choose one minute or two minutes again.");let i=e=>({...C,drainPeriodMinutes:n,notes:s,missing:a,problem:e});for(let[t,s]of[["inside length",e.bayLengthIn],["inside width",e.bayWidthIn],["inside depth",e.bayDepthIn]])if(P(s))a.push(`Measure the ${t} of one sink compartment, in inches, on the inside.`);else if(s<N.minBayInches||s>N.maxBayInches)return i(`A sink compartment ${t} of ${s} inches is outside the ${N.minBayInches} to ${N.maxBayInches} inch range this page will read, and ${N.maxBayInches} inches is ${N.maxBayInches/12} feet. Measure the inside of one compartment rather than the whole sink unit, and check that the figure is in inches.`);let o=M(e.bayCount);if($(e.bayCount))a.push("Say how many compartments the sink has.");else if(null===o||o<1||o>N.maxBays)return i(`The compartment count has to be a whole number from 1 to ${N.maxBays}. A commercial pot sink is normally two, three or four compartments, and this page treats every compartment as the same size.`);if(null===n&&$(e.drainPeriodMinutes)&&a.push("Choose the drain-down window. One minute demands a larger interceptor than two minutes, because the same water has to pass in half the time."),a.length>0)return i(null);let l=e.bayLengthIn,r=e.bayWidthIn,d=l*r*e.bayDepthIn*o,h=d/231,u=.75*h,p=u/n,g=h/2.5,f=g>p,x=f?g:p,b=2*x;return s.push(`The compartments hold ${G(h)} between them and the code assumes ${Math.round(75)} percent of that drains, so ${G(u)} has to pass in ${n} ${1===n?"minute":"minutes"}.`),f?(s.push(`The drain-down calculation on its own asks for ${k(p,2)} GPM. UPC 1014.2.1 separately caps the fixture volume feeding an interceptor at 2.5 times its rated flow, which for ${G(h)} of sink means the unit cannot be rated below ${k(g,2)} GPM. The cap is the binding figure here, so ${k(x,2)} GPM is the number to shop against.`),s.push(`That is not a quirk of your sink. At a two minute window the formula returns 0.375 times the fixture volume while the cap needs ${k(.4,3)} times it, so the cap outranks the calculation by ${k(1.0666666666666667,4)} on every two minute sizing there has ever been. The published example this page was built from misses it, specifying a 35 GPM unit for a sink holding 89.77 gallons when 35 GPM legally tops out at 87.5.`)):s.push(`At a ${n} minute window the drain-down figure of ${k(p,2)} GPM already clears the UPC 1014.2.1 volumetric cap, which would only require ${k(g,2)} GPM. The cap starts to bind above a drain window of 1.875 minutes.`),s.push(`A unit certified to ASME A112.14.3 or PDI-G101 carries a grease capacity of exactly twice its rated flow, so a ${k(x,2)} GPM rating comes with ${k(b,2)} pounds of capacity. Buy at or above the rating rather than at the nearest number below it.`),x>c.highGpm&&s.push(`${k(x,2)} GPM is past the ${c.lowGpm} to ${c.highGpm} GPM span the published research gives for hydromechanical units, which is where the source puts the work onto an outdoor gravity tank instead. Read the gallon methods below rather than this one.`),{computed:!0,totalCubicInches:d,totalGallons:h,effectiveGallons:u,drainPeriodMinutes:n,drainDownGpm:p,capFloorGpm:g,requiredGpm:x,governedBy:f?"volumetric-cap":"drain-down",requiredPounds:b,cappedFixtureGallons:2.5*x,notes:s,missing:a,problem:null}}(e),s=function(e){let t=[],s=[],a=[],n=e=>({computed:!1,lines:a,totalDfu:0,gallons:0,band:null,notes:t,missing:s,problem:e}),i=0;for(let t of p){let s=e[t.key];if($(s))continue;let o=M(s);if(null===o)return n(`The count for "${t.label}" has to be a whole number from 0 to ${N.maxFixtureCount}.`);if(0===o)continue;let l=o*t.dfu;i+=l,a.push({key:t.key,label:t.label,count:o,dfuEach:t.dfu,dfuTotal:l})}if(0===i)return s.push("Count the fixtures that drain into the interceptor. The published table starts at one drainage fixture unit, so nothing is worked out until at least one fixture is entered."),n(null);if(i>f)return n(`${i} drainage fixture units is past the ${f} unit end of UPC Table 1014.3.6, which is where the published table stops. There is no row above it to read, and extrapolating one would mean inventing a code value, so a facility this size needs a plumbing engineer rather than a web page.`);let o=g.find(e=>i>=e.minDfu&&i<=e.maxDfu)??null;return null===o?n(`No row of UPC Table 1014.3.6 covers ${i} drainage fixture units, which should not be possible and means this page has a transcription error in its table. Do not use any figure from this section.`):(t.push(`${i} drainage fixture units falls in the ${o.minDfu} to ${o.maxDfu} unit row, which sets a minimum gravity interceptor of ${G(o.gallons)}.`),t.push("Only the five fixtures the published research names are counted here, so a kitchen with a wok range, a rotisserie, a hand sink or a can wash has drainage this page cannot see. Treat the total as a floor on your real fixture unit load rather than as the load itself."),500===o.gallons&&t.push(`${G(500)} is also the structural floor UPC puts under any outdoor gravity interceptor, so this row is the smallest tank the model code contemplates rather than a size worked out for your kitchen.`),{computed:!0,lines:a,totalDfu:i,gallons:o.gallons,band:o,notes:t,missing:s,problem:null})}(e.fixtureCounts??{}),a=function(e,t){let s=[],a=[],n=b.includes(e)?e:null;$(e)||null!==n||a.push("The retention time was not one this page recognizes, so it has been cleared. Choose 30, 45 or 60 minutes again.");let i=e=>({computed:!1,peakFlowGpm:0,retentionMinutes:n,gallons:0,atEachRetention:[],notes:s,missing:a,problem:e});if(!t.computed||null!==t.problem)return a.push("Fill in the sink measurements above first. This method multiplies a peak flow by a retention time, and the only flow on this page comes from the fixture drain-down."),i(null);if(null===n)return a.push("Choose a retention time. The model code minimum is 30 minutes."),i(null);let o=t.requiredGpm,l=o*n,r=b.map(e=>({minutes:e,gallons:o*e}));return s.push(`${k(o,2)} GPM held for ${n} minutes is ${G(l)} of liquid volume. This is a gravity tank figure and it has nothing in common with the GPM rating above, which describes a different device.`),s.push("The IPC volumetric method needs a peak operational flow and the published answer behind this page never says how to obtain one, so the flow used here is the fixture drain-down flow worked out above. A plan checker may instead convert the whole building drainage fixture unit load into a flow through a conversion table, which is a different number."),n===y&&s.push(`30 minutes is the model code MINIMUM rather than a recommendation, so this is the smallest tank the IPC method produces for your flow. Local amendments raise it to 45 or 60 minutes for a high grease kitchen or one with a garbage disposal, which would give ${G(45*o)} and ${G(60*o)} instead.`),l<500&&s.push(`${G(l)} is under the ${G(500)} structural floor UPC puts on an outdoor gravity interceptor, so the arithmetic has stopped being the thing that decides. The floor governs, and
1your own authority may set it higher still.`),{computed:!0,peakFlowGpm:o,retentionMinutes:n,gallons:l,atEachRetention:r,notes:s,missing:a,problem:null}}(e.retentionMinutes,t),n=function(e){let t,s,a=[],n=[],i=(t=e.wasteFlowKey,w.find(e=>e.key===t)??null),o=(s=e.loadingFactorKey,v.find(e=>e.key===s)??null);$(e.wasteFlowKey)||null!==i||n.push("The service type was not one this page recognizes, so it has been cleared. Choose it again."),$(e.loadingFactorKey)||null!==o||n.push("The kitchen equipment answer was not one this page recognizes, so it has been cleared. Choose it again.");let l=e=>({computed:!1,seats:0,hoursPerDay:0,wasteFlow:i,loading:o,gallons:0,notes:a,missing:n,problem:e});if(P(e.seats))n.push("Enter the legal seating capacity of the dining room.");else if(e.seats<=0||e.seats>N.maxSeats)return l(`Seating has to be from 1 to ${N.maxSeats.toLocaleString()} seats. This formula multiplies seats by hours, so a mistyped seat count moves the tank size by the same multiple it was mistyped by.`);if(P(e.hoursPerDay))n.push("Enter how many hours a day the kitchen is open.");else if(e.hoursPerDay<=0||e.hoursPerDay>N.maxHoursPerDay)return l(`Hours of operation have to be above zero and at or below ${N.maxHoursPerDay}, because a day has ${N.maxHoursPerDay} hours in it.`);if($(e.wasteFlowKey)&&n.push("Choose whether this is a standard restaurant or a limited service kitchen."),$(e.loadingFactorKey)&&n.push("Say whether there is a commercial dishwasher and a garbage disposal."),n.length>0)return l(null);let r=e.seats,d=e.hoursPerDay,h=r*d*i.gallonsPerMeal*o.factor;return a.push(`${r.toLocaleString()} seats over ${d} hours at ${i.gallonsPerMeal} gallons a meal, multiplied by a loading factor of ${o.factor}, gives ${G(h)}.`),a.push("This formula is not in the IPC or UPC text. It comes out of municipal Fats, Oils and Grease ordinances and it exists for restaurants that do not have finished plumbing drawings yet, so a jurisdiction that sizes off the fixture unit table has never used it."),h<500&&a.push(`${G(h)} is under the ${G(500)} structural floor UPC puts on an outdoor gravity interceptor, so the floor governs rather than this arithmetic.`),{computed:!0,seats:r,hoursPerDay:d,wasteFlow:i,loading:o,gallons:h,notes:a,missing:n,problem:null}}(e),i=function(e,t,s){let a,n=[];if(e.computed&&n.push({key:"dfu",name:"Fixture units against the published table",code:"UPC Table 1014.3.6",gallons:e.gallons}),t.computed&&n.push({key:"retention",name:"Peak flow held for the retention time",code:"IPC 1003.3.6",gallons:t.gallons}),s.computed&&n.push({key:"meals",name:"Seats, hours and a loading factor",code:"a municipal FOG ordinance",gallons:s.gallons}),0===n.length)return null;let i=n.reduce((e,t)=>t.gallons<e.gallons?t:e),o=n.reduce((e,t)=>t.gallons>e.gallons?t:e),l=0===i.gallons?1:o.gallons/i.gallons,r=n.length>1&&l>=1.5;return a=1===n.length?`Only one gallon method has enough input to run, giving ${G(i.gallons)} by ${i.code}. Fill in the other sections before you lean on that figure, because the methods routinely disagree with each other and one number on its own hides that.`:r?`These methods do not agree about your kitchen. The smallest is ${G(i.gallons)} from ${i.code} and the largest is ${G(o.gallons)} from ${o.code}, a spread of ${k(l,2)} to one. All of them are published, all of them are in force somewhere, and which one applies to you is decided by the authority that has to accept the installation.`:`The methods land close together on your kitchen, from ${G(i.gallons)} by ${i.code} to ${G(o.gallons)} by ${o.code}. That agreement is worth having and it still does not tell you which method your own authority applies.`,{entries:n,lowest:i,highest:o,spreadRatio:l,materialDisagreement:r,headline:a}}(s,a,n),o=T(e.localMinimumGallons),l=function(e,t){if(null===t||$(e)||null!==T(e))return null;let s=[],a=Math.max(e,500),n=Math.max(a,t.lowest.gallons),i=Math.max(a,t.highest.gallons),o=a>=t.lowest.gallons;e<500?s.push(`You entered a local minimum of ${G(e)}, which is under the ${G(500)} structural floor the Uniform Plumbing Code puts on an outdoor gravity interceptor. Both figures are shown and the larger one is used below. Check the local number before you rely on it, because an authority allowing a smaller tank than the model code is unusual enough to be worth confirming in writing.`):e>500&&s.push(`Your authority's ${G(e)} minimum is above the ${G(500)} model code floor, which is common. Theirs is the one that governs.`),o&&s.push(`The floor rather than any calculation sets the bottom of this band. Every method that came out under ${G(a)} has been raised to it, so the arithmetic below that point is not what decides your tank.`),1===t.entries.length&&s.push("O
1nly one of the gallon methods has run, so this band rests on a single route to the answer. Fill in the other sections before you take it anywhere."),s.push("This band is a starting point for a conversation with your sewer authority and a licensed plumber, and it is not a specification. Nothing here says any size is compliant. Plans get signed off by an inspector or a licensed professional before equipment is bought, and a tank that has already been delivered is an expensive thing to be wrong about.");let l=n===i?`Every published method that ran, raised to your authority's floor, lands on ${G(n)}. Take that figure to them rather than treating it as settled.`:`Once your authority's floor is applied, the published methods span ${G(n)} to ${G(i)}. Which end applies is their decision rather than this page's, so take both numbers to them.`;return{localMinimumGallons:e,modelCodeMinimumGallons:500,floorGallons:a,bandLowGallons:n,bandHighGallons:i,lowMethod:t.lowest,highMethod:t.highest,floorGovernsLowEnd:o,notes:s,headline:l}}(e.localMinimumGallons,i),r=t.problem??s.problem??a.problem??n.problem??o??null;return{hgi:t,dfu:s,retention:a,meals:n,comparison:i,gravity:l,awaitingLocalMinimum:null!==i&&null===l,problem:r}})({bayLengthIn:S(e),bayWidthIn:S(s),bayDepthIn:S(d),bayCount:S(B),drainPeriodMinutes:K===z?null:Number(K),fixtureCounts:ed,retentionMinutes:J===z?null:Number(J),seats:S(X),hoursPerDay:S(et),wasteFlowKey:ea===z?null:ea,loadingFactorKey:ei===z?null:ei,localMinimumGallons:S(el)}),[e,s,d,B,K,ed,J,X,et,ea,ei,el]),{hgi:eu,dfu:em,meals:ec,comparison:ep,gravity:eg}=eh,ef=["GREASE INTERCEPTOR SIZING","","HYDROMECHANICAL INTERCEPTOR, RATED IN GALLONS A MINUTE","UPC 1014.2 and IPC 1003.3.5, unit certified to ASME A112.14.3 or PDI-G101",eu.computed?`Fixture volume ${E(eu.totalGallons)} gallons 2Drains at ${Math.round(75)} percent ${E(eu.effectiveGallons)} gallons 3Drain-down window ${eu.drainPeriodMinutes} min 4Drain-down needs ${A(eu.drainDownGpm)} GPM 5Volumetric cap needs ${A(eu.capFloorGpm)} GPM 6RATING REQUIRED ${A(eu.requiredGpm)} GPM (set by ${O[eu.governedBy]??"the larger of the two rules"}) 7Grease capacity ${A(eu.requiredPounds)} lb`:eu.missing.map(e=>`STILL NEEDED: ${e}`).join("\n"),eu.problem?`PROBLEM: ${eu.problem}`:"",...eu.computed?eu.notes.map(e=>`NOTE: ${e}`):[],"","GRAVITY INTERCEPTOR, RATED IN GALLONS OF HOLDING VOLUME",em.computed?`Fixture units, UPC Table 1014.3.6 ${em.totalDfu} DFU -> ${E(em.gallons)} gallons`:em.missing.map(e=>`STILL NEEDED: ${e}`).join("\n"),em.problem?`PROBLEM: ${em.problem}`:"",eh.retention.computed?`Flow x retention, IPC 1003.3.6 ${A(eh.retention.peakFlowGpm)} GPM x ${eh.retention.retentionMinutes} min -> ${E(eh.retention.gallons)} gallons`:eh.retention.missing.map(e=>`STILL NEEDED: ${e}`).join("\n"),ec.computed?`Seats x hours, municipal FOG ${ec.seats} seats x ${ec.hoursPerDay} h -> ${E(ec.gallons)} gallons`:ec.missing.map(e=>`STILL NEEDED: ${e}`).join("\n"),ec.problem?`PROBLEM: ${ec.problem}`:"","",ep?ep.headline:"","",eg?[eg.headline,`Your authority's minimum ${E(eg.localMinimumGallons)} gallons`,`UPC model code floor ${E(eg.modelCodeMinimumGallons)} gallons`,`Band after the floor ${E(eg.bandLowGallons)} to ${E(eg.bandHighGallons)} gallons`,...eg.notes.map(e=>`NOTE: ${e}`)].join("\n"):"NO SIZE GIVEN: enter the minimum your own sewer authority publishes. This page will not guess it.",eh.problem?`PROBLEM: ${eh.problem}`:"","","WHAT THIS PAGE WILL NOT WORK OUT",...j.map(e=>` - ${e}`),"",D].filter(e=>""!==e).join("\n");return(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsxs)("div",{className:"rounded-lg border border-destructive/50 bg-destructive/5 p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"Read this before you enter anything, because it changes what the numbers below are for"}),(0,a.jsxs)("p",{className:"mt-2 text-sm text-muted-foreground",children:["Your local sewer authority sets its own minimum interceptor size and that minimum governs whatever any calculation says. The Uniform Plumbing Code floor for an outdoor gravity interceptor is ",500," gallons and plenty of districts enforce double that, so this page takes their figure as an input and gives you no size at all until you have it. Everything above that box is model code arithmetic, which is a starting point for a conversation with them rather than a specification you can buy against."]})]}),(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"The sink, which sizes a hydromechanical interceptor in gallons a minute"}),(0,a.jsx)("p",{className:"mt-2 text-sm text-muted-foreground",children:"Measure one compartment on the inside, and this page treats every compartment as that same size. UPC 1014.2 and IPC 1003.3.5 share this calculation, and the unit you end up buying is certified to ASME A112.14.3 or PDI-G101 at a rated flow."}),(0,a.jsxs)("div",{className:"mt-4 grid gap-4 sm:grid-cols-2",children:[(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-bl",children:"Compartment length"}),(0,a.jsx)(i.p,{id:"gi-bl",inputMode:"decimal",className:"font-mono",value:e,onCh
7ange:e=>t(e.target.value)}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"inches, measured inside"})]}),(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-bw",children:"Compartment width"}),(0,a.jsx)(i.p,{id:"gi-bw",inputMode:"decimal",className:"font-mono",value:s,onChange:e=>r(e.target.value)}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"inches, measured inside"})]}),(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-bd",children:"Compartment depth"}),(0,a.jsx)(i.p,{id:"gi-bd",inputMode:"decimal",className:"font-mono",value:d,onChange:e=>R(e.target.value)}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"inches, from the bottom to the overflow rim"})]}),(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-bc",children:"How many compartments"}),(0,a.jsx)(i.p,{id:"gi-bc",inputMode:"numeric",className:"font-mono",value:B,onChange:e=>q(e.target.value)}),(0,a.jsxs)("p",{className:"text-xs text-muted-foreground",children:["1 to ",N.maxBays,", all the same size"]})]}),(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-dp",children:"Drain-down window"}),(0,a.jsxs)("select",{id:"gi-dp",className:I,value:K,onChange:e=>Y(e.target.value),children:[(0,a.jsx)("option",{value:z,children:"Pick one before anything else"}),m.map(e=>(0,a.jsx)("option",{value:String(e),children:L[e]},e))]}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"how long the full sink is allowed to take to empty"})]})]}),null!==eu.problem&&(0,a.jsx)("p",{className:"mt-4 rounded-md border border-destructive/50 bg-destructive/5 p-3 text-sm",children:eu.problem}),eu.missing.length>0&&(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:eu.missing.map(e=>(0,a.jsx)("li",{children:e},e))}),eu.computed&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"mt-4 space-y-1 text-sm",children:[(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"Fixture volume"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(eu.totalGallons)," gallons"]})]}),(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"What the code assumes actually drains"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(eu.effectiveGallons)," gallons"]})]}),(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"The drain-down calculation asks for"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[A(eu.drainDownGpm)," GPM"]})]}),(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"The UPC 1014.2.1 volumetric cap asks for"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[A(eu.capFloorGpm)," GPM"]})]}),(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1 font-medium",children:[(0,a.jsxs)("span",{children:["Rated flow to shop against, set by"," ",O[eu.governedBy]??"the larger of the two rules"]}),(0,a.jsxs)("span",{className:"tabular-nums",children:[A(eu.requiredGpm)," GPM"]})]}),(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"Grease capacity that comes with it"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[A(eu.requiredPounds)," pounds"]})]})]}),(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:eu.notes.map(e=>(0,a.jsx)("li",{children:e},e))})]})]}),(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"The fixtures, which size a gravity interceptor in gallons"}),(0,a.jsx)("p",{className:"mt-2 text-sm text-muted-foreground",children:"A different device measured in a different unit. Count what drains into it, and UPC Table 1014.3.6 turns the fixture unit total into a minimum tank volume. Only the five fixtures the published source names are counted, so a kitchen with a wok range or a can wash has drainage this page cannot see."}),(0,a.jsx)("div",{className:"mt-4 grid gap-4 sm:grid-cols-2",children:p.map(e=>(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:`gi-f-${e.key}`,children:e.label}),(0,a.jsx)(i.p,{id:`gi-f-${e.key}`,inputMode:"numeric",className:"font-mono",value:V[e.key]??"",onChange:t=>Z(s=>({...s,[e.key]:t.target.value}))}),(0,a.jsxs)("p",{className:"text-xs text-muted-foreground",children:[e.dfu," fixture units each, ",e.hint]})]},e.key))}),null!==em.problem&&(0,a.jsx)("p",{className:"mt-4 rounded-md border border-destructive/50 bg-destructive/5 p-3 text-sm",children:em.problem}),em.missing.length>0&&(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:em.missing.map(e=>(0,a.jsx)("li",{children:e},e))}),em.computed&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"mt-4 space-y-1 text-sm",children:[em.lines.map(e=>(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("span",{className:"text-muted-foreground",children:[e.count," x ",e.label]}),(0,a.jsxs)("span",{className:"tabular-nums",children:[e.dfuTotal," DFU"]})]},e.key)),(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"Total drainage fixture units"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[em.totalDfu," DFU"]})]}),(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1 font-medium",children:[(0,a.jsx)("span",{children:"Minimum tank from the table"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(em.gallons)," gallons"]})]})]}),(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:em.notes.map(e=>(0,a.jsx)("li",{children:e},e))})]})]}),(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"The same tank by flow and retention time, which is how the IPC does it"}),(0,a.jsx)("p",{className:"mt-2 text-sm text-muted-foreground",children:"IPC 1003.3.6 multiplies a peak flow by the time the water has to sit still for fats to cool and rise. The flow comes from the sink measurements above rather than from a box of its own, so this
7section and that one can never end up describing different kitchens."}),(0,a.jsxs)("div",{className:"mt-4 grid gap-4 sm:grid-cols-2",children:[(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-rt",children:"Retention time"}),(0,a.jsxs)("select",{id:"gi-rt",className:I,value:J,onChange:e=>Q(e.target.value),children:[(0,a.jsx)("option",{value:z,children:"Pick one before anything else"}),b.map(e=>(0,a.jsx)("option",{value:String(e),children:U[e]},e))]}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"your authority can require more than the model code minimum"})]}),eh.retention.computed&&(0,a.jsxs)("div",{className:"space-y-1 text-sm sm:pt-6",children:[(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"Peak flow used"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[A(eh.retention.peakFlowGpm)," GPM"]})]}),(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1 font-medium",children:[(0,a.jsx)("span",{children:"Tank volume"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(eh.retention.gallons)," gallons"]})]})]})]}),eh.retention.missing.length>0&&(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:eh.retention.missing.map(e=>(0,a.jsx)("li",{children:e},e))}),eh.retention.computed&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"mt-4 space-y-1 text-sm",children:eh.retention.atEachRetention.map(e=>(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("span",{className:"text-muted-foreground",children:["At ",e.minutes," minutes"]}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(e.gallons)," gallons"]})]},e.minutes))}),(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:eh.retention.notes.map(e=>(0,a.jsx)("li",{children:e},e))})]})]}),(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"The dining room, which is how a municipal grease ordinance sizes it"}),(0,a.jsx)("p",{className:"mt-2 text-sm text-muted-foreground",children:"This formula is not in the model code text at all. Wastewater districts publish it in their own Fats, Oils and Grease ordinances for restaurants that have no plumbing drawings yet, and it routinely lands far above the code methods on the same building."}),(0,a.jsxs)("div",{className:"mt-4 grid gap-4 sm:grid-cols-2",children:[(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-st",children:"Legal seating capacity"}),(0,a.jsx)(i.p,{id:"gi-st",inputMode:"numeric",className:"font-mono",value:X,onChange:e=>ee(e.target.value)}),(0,a.jsxs)("p",{className:"text-xs text-muted-foreground",children:["seats in the dining room, up to ",N.maxSeats.toLocaleString()]})]}),(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-hr",children:"Hours open a day"}),(0,a.jsx)(i.p,{id:"gi-hr",inputMode:"decimal",className:"font-mono",value:et,onChange:e=>es(e.target.value)}),(0,a.jsxs)("p",{className:"text-xs text-muted-foreground",children:["kitchen hours, up to ",N.maxHoursPerDay]})]}),(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-wf",children:"Service type"}),(0,a.jsxs)("select",{id:"gi-wf",className:I,value:ea,onChange:e=>en(e.target.value),children:[(0,a.jsx)("option",{value:z,children:"Pick one before anything else"}),w.map(e=>(0,a.jsx)("option",{value:e.key,children:e.label},e.key))]}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"only the two categories the published source names"})]}),(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-lf",children:"Kitchen equipment"}),(0,a.jsxs)("select",{id:"gi-lf",className:I,value:ei,onChange:e=>eo(e.target.value),children:[(0,a.jsx)("option",{value:z,children:"Pick one before anything else"}),v.map(e=>(0,a.jsxs)("option",{value:e.key,children:[e.label,", factor ",e.factor]},e.key))]}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"a disposal grinds food into the line and raises the multiplier"})]})]}),null!==ec.problem&&(0,a.jsx)("p",{className:"mt-4 rounded-md border border-destructive/50 bg-destructive/5 p-3 text-sm",children:ec.problem}),ec.missing.length>0&&(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:ec.missing.map(e=>(0,a.jsx)("li",{children:e},e))}),ec.computed&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"mt-4 space-y-1 text-sm",children:(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1 font-medium",children:[(0,a.jsx)("span",{children:"Tank volume from the ordinance formula"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(ec.gallons)," gallons"]})]})}),(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:ec.notes.map(e=>(0,a.jsx)("li",{children:e},e))})]})]}),null!==ep&&(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"What the published methods say about your kitchen"}),(0,a.jsx)("p",{className:"mt-3 text-sm font-medium",children:ep.headline}),(0,a.jsx)("div",{className:"mt-3 space-y-1 text-sm",children:ep.entries.map(e=>(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1",children:[(0,a.jsxs)("span",{className:"text-muted-foreground",children:[e.name,", ",e.code]}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(e.gallons)," gallons"]})]},e.key))})]}),(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"The minimum your own authority enforces"}),(0,a.jsx)("p",{className:"mt-2 text-sm text-muted-foreground",children:"Call the wastewater district or open their Fats, Oils and Grease ordinance and read the number off it. This page will not guess it, and no size is shown until it is entered, because a calculator that invents a code value is worse than no calculator on account of looking authoritative."}),(0,a.jsx)("div",{className:"mt-4 grid gap-4 sm:grid-cols-2",children:(0,a.jsxs)("div",{className:"space-y-1.5",children:[(0,a.jsx)("label",{className:"text-sm font-medium",htmlFor:"gi-lm",children:"Their published minimum"}),(0,a.jsx)(i.p,{id:"gi-lm",inputMode:"decimal",className:"font-mono",value:el,onChange:e=>er(e.target.value)}),(0,a.jsxs)("p",{className:"text-xs text-muted-foreground",children:["gallons. The UPC model code floor is ",500," and many districts set theirs higher."]}
7)]})}),null!==eh.problem&&(0,a.jsx)("p",{className:"mt-4 rounded-md border border-destructive/50 bg-destructive/5 p-3 text-sm",children:eh.problem}),null===eg?(0,a.jsx)("p",{className:"mt-4 rounded-md border bg-muted p-3 text-sm",children:"No tank size is shown, and that is deliberate. Enter the minimum your authority publishes and the band below fills in. Everything above stays visible either way, because the model code arithmetic is worth reading on its own."}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("p",{className:"mt-4 text-sm font-medium",children:eg.headline}),(0,a.jsxs)("div",{className:"mt-3 space-y-1 text-sm",children:[(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"Their published minimum"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(eg.localMinimumGallons)," gallons"]})]}),(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:"UPC model code floor"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(eg.modelCodeMinimumGallons)," gallons"]})]}),(0,a.jsxs)("div",{className:"flex justify-between border-t pt-1 font-medium",children:[(0,a.jsx)("span",{children:"The published methods, raised to that floor"}),(0,a.jsxs)("span",{className:"tabular-nums",children:[E(eg.bandLowGallons)," to ",E(eg.bandHighGallons)," gallons"]})]})]}),(0,a.jsx)("ul",{className:"mt-4 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:eg.notes.map(e=>(0,a.jsx)("li",{children:e},e))})]})]}),(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"What this page will not work out for you"}),(0,a.jsx)("ul",{className:"mt-3 list-disc space-y-2 pl-5 text-sm text-muted-foreground",children:j.map(e=>(0,a.jsx)("li",{children:e},e))})]}),(0,a.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-medium",children:"The arithmetic behind each method"}),(0,a.jsx)("pre",{className:"mt-2 overflow-x-auto rounded bg-muted p-3 font-mono text-sm",children:`HYDROMECHANICAL, in GPM UPC 1014.2 / IPC 1003.3.5 8 9 gallons = L x W x D x bays / 231 10 GPM = gallons x 0.75 / drain minutes 11 lb = GPM x 2 12 13 and separately, UPC 1014.2.1: 14 gallons <= 2.5 x rated GPM 15 so rated GPM >= gallons / 2.5 16 17 at a 2 minute window the first rule gives 0.375 x gallons 18 and the cap demands ${k(.4,3)} x gallons, so the cap always wins 19 20GRAVITY, in gallons 21 22 UPC Table 1014.3.6 total DFU -> a published minimum volume 23 IPC 1003.3.6 gallons = peak GPM x retention minutes 24 municipal FOG gallons = seats x hours x gal per meal x loading factor 25 26 UPC floor for an outdoor gravity tank 500 gallons 27 published DFU table ends at ${f} DFU / ${x} gallons 28 typical HGI span ${c.lowGpm} to ${c.highGpm} GPM`}),(0,a.jsx)("p",{className:"mt-3 text-sm text-muted-foreground",children:"The two blocks are never added together and neither converts into the other. A GPM rating describes how fast an engineered baffle can separate grease out of moving water, and a gallon figure describes how long water sits still in a buried tank."})]}),(0,a.jsx)(l.i,{value:ef,label:"Copy every method and the refusals"}),(0,a.jsx)("p",{className:"text-sm text-muted-foreground",children:D}),(0,a.jsx)(o.ToolActions,{share:()=>_({len:e,wid:s,dep:d,bays:B,drain:K,counts:V,retention:J,seats:X,hours:et,waste:ea,loading:ei,localMin:el}),title:"Grease Interceptor Calculator",queryIsImpersonal:"the sink, fixture and dining room figures you entered"})]})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.