{"version":3,"sources":["ajax.js","cubehelix.js","Layout.js","MainText.js","HealthInsuranceExplainer.js","Posts.js","FlexboxFriend.js","App.js","reportWebVitals.js","index.js"],"names":["ajax","path","options","baseAjax","headers","then","response","json","base","url","fetch","catch","error","console","log","cubehelixColor","c","color","colors","index","hsl","lerp","v0","v1","t","i","length","c1","c2","cubehelix","Layout","children","useState","Math","random","setC","className","onClick","style","backgroundColor","toString","Date","getFullYear","MainText","href","HealthInsuranceExplainer","selection","setSelection","medicalSpend","setMedicalSpend","okay","showCompanyPays","showEmployeePays","showTotal","plans","deductible","familyDeductible","oopm","familyOopm","coinsurance","name","companyPays","employee","employeePays","copay","copaySpecialist","tier","maxCompanyPays","map","p","reduce","a","b","max","maxWidth","pct","v","percent","round","money","header","explanation","type","value","onChange","e","target","num","text","spend","plan","companyPaysMargin","bars","hide","width","marginLeft","klass","highlight","sub","COST","examples","startingMargin","isCopay","isHDHP","amount","note","push","secondAmount","Error","margin","total","amountLeft","min","preAmount","isTotal","bar","totalLabelPercentage","title","todo","q","o","s","window","scrollTo","top","behavior","opacity","Posts","useRouteMatch","PostPage","AllPosts","postId","useParams","Post","loading","setLoading","post","setPost","useEffect","dangerouslySetInnerHTML","__html","posts","setPosts","to","lastModified","toDateString","cleanPx","isNaN","FlexboxFriend","setWidth","floor","COLOR_MODULUS","baseColorId","gutter","setGutter","showOptions","setShowOptions","event","Number","checked","Container","starter","baseName","setChildren","el","useRef","latestWidth","updateWidthText","current","clientWidth","span","querySelector","innerHTML","addEventListener","removeEventListener","ref","gap","key","Child","colorId","removeSelf","_","without","dispatchEvent","Event","removeChild","setText","minWidth","setMinWidth","setMaxWidth","fullWidth","setFullWidth","minHeight","setMinHeight","growRatio","setGrowRatio","css","flexGrow","lock","field","setter","placeholder","Home","counter","setCounter","data","test","location","search","method","App","reportWebVitals","onPerfEntry","Function","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","document","getElementById"],"mappings":"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","file":"static/js/main.f38f8e0a.chunk.js","sourcesContent":["export default function ajax(path, options = {}) {\n options = {\n ...options,\n headers: {\n ...(options.headers || {}),\n 'Accept': 'application/json',\n }\n };\n\n // TODO: handle errors here.\n return baseAjax(path, options)\n .then(response => response.json())\n}\n\nexport function baseAjax(path, options = {}) {\n const base = (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') ?\n 'http://localhost:8080' :\n '';\n const url = base + path\n\n return fetch(url, options)\n .catch(error => {\n console.log(\"Error:\", error)\n // oh, this should re-raise an error, not a plain return\n return error;\n })\n}\n","import { cubehelix } from 'd3-color';\n\nexport default function cubehelixColor(c) {\n // These points are taken from mbostock's original cubehelix post\n // linearly interpolate between them in the cubehelix color space\n const colors = [\n { index: 0.0, hsl: [-100, 0.75, 0.35]},\n { index: 0.5, hsl: [ 80, 1.50, 0.80]},\n { index: 1.0, hsl: [ 260, 0.75, 0.35]},\n ];\n\n function lerp(v0, v1, t) {\n return (1 - t) * v0 + t * v1;\n }\n\n let color;\n\n for (let i = 0; i < colors.length - 1; i++) {\n const c1 = colors[i];\n const c2 = colors[i+1];\n if (c1.index <= c && c < c2.index) {\n const t = (c - c1.index) / (c2.index - c1.index);\n color = [\n lerp(c1.hsl[0], c2.hsl[0], t),\n lerp(c1.hsl[1], c2.hsl[1], t),\n lerp(c1.hsl[2], c2.hsl[2], t),\n ];\n break;\n }\n }\n\n return cubehelix(color[0],color[1],color[2]);\n}\n","import './Layout.css';\n\nimport { useState } from 'react';\nimport cubehelixColor from './cubehelix';\n\nexport default function Layout({ children }) {\n const [c, setC] = useState(Math.random());\n\n return (\n
\n
\n
setC((c) => (c + 0.1) % 1.0)}\n style={ { backgroundColor: cubehelixColor(c).toString() } }\n >\n

Hi.(P.S. you can click on this.)

\n
\n { children }\n \n
\n
\n );\n}\n","import { Fragment } from 'react';\n\nexport default function MainText() {\n return (\n

I'm Jesse Youngmann.

\n

I'm a full-stack web developer.

\n

I have experience in Rails, React, Postgres, Chef, Ansible, and a bunch of other web development tools.

\n

I've really enjoyed using Rust for personal projects.

\n

You can find my resume at linkedin and some public code at github.

\n\n

There's not much here.

\n

This site is mostly for testing webdev tools.

\n

I made it with React for the frontend, and a Rust backend in Actix, which is great and entirely overkill for a personal site.

\n

I automated provisioning and compiling and deploying it to a DigitalOcean droplet with Docker, Webpack, and Ansible. (I'm not actually deploying a docker container, just cross compiling it for linux with docker.)

\n

It's being served by nginx and Actix.

\n

It's got HTTPS using Let's Encrypt and certbot.

\n

Maybe there'll be more stuff here later. Until then, go read some of my favorite things:

\n

Some of my favorite things:

\n

Gunnerkrigg Court

\n

Octopus Pie

\n

Paranatural

\n

\n Some great indie games: Fez\n , Faster Than Light\n , Slay the Spire\n , Hollow Knight\n , Hades\n , Crypt of the Necrodancer\n \n

\n
);\n}\n","import './HealthInsuranceExplainer.css';\n\nimport { useState } from 'react';\nimport cubehelixColor from './cubehelix';\n\nexport default function HealthInsuranceExplainer() {\n //const [realShowCompanyPays, setShowCompanyPays] = useState(true);\n //const [realShowEmployeePays, setShowEmployeePays] = useState(true);\n const [selection, setSelection] = useState(null);\n const [medicalSpend, setMedicalSpend] = useState(500);\n\n function setSelectionAndScroll(s) {\n setSelection(s);\n window.scrollTo({ top: 0, behavior: \"smooth\" });\n }\n\n const okay = selection === null;\n\n const showCompanyPays = okay;\n const showEmployeePays = okay || selection === 'mostYouCanPay' || selection === 'compare';\n const showTotal = okay;\n\n const plans = [\n {\n deductible: 5000,\n familyDeductible: 1000,\n oopm: 5000,\n familyOopm: 5000,\n coinsurance: 100,\n name: 'H50 PPO Plus HSA',\n companyPays: {\n employee: 296.80 * 12,\n },\n employeePays: {\n employee: 0.00 * 12,\n },\n copay: null,\n copaySpecialist: null,\n },\n\n {\n deductible: 3000,\n familyDeductible: 1000,\n oopm: 6000,\n familyOopm: 5000,\n coinsurance: 80,\n name: 'P30 PPO Plus',\n companyPays: {\n employee: 358.50 * 12,\n },\n employeePays: {\n employee: 0.00 * 12,\n },\n copay: 25,\n copaySpecialist: 50,\n },\n\n {\n deductible: 2000,\n familyDeductible: 4000,\n oopm: 4000,\n familyOopm: 8000,\n coinsurance: 80,\n name: 'P20 PPO Plus',\n companyPays: {\n employee: 358.50 * 12,\n },\n employeePays: {\n employee: 45.84 * 12,\n },\n copay: 25,\n copaySpecialist: 50,\n },\n\n {\n deductible: 500,\n familyDeductible: 1000,\n oopm: 2500,\n familyOopm: 5000,\n coinsurance: 90,\n name: 'S05 PPO Plus',\n companyPays: {\n employee: 358.50 * 12,\n },\n employeePays: {\n employee: 139.81 * 12,\n },\n copay: 25,\n copaySpecialist: 50,\n },\n ];\n\n const totalLabelPercentage = 0.06;\n\n const tier = 'employee';\n const maxCompanyPays = plans.map(p => p.companyPays[tier]).reduce((a,b) => Math.max(a,b));\n const maxWidth = plans.map(p => (showCompanyPays ? maxCompanyPays : 0) + (showEmployeePays ? p.employeePays[tier] : 0) + p.oopm)\n .reduce((a,b) => Math.max(a,b)) * (1 + totalLabelPercentage);\n\n function pct(v) {\n const percent = Math.round((v / maxWidth) * 10000) / 100;\n return `${percent}%`;\n }\n\n function money(v) {\n return `$${Math.round(v)}`;\n }\n\n function zeroClass(v) {\n if (Math.round(v * 100) === 0) {\n return 'plan-math__amount-zero';\n } else {\n return '';\n }\n }\n\n function renderPlan(plan) {\n const deductible = plan.deductible;\n const companyPaysMargin = (maxCompanyPays - plan.companyPays[tier]);\n const companyPays = plan.companyPays[tier];\n const employeePays = plan.employeePays[tier];\n const oopm = (plan.oopm - plan.deductible);\n\n const bars = [{\n name: \"Employer Contribution\",\n hide: !showCompanyPays,\n width: companyPays,\n marginLeft: companyPaysMargin,\n value: plan.companyPays[tier],\n klass: 'company-contribution',\n }, {\n name: \"Employee Contribution\",\n hide: !showEmployeePays,\n width: employeePays,\n value: plan.employeePays[tier],\n klass: 'employee-contribution',\n }, {\n name: \"Deductible\",\n width: deductible,\n value: plan.deductible,\n klass: 'deductible',\n highlight: selection === 'deductible',\n }, {\n name: 'OOPM',\n width: oopm,\n value: plan.oopm - plan.deductible,\n sub: '(+ded)',\n klass: 'oopm',\n }];\n\n const COST = 234;\n\n let examples = null;\n if (selection === 'copay' || selection === 'nonCopay' || selection === 'preventive' ) {\n const startingMargin = showCompanyPays ? maxCompanyPays : 0 + showEmployeePays ? plan.employeePays[tier] : 0;\n\n const isCopay = selection === 'copay';\n const isHDHP = plan.copay === null && plan.deductible === plan.oopm;\n\n if (selection === 'preventive') {\n examples = [{\n width: 0,\n marginLeft: startingMargin,\n amount: 0,\n note: \"Preventive care is always covered.\",\n }];\n if (!isHDHP) {\n examples.push({\n width: 0,\n marginLeft: plan.deductible,\n note: \"Preventive care is always covered.\",\n amount: 0,\n });\n }\n // TODO: check if copay is available here!\n } else if (plan.copay !== null && plan.coinsurance !== null) {\n const amount = isCopay ? plan.copay : COST;\n\n const secondAmount = isCopay ? plan.copay : COST * ((100 - plan.coinsurance) / 100);\n\n examples = [{\n width: amount,\n marginLeft: startingMargin,\n amount,\n note: isCopay ? \"Just pay the copay.\" : \"Pay full amount until deductible is reached\",\n }, {\n width: secondAmount,\n marginLeft: (plan.deductible - amount),\n amount: secondAmount,\n note: isCopay ? \"Just pay the copay.\" : `Plan pays coinsurance of ${ plan.coinsurance }%, you pay ${ 100 - plan.coinsurance }% of total cost.`,\n }, {\n width: 0,\n marginLeft: (plan.oopm - plan.deductible - secondAmount),\n amount: 0,\n note: \"Sana covers all costs after oopm is reached.\",\n }];\n } else if (isHDHP) {\n examples = [{\n width: COST,\n marginLeft: startingMargin,\n amount: COST,\n note: \"Pay full amount until deductible is reached.\",\n }, { // if deductible == oopm\n width: 0,\n marginLeft: (plan.oopm - COST),\n note: \"Sana covers all costs after deductible is reached.\",\n amount: 0,\n }];\n } else {\n throw new Error(\"Not a valid plan type\");\n }\n } else if (selection === 'mostYouCanPay') {\n const startingMargin = showCompanyPays ? maxCompanyPays : 0;\n const amount = (showEmployeePays ? plan.employeePays[tier] : 0) + plan.oopm;\n examples = [{\n width: amount,\n amount,\n marginLeft: startingMargin,\n note: \"The most you can pay in a year is your employee contributions plus your out of pocket max.\",\n highlight: true,\n }];\n } else if (selection === 'compare') {\n let margin = showCompanyPays ? maxCompanyPays : 0;\n let total = 0;\n examples = [];\n\n if (plan.employeePays[tier] !== 0) {\n let amount = plan.employeePays[tier];\n examples.push({\n width: amount,\n amount,\n marginLeft: margin,\n note: \"You always pay premiums.\",\n });\n margin = 0;\n total = total + amount;\n }\n\n let amountLeft = medicalSpend;\n\n if (amountLeft > 0 && plan.deductible !== 0) {\n const amount = Math.min(amountLeft, plan.deductible);\n amountLeft = amountLeft - amount;\n\n let note = `You pay the full amount of the first ${money(amount)}`;\n if (plan.copay !== null) {\n note = note + \" (Assume no copays here for simplicity.)\";\n }\n\n examples.push({\n width: amount,\n amount,\n note,\n });\n total = total + amount;\n }\n\n if (amountLeft > 0 && plan.deductible !== plan.oopm) {\n const preAmount = Math.min(amountLeft, (plan.oopm - plan.deductible) / (1 - plan.coinsurance / 100));\n\n amountLeft = amountLeft - preAmount;\n\n const amount = preAmount * (1 - plan.coinsurance / 100);\n\n examples.push({\n width: amount,\n amount,\n note: `Coinsurance kicks in and reduces ${ money(preAmount) } by ${ plan.coinsurance }%`,\n });\n total = total + amount;\n }\n\n examples.push({\n isTotal: true,\n amount: total,\n sub: amountLeft > 0 ? `You pay none of the remaining ${ money(amountLeft)}.` : null,\n });\n\n }\n\n return (
\n { plan.name }\n
\n { bars.map((bar, index) => bar.hide ? null :\n \n
\n { money(bar.value) }\n { bar.sub ? { bar.sub } : null }\n
{ bar.name }
\n
\n
\n )}\n { !showTotal ? null :
\n Total:
{ money(plan.oopm + plan.employeePays[tier]) }\n
}\n
\n { examples === null ? null :\n
\n { examples.map((bar) => bar.isTotal ?\n
\n Total you pay:
{ money(bar.amount) }\n { bar.sub ? { bar.sub } : null }\n
\n :\n \n
\n { money(bar.amount) }\n
{ bar.note }
\n
\n
\n ) }\n \n }\n );\n }\n\n //\n\n const header = {\n 'copay': \"What will I pay for a doctor's appointment?\",\n 'nonCopay': \"What will I pay for other medical costs?\",\n 'preventive': \"What will I pay for preventive care?\",\n 'deductible': 'What is a deductible?',\n 'mostYouCanPay': 'What is the most I can pay in a year?',\n 'compare': 'Compare plans at various medical spends',\n }[selection] || 'Your available health insurance plans:';\n\n const explanation = {\n 'copay': \"A copay is a set amount you can pay for some doctor's visits instead of paying the full cost.\",\n 'nonCopay': \"Examples? Like labs.\",\n 'preventive': \"Preventive care, like vaccinations and [other examples here], is always fully covered.\",\n 'deductible': \"A deductible is the amount you must pay in copays and medical costs before coinsurance kicks in.\",\n 'mostYouCanPay': \"The most you can pay in a year is the sum of your premiums and out of pocket max.\",\n 'compare': \"Enter an amount of medical spend and see what the cost to you would be.\",\n }[selection];\n\n const questions = [\n {\n name: \"Examples\",\n options: [\n { title: 'What do I pay if I go to a doctor?', selection: 'copay' },\n { title: 'What do I pay for preventive medical care?', selection: 'preventive' },\n { title: 'What do I pay for other care?', selection: 'nonCopay' },\n ],\n },\n {\n name: \"Medical Costs\",\n options: [\n { title: 'What is the least I might pay in a year?', selection: 'leastYouCanPay', todo: true },\n { title: 'What is the most I can pay in a year?', selection: 'mostYouCanPay' },\n { title: 'What is an average amount I might pay in a year?', selection: 'averageYouCanPay', todo: true },\n { title: 'How can I compare the expected value of each plan? (This is the cool one!)', selection: 'compare' },\n { title: 'In which order would I hit the OOPM?', selection: 'oopmOrder', todo: true },\n { title: 'What are the break even points between plans?', selection: 'breakEven', todo: true },\n ],\n },\n {\n name: \"Definitions\",\n options: [\n { title: 'What is a deductible?', selection: 'deductible' },\n { title: 'What is an out of pocket max?', selection: 'oopm', todo: true },\n { title: 'What is coinsurance?', selection: 'coinsurance', todo: true },\n { title: 'What is a copay?', selection: 'copa2y', todo: true },\n ],\n },\n {\n name: \"Other\",\n options: [\n { title: 'Show the employer contribution', selection: null },\n ],\n },\n ];\n\n function renderMedicalSpendInput() {\n if (selection !== 'compare') {\n return null;\n }\n\n const exampleSpends = [\n { num: 0, text: \"$0\" },\n { num: 500, text: \"$500\" },\n { num: 1000, text: \"$1,000\" },\n { num: 2500, text: \"$2,500\" },\n { num: 5000, text: \"$5,000\" },\n { num: 10000, text: \"$10,000\" },\n { num: 25000, text: \"$25,000\" },\n ];\n\n return (
\n \n { exampleSpends.map( spend => ) }\n
);\n }\n\n return (
\n

{ header }

\n { explanation &&

{ explanation }

}\n { renderMedicalSpendInput() }\n { plans.map(renderPlan) }\n { questions.map(q =>
\n

{ q.name }

\n \n
) }\n
);\n}\n\n// TODO:\n// click on any li, highlight it in the grid\n// show:\n// before meeting your deductible: you pay copay, or total if no copay for that\n// after meeting deductible, before oopm: you pay coinsurance (or copay if present)\n// after oopm: you pay nothing\n//\n// how to easily show difference between oopm (which is inclusive of deductible) vs premiums (not included?)\n// show payments into HSA from company? as negative charge, shifting next function left? chart should have ticks underneath\n// label shows how wide it is\n//\n//\n// todo: highlight things\n","import './Posts.css';\n\nimport { useState, useEffect } from 'react';\n\nimport { Switch, Route, Link, useParams, useRouteMatch } from \"react-router-dom\";\n\nimport ajax from './ajax';\n\nexport default function Posts() {\n const { path } = useRouteMatch();\n\n return
\n \n \n \n \n \n \n \n \n
;\n}\n\nfunction PostPage() {\n const { postId } = useParams();\n return ;\n}\n\nfunction Post({ postId }) {\n const [loading, setLoading] = useState(true);\n const [post, setPost] = useState(null);\n\n function getPost() {\n ajax(`/posts/${postId}`)\n .then(response => {\n setPost(response.post);\n setLoading(false);\n });\n }\n\n useEffect(getPost, [postId]);\n\n return
\n { loading ?\n

LOADING

:\n
\n }\n
;\n}\n\nfunction AllPosts() {\n const [loading, setLoading] = useState(true);\n const [posts, setPosts] = useState(null);\n\n function getPosts() {\n ajax('/posts/api')\n .then(response => {\n setPosts(response.posts);\n setLoading(false);\n });\n }\n\n useEffect(getPosts, []);\n\n return
\n

All posts!

\n

These are mostly snippets of very specific things I couldn't easily find anywhere else on the internet, so here's hoping google indexes them.

\n { loading ?\n

LOADING

:\n posts.map(p =>
\n

\n Posted { (new Date(p.lastModified * 1000)).toDateString() }:\n

\n \n
)\n }\n
;\n}\n","import './FlexboxFriend.css';\n\nimport { useState, useRef, useEffect } from 'react';\nimport _ from 'lodash';\nimport cubehelixColor from './cubehelix';\n\nfunction cleanPx(v) {\n if (v === \"\" || v == null || isNaN(v)) {\n return null;\n } else {\n return `${v}px`;\n }\n}\n\n\nexport default function FlexboxFriend() {\n const [width, setWidth] = useState(1200);\n const [baseColorId] = useState(() => Math.floor(Math.random() * COLOR_MODULUS));\n const [gutter, setGutter] = useState(20);\n const [showOptions, setShowOptions] = useState(true);\n\n function resize(event) {\n setWidth(Number(event.target.value));\n }\n\n return (
\n \n
\n
\n \n setShowOptions(!!e.target.checked) } />\n
\n { showOptions &&
\n \n setGutter(e.target.value) } />\n \n
}\n
\n
\n \n
\n
);\n}\n\n\n// okay, can click on anything, select it\n// put UI in there? or portal it?\n// or just do callbacks?\n\nconst COLOR_MODULUS = 24;\n\nfunction Container({ starter, showOptions, gutter, baseColorId, baseName }) {\n baseName = baseName || \"element\";\n\n const [children, setChildren] = useState(starter ? [1] : []);\n\n const el = useRef(null);\n const latestWidth = useRef(null);\n\n function updateWidthText() {\n const width = el.current.clientWidth;\n if (latestWidth.current !== width) {\n latestWidth.current = width;\n const span = el.current.querySelector('.width-text');\n if (span) {\n span.innerHTML = width;\n }\n }\n }\n\n // on every re-render\n useEffect(updateWidthText);\n\n useEffect(() => {\n window.addEventListener('resize', updateWidthText);\n return () => {\n window.removeEventListener('resize', updateWidthText);\n }\n }, []);\n\n function removeChild(key) {\n setChildren(_.without(children, key))\n // Okay, this is a hack to get other divs to re-render\n // their size\n window.dispatchEvent(new Event('resize'));\n }\n\n function addChild() {\n setChildren([\n ...children,\n (children[children.length-1] || 0) + 1,\n ]);\n }\n\n return (
\n { showOptions &&
\n \n
}\n
\n width: px\n
\n\n
\n { children.map(key => removeChild(key) }\n gutter={ gutter }\n />) }\n
\n
);\n}\n\nfunction Child({ baseName, baseColorId, colorId, gutter, showOptions, removeSelf }) {\n const [text, setText] = useState(baseName);\n\n // TODO: debounce these\n const [minWidth, setMinWidth] = useState(250);\n const [maxWidth, setMaxWidth] = useState(null);\n const [fullWidth, setFullWidth] = useState(false);\n\n const [minHeight, setMinHeight] = useState(200);\n const [growRatio, setGrowRatio] = useState(1);\n\n const el = useRef(null);\n\n let css = {\n backgroundColor: cubehelixColor(((baseColorId + colorId) % COLOR_MODULUS) / COLOR_MODULUS),\n flexGrow: growRatio,\n minWidth: cleanPx(minWidth),\n maxWidth: cleanPx(maxWidth),\n minHeight: cleanPx(minHeight),\n };\n\n if (fullWidth) {\n css.width = '100%';\n }\n\n // useref for self\n function lock(field, setter) {\n return () => {\n setter(el.current[field]);\n };\n }\n\n return (
\n { showOptions ?
\n setText(e.target.value) } placeholder=\"element name\" />\n \n
\n \n setFullWidth(!!e.target.checked) } />\n
\n
\n \n setMinWidth(e.target.value) } />\n \n \n
\n
\n \n setMaxWidth(e.target.value) } />\n \n \n
\n
\n \n setMinHeight(e.target.value) } />\n \n
\n
\n \n setGrowRatio(e.target.value) } />\n \n
\n
:
{ text }
}\n \n
);\n}\n","import './App.css';\n\nimport { useState, useEffect } from 'react';\nimport ajax from './ajax';\nimport { BrowserRouter as Router, Switch, Route, Link, Redirect } from \"react-router-dom\";\n\nimport Layout from './Layout';\nimport MainText from './MainText';\nimport HealthInsuranceExplainer from './HealthInsuranceExplainer';\nimport Posts from './Posts';\nimport FlexboxFriend from './FlexboxFriend';\n\nfunction App() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n}\n\nfunction Home() {\n const [counter, setCounter] = useState(null);\n\n function getCounter() {\n ajax(\"/counter\")\n .then(data => setCounter(data.counter));\n }\n\n function handleClick() {\n ajax(\"/counter\", { method: \"POST\" })\n .then(data => setCounter(data.counter));\n }\n\n useEffect(() => {\n getCounter();\n }, []);\n\n if ((/health_insurance_explainer/).test(window.location.search)) {\n return \n }\n\n return (\n \n
\n
\n \n
\n
\n

\n Useful Code Snippets\n

\n You can tell this isn't a static site because of this stateful counter that persists across page loads:\n { counter != null &&
\n has been\n clicked { counter } times\n since the server was restarted.\n
}\n

\n Testing rollbacks v1!\n

\n
\n
\n
\n );\n}\n\nexport default App;\n","const reportWebVitals = onPerfEntry => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}